Permalink
Browse files

Read serial characters for the GPS in a separate thread

  • Loading branch information...
monkbroc committed Jul 9, 2017
1 parent a75f040 commit f31a605369f68a3323a71fa2d5fcf804a6fe292a
Showing with 75 additions and 31 deletions.
  1. +7 −5 README.md
  2. +11 −7 examples/carloop_minimal/carloop_minimal.cpp
  3. +1 −1 library.properties
  4. +38 −0 src/TinyGPS++.h
  5. +15 −15 src/carloop.cpp
  6. +3 −3 src/carloop.h
@@ -88,12 +88,14 @@ void loop() {
### `gps()`
If you have a GPS connected to the Carloop, you access GPS function through the TinyGPS object with `carloop.gps()`
If you have a GPS connected to the Carloop, you access GPS function through the TinyGPS object with `carloop.gps()`. To ensure that the GPS location doesn't update in the middle of reading it, surround the block where you extract the GPS data in a `WITH_LOCK` block.
```
float lat = carloop.gps().location.lat();
float lng = carloop.gps().location.lng();
bool gpsValid = carloop.gps().location.isValid();
WITH_LOCK(carloop.gps()) {
float lat = carloop.gps().location.lat();
float lng = carloop.gps().location.lng();
bool gpsValid = carloop.gps().location.isValid();
}
```
[See the TinyGPS library for detailed examples.](https://github.com/codegardenllc/tiny_gps_plus)
@@ -113,5 +115,5 @@ float battVoltage = carloop.battery();
## License
Copyright 2016 Julien Vanier. Distributed under the MIT license. See [LICENSE](/license) for details.
Copyright 2016-2017 1000 Tools, Inc. Distributed under the MIT license. See [LICENSE](/license) for details.
@@ -58,13 +58,17 @@ void printValuesAtInterval() {
void printValues()
{
auto &gps = carloop.gps();
Serial.printf("Battery voltage: %12f ", carloop.battery());
Serial.printf("CAN messages: %12d ", canMessageCount);
Serial.printf("GPS %6d chars: ", gps.charsProcessed());
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printDateTime(gps.date, gps.time);
Serial.println("");
// Ensure that the GPS state doesn't change while printing
WITH_LOCK(gps) {
Serial.printf("Battery voltage: %12f ", carloop.battery());
Serial.printf("CAN messages: %12d ", canMessageCount);
Serial.print("GPS ");
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printDateTime(gps.date, gps.time);
Serial.printf("%6d chars, %d checksum error", gps.charsProcessed(), gps.failedChecksum());
Serial.println("");
}
}
void printFloat(float val, bool valid, int len, int prec)
@@ -1,5 +1,5 @@
name=carloop
version=1.2.0
version=2.0.0
license=MIT
author=Julien Vanier <julien@carloop.io>
sentence=Carloop.io library for the Particle platform
@@ -271,6 +271,40 @@ class TinyGPSPlus
uint32_t passedChecksum() const { return passedChecksumCount; }
bool isFixed() const { return fix; }
// Additional methods for thread synchronization
#if PLATFORM_THREADING
os_mutex_recursive_t get_mutex()
{
if (mutex == nullptr) {
os_mutex_recursive_create(&mutex);
}
return mutex;
}
#endif
bool try_lock()
{
#if PLATFORM_THREADING
return !os_mutex_recursive_trylock(get_mutex());
#else
return true;
#endif
}
void lock()
{
#if PLATFORM_THREADING
os_mutex_recursive_lock(get_mutex());
#endif
}
void unlock()
{
#if PLATFORM_THREADING
os_mutex_recursive_unlock(get_mutex());
#endif
}
private:
enum
{
@@ -304,6 +338,10 @@ class TinyGPSPlus
// internal utilities
int fromHex(char a);
bool endOfTermHandler();
#if PLATFORM_THREADING
os_mutex_recursive_t mutex;
#endif
};
#endif // def(__TinyGPSPlus_h)
@@ -8,8 +8,6 @@
#include "carloop.h"
#include <functional>
std::function<void(char)> serialHandler;
template<typename Config>
Carloop<Config>::Carloop()
: canDriver(Config::CAN_PINS),
@@ -94,17 +92,16 @@ void Carloop<Config>::enableGPS()
Serial1.begin(Config::GPS_BAUD_RATE);
serialHandler = [this](char c)
{
gpsDriver.encode(c);
};
if (!gpsSerialThread.is_valid()) {
// Start a thread that will run this->receiveSerialChars()
gpsSerialThread = Thread("gps_serial", [this]() { receiveSerialChars(); });
}
}
template <typename Config>
void Carloop<Config>::disableGPS()
{
digitalWrite(Config::GPS_ENABLE_PIN, Config::GPS_ENABLE_INACTIVE);
serialHandler = nullptr;
}
template <typename Config>
@@ -142,15 +139,18 @@ bool Carloop<Config>::hasBattery()
}
// Receive bytes from the GPS
void serialEvent1()
{
while(Serial1.available())
{
char c = Serial1.read();
if(serialHandler)
{
serialHandler(c);
template <typename Config>
void Carloop<Config>::receiveSerialChars()
{
while(true) {
WITH_LOCK(gpsDriver) {
while(Serial1.available())
{
char c = Serial1.read();
gpsDriver.encode(c);
}
}
delay(1);
}
}
@@ -32,9 +32,6 @@ struct CarloopRevision2
static constexpr auto GPS_ENABLE_PIN = A0;
static constexpr auto GPS_ENABLE_ACTIVE = HIGH;
static constexpr auto GPS_ENABLE_INACTIVE = LOW;
// Serial cannot be configured because of dependency on the serialEvent1
// handler
// constexpr auto &GPS_SERIAL = Serial1;
static constexpr auto FEATURES = CARLOOP_CAN | CARLOOP_GPS | CARLOOP_BATTERY;
};
@@ -67,10 +64,13 @@ class Carloop
bool hasBattery();
private:
void receiveSerialChars();
CANChannel canDriver;
uint32_t canSpeed;
TinyGPSPlus gpsDriver;
Thread gpsSerialThread;
float batteryVoltage;

0 comments on commit f31a605

Please sign in to comment.