From 08aad7338b1ab449a307743410026aa3d2d0dc33 Mon Sep 17 00:00:00 2001 From: Florent Date: Sat, 31 May 2025 10:57:22 +0200 Subject: [PATCH] gps : sync time on fix --- examples/companion_radio/main.cpp | 2 +- src/helpers/sensors/LocationProvider.h | 6 ++++ .../sensors/MicroNMEALocationProvider.h | 29 +++++++++++++++++-- variants/t1000-e/target.cpp | 21 ++++++++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 30a1c9cc..8c6c715c 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -1643,7 +1643,7 @@ public: StdRNG fast_rng; SimpleMeshTables tables; -MyMesh the_mesh(radio_driver, fast_rng, *new VolatileRTCClock(), tables); // TODO: test with 'rtc_clock' in target.cpp +MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables); void halt() { while (1) ; diff --git a/src/helpers/sensors/LocationProvider.h b/src/helpers/sensors/LocationProvider.h index 056e61e0..f51eea28 100644 --- a/src/helpers/sensors/LocationProvider.h +++ b/src/helpers/sensors/LocationProvider.h @@ -4,13 +4,19 @@ class LocationProvider { +protected: + bool _time_sync_needed = true; public: + virtual void syncTime() { _time_sync_needed = true; } + virtual bool waitingTimeSync() { return _time_sync_needed; } virtual long getLatitude() = 0; virtual long getLongitude() = 0; virtual long getAltitude() = 0; + virtual long satellitesCount() = 0; virtual bool isValid() = 0; virtual long getTimestamp() = 0; + virtual void sendSentence(const char * sentence); virtual void reset(); virtual void begin(); virtual void stop(); diff --git a/src/helpers/sensors/MicroNMEALocationProvider.h b/src/helpers/sensors/MicroNMEALocationProvider.h index 9f439e25..ee6e43eb 100644 --- a/src/helpers/sensors/MicroNMEALocationProvider.h +++ b/src/helpers/sensors/MicroNMEALocationProvider.h @@ -19,13 +19,16 @@ class MicroNMEALocationProvider : public LocationProvider { char _nmeaBuffer[100]; MicroNMEA nmea; + mesh::RTCClock* _clock; Stream* _gps_serial; int _pin_reset; int _pin_en; + long next_check = 0; + long time_valid = 0; public : - MicroNMEALocationProvider(Stream& ser, int pin_reset = GPS_RESET, int pin_en = GPS_EN) : - _gps_serial(&ser), nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _pin_reset(pin_reset), _pin_en(pin_en) { + MicroNMEALocationProvider(Stream& ser, mesh::RTCClock* clock = &rtc_clock, int pin_reset = GPS_RESET, int pin_en = GPS_EN) : + _gps_serial(&ser), nmea(_nmeaBuffer, sizeof(_nmeaBuffer)), _pin_reset(pin_reset), _pin_en(pin_en), _clock(clock) { if (_pin_reset != -1) { pinMode(_pin_reset, OUTPUT); digitalWrite(_pin_reset, GPS_RESET_FORCE); @@ -59,6 +62,7 @@ public : } } + void syncTime() override { nmea.clear(); LocationProvider::syncTime(); } long getLatitude() override { return nmea.getLatitude(); } long getLongitude() override { return nmea.getLongitude(); } long getAltitude() override { @@ -66,6 +70,7 @@ public : nmea.getAltitude(alt); return alt; } + long satellitesCount() override { return nmea.getNumSatellites(); } bool isValid() override { return nmea.isValid(); } long getTimestamp() override { @@ -73,7 +78,12 @@ public : return dt.unixtime(); } + void sendSentence(const char *sentence) override { + nmea.sendSentence(*_gps_serial, sentence); + } + void loop() override { + while (_gps_serial->available()) { char c = _gps_serial->read(); #ifdef GPS_NMEA_DEBUG @@ -81,5 +91,20 @@ public : #endif nmea.process(c); } + + if (!isValid()) time_valid = 0; + + if (millis() > next_check) { + next_check = millis() + 1000; + if (_time_sync_needed && time_valid > 2) { + if (_clock != NULL) { + rtc_clock.setCurrentTime(getTimestamp()); + _time_sync_needed = false; + } + } + if (isValid()) { + time_valid ++; + } + } } }; \ No newline at end of file diff --git a/variants/t1000-e/target.cpp b/variants/t1000-e/target.cpp index be82ca76..296551e1 100644 --- a/variants/t1000-e/target.cpp +++ b/variants/t1000-e/target.cpp @@ -9,7 +9,7 @@ RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BU WRAPPER_CLASS radio_driver(radio, board); VolatileRTCClock rtc_clock; -MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); +MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); T1000SensorManager sensors = T1000SensorManager(nmea); #ifdef DISPLAY_CLASS @@ -179,14 +179,26 @@ void T1000SensorManager::loop() { } } -int T1000SensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch) +int T1000SensorManager::getNumSettings() const { return 2; } // just one supported: "gps" (power switch) const char* T1000SensorManager::getSettingName(int i) const { - return i == 0 ? "gps" : NULL; + switch (i) { + case 0: + return "gps"; + break; + case 1: + return "sync"; + break; + default: + return NULL; + break; + } } const char* T1000SensorManager::getSettingValue(int i) const { if (i == 0) { return gps_active ? "1" : "0"; + } else if (i == 1) { + return _nmea->waitingTimeSync() ? "1" : "0"; } return NULL; } @@ -198,6 +210,9 @@ bool T1000SensorManager::setSettingValue(const char* name, const char* value) { start_gps(); } return true; + } else if (strcmp(name, "sync") == 0) { + _nmea->syncTime(); // whatever the value ... + return true; } return false; // not supported }