diff --git a/include/gpsread.h b/include/gpsread.h index 17336afd..eca6645c 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -21,7 +21,7 @@ int gps_init(void); void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store); void gps_storelocation(gpsStatus_t *gps_store); void gps_loop(void *pvParameters); -time_t fetch_gpsTime(gpsStatus_t value); +time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec); int gps_config(); #endif \ No newline at end of file diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 8a8ab504..068127e6 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -12,7 +12,7 @@ TaskHandle_t GpsTask; #ifdef GPS_SERIAL HardwareSerial GPS_Serial(1); // use UART #1 static uint16_t nmea_txDelay_ms = - tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS; + (tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS); #else static uint16_t nmea_txDelay_ms = 0; #endif @@ -82,10 +82,7 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { - // nmea telegram serial delay compensation; not sure if we need this? - // if (gps.time.age() > nmea_txDelay_ms) - // gps_store->timedate.Second = gps.time.second() + 1; - // else + gps_store->time_age = gps.time.age() + nmea_txDelay_ms; gps_store->timedate.Second = gps.time.second(); gps_store->timedate.Minute = gps.time.minute(); gps_store->timedate.Hour = gps.time.hour(); @@ -99,10 +96,11 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { } // function to fetch current time from struct; note: this is costly -time_t fetch_gpsTime(gpsStatus_t value) { +time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec) { + *msec = 1000 - value.time_age; time_t t = timeIsValid(makeTime(value.timedate)); - ESP_LOGD(TAG, "GPS time: %d", t); + ESP_LOGD(TAG, "GPS time: %d | time age: %d", t, value.time_age); return t; } // fetch_gpsTime() diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 7382d8d8..30dcedc0 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -72,7 +72,7 @@ #define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] #define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0] -#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] +#define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] // settings for syncing time with timeserver applications #define TIME_SYNC_SAMPLES 1 // number of time requests for averaging diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index a3c14829..99f6f002 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -1,4 +1,5 @@ #include "timekeeper.h" +#include "paxcounter.conf" #if !(HAS_LORA) #if (TIME_SYNC_LORASERVER) @@ -25,29 +26,17 @@ void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } void calibrateTime(void) { time_t t = 0; - timesource_t timeSource; + uint16_t t_msec = 0; #if (HAS_GPS) // fetch recent time from last NMEA record - t = fetch_gpsTime(gps_status); + t = fetch_gpsTime(gps_status, &t_msec); if (t) { -#ifdef HAS_RTC - set_rtctime(t); // calibrate RTC -#endif timeSource = _gps; goto finish; } #endif -// no time from GPS -> fallback to RTC time while trying lora sync -#ifdef HAS_RTC - t = get_rtctime(); - if (t) { - timeSource = _rtc; - goto finish - } -#endif - // kick off asychronous Lora timeserver timesync if we have #if (HAS_LORA) && (TIME_SYNC_LORASERVER) send_timesync_req(); @@ -56,15 +45,18 @@ void calibrateTime(void) { LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); #endif +// no time from GPS -> fallback to RTC time while trying lora sync +#ifdef HAS_RTC + t = get_rtctime(); + if (t) { + timeSource = _rtc; + goto finish; + } +#endif + finish: - if (t) { // sync successful - setMyTime(t, 0, timeSource); // set time - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); - ESP_LOGD(TAG, "time = %d | source: %c", t, timeSetSymbols[timeSource]); - } else { // sync failed, we want to retry shortly - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); - } + setMyTime(t, t_msec, timeSource); // set time } // calibrateTime() diff --git a/src/timesync.cpp b/src/timesync.cpp index f8ba0157..9499502d 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -209,22 +209,25 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { // adjust system time, calibrate RTC and RTC_INT pps void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, - timesource_t timesource) { + timesource_t mytimesource) { - time_t time_to_set = (time_t)(t_sec + 1); - - ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec", - millis() / 1000.0, time_to_set, t_msec); + time_t time_to_set = (time_t)(t_sec); if (timeIsValid(time_to_set)) { + ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, + time_to_set, t_msec); // wait until top of second with millisecond precision - if (t_msec) + if (t_msec) { vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); + time_to_set++; + } -// set RTC time and calibrate RTC_INT pulse on top of second +// if we got a timesource, set RTC time and calibrate RTC_INT pulse on top of +// second #ifdef HAS_RTC - set_rtctime(time_to_set); + if (mytimesource != _rtc) + set_rtctime(time_to_set); #endif // sync pps timer to top of second @@ -235,13 +238,15 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, setTime(time_to_set); // set the time on top of second - timeSource = timesource; - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat - ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted", - millis() / 1000.0); - } else - ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated", - millis() / 1000.0); + timeSource = mytimesource; // set global variable + timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); + ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c", + millis() / 1000.0, timeSetSymbols[timeSource]); + } else { + timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); + ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c", + millis() / 1000.0, timeSetSymbols[timeSource]); + } } void timesync_init() {