diff --git a/include/globals.h b/include/globals.h index ff3f2028..17c485c2 100644 --- a/include/globals.h +++ b/include/globals.h @@ -114,7 +114,7 @@ extern SemaphoreHandle_t I2Caccess, TimePulse; extern TaskHandle_t irqHandlerTask, ClockTask; extern TimerHandle_t WifiChanTimer; extern Timezone myTZ; -extern time_t LastSyncTime, userUTCTime; +extern time_t lastSyncTime, userUTCTime; // application includes #include "led.h" diff --git a/include/timemanager.h b/include/timemanager.h index 648caca2..16e7276a 100644 --- a/include/timemanager.h +++ b/include/timemanager.h @@ -20,7 +20,6 @@ void clock_loop(void *pvParameters); void time_sync(void); int wait_for_pulse(void); int syncTime(time_t const t, uint8_t const timesource); -int syncTime(uint32_t const t, uint8_t const timesource); void IRAM_ATTR CLOCKIRQ(void); int timepulse_init(void); void timepulse_start(void); diff --git a/src/if482.cpp b/src/if482.cpp index 54b9ae5d..9f21f7ac 100644 --- a/src/if482.cpp +++ b/src/if482.cpp @@ -89,16 +89,19 @@ HardwareSerial IF482(2); // use UART #2 (note: #1 may be in use for serial GPS) // triggered by timepulse to ticker out DCF signal void IF482_Pulse(time_t t) { + static const TickType_t txDelay = + pdMS_TO_TICKS(IF482_PULSE_LENGTH) - tx_Ticks(HAS_IF482); + TickType_t startTime = xTaskGetTickCount(); - static const TickType_t txDelay = pdMS_TO_TICKS(IF482_PULSE_LENGTH) - tx_Ticks(HAS_IF482); - vTaskDelayUntil(&startTime, txDelay); - IF482.print(IF482_Frame(t+1)); // note: if482 telegram for *next* second + + vTaskDelayUntil(&startTime, txDelay); // wait until moment to fire + IF482.print(IF482_Frame(t + 1)); // note: if482 telegram for *next* second } String IRAM_ATTR IF482_Frame(time_t startTime) { time_t t = myTZ.toLocal(startTime); - char mon, buf[14], out[IF482_FRAME_SIZE]; + char mon, out[IF482_FRAME_SIZE]; switch (timeStatus()) { // indicates if time has been set and recently synced case timeSet: // time is set and is synced @@ -113,9 +116,10 @@ String IRAM_ATTR IF482_Frame(time_t startTime) { } // switch // generate IF482 telegram - snprintf(buf, sizeof(buf), "%02u%02u%02u%1u%02u%02u%02u", year(t) - 2000, - month(t), day(t), weekday(t), hour(t), minute(t), second(t)); - snprintf(out, sizeof(out), "O%cL%s\r", mon, buf); + snprintf(out, sizeof(out), "O%cL%02u%02u%02u%1u%02u%02u%02u\r", mon, + year(t) - 2000, month(t), day(t), weekday(t), hour(t), minute(t), + second(t)); + ESP_LOGD(TAG, "IF482 = %s", out); return out; } @@ -124,13 +128,13 @@ String IRAM_ATTR IF482_Frame(time_t startTime) { TickType_t tx_Ticks(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPins) { - uint32_t datenbits = ((config & 0x0c) >> 2) + 5; + uint32_t databits = ((config & 0x0c) >> 2) + 5; uint32_t stopbits = ((config & 0x20) >> 5) + 1; - uint32_t tx_delay = - (2 + datenbits + stopbits) * IF482_FRAME_SIZE * 1000.0 / baud; + uint32_t txTime = + (databits + stopbits + 2) * IF482_FRAME_SIZE * 1000.0 / baud; // +2 ms margin for the startbit and the clock's processing time - return pdMS_TO_TICKS(round(tx_delay)); + return pdMS_TO_TICKS(round(txTime)); } #endif // HAS_IF482 \ No newline at end of file diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 69cd6f34..40f2d1e8 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -443,7 +443,7 @@ void user_request_network_time_callback(void *pVoidUserUTCTime, int flagSuccess) { #ifdef HAS_LORA // Explicit conversion from void* to uint32_t* to avoid compiler errors - uint32_t *pUserUTCTime = (uint32_t *)pVoidUserUTCTime; + time_t *pUserUTCTime = (time_t *)pVoidUserUTCTime; lmic_time_reference_t lmicTimeReference; if (flagSuccess != 1) { @@ -468,11 +468,11 @@ void user_request_network_time_callback(void *pVoidUserUTCTime, ostime_t ticksRequestSent = lmicTimeReference.tLocal; // Add the delay between the instant the time was transmitted and // the current time - uint32_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000; + time_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000; *pUserUTCTime += requestDelaySec; // Update system time with time read from the network - if (syncTime(*pUserUTCTime, lora)) { // do we have a valid time? + if (syncTime(*pUserUTCTime, lora)) { // have we got a valid time? #ifdef HAS_RTC if (TimeIsSynced) set_rtctime(now()); // UTC time diff --git a/src/main.cpp b/src/main.cpp index af783420..e4056af0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -72,7 +72,7 @@ TaskHandle_t irqHandlerTask, ClockTask; SemaphoreHandle_t I2Caccess, TimePulse; bool volatile TimePulseTick = false; bool TimeIsSynced = false; -time_t LastSyncTime = 0, userUTCTime = 0; +time_t lastSyncTime = 0, userUTCTime = 0; // container holding unique MAC address hashes with Memory Alloctor using PSRAM, // if present diff --git a/src/timemanager.cpp b/src/timemanager.cpp index d2b6b99b..47f1d7c2 100644 --- a/src/timemanager.cpp +++ b/src/timemanager.cpp @@ -9,17 +9,21 @@ void time_sync() { #ifdef TIME_SYNC_INTERVAL - time_t lastTimeSync = now() - LastSyncTime; // check if a sync is due + static time_t ageOfTime = 0; + + ageOfTime = now() - lastSyncTime; // check if a sync is due + + // is it time to sync with external source or did we never sync yet? + if ((ageOfTime >= (TIME_SYNC_INTERVAL * 60000)) || !lastSyncTime) { - if ((lastTimeSync >= (TIME_SYNC_INTERVAL * 60000)) || !LastSyncTime) { - // is it time to sync with external source? #ifdef HAS_GPS - if (syncTime(get_gpstime(), pps)) // attempt sync with GPS time + syncTime(get_gpstime(), pps); // attempt sync with GPS time #endif + #if defined HAS_LORA && defined TIME_SYNC_LORA - if (!TimeIsSynced) // no GPS sync -> try lora sync - LMIC_requestNetworkTime(user_request_network_time_callback, - &userUTCTime); + if (!TimeIsSynced) // no GPS sync -> try lora sync + LMIC_requestNetworkTime(user_request_network_time_callback, + &userUTCTime); #endif } @@ -27,10 +31,11 @@ void time_sync() { if (TimeIsSynced) { // recalibrate RTC, if we have one set_rtctime(now()); } else { // we switch to fallback time after a while - if ((lastTimeSync >= (TIME_SYNC_TIMEOUT * 60000)) || - !LastSyncTime) { // sync is still due -> use RTC as fallback source - if (syncTime(get_rtctime(), rtc)) // sync with RTC time - TimeIsSynced = false; + if ((ageOfTime >= (TIME_SYNC_TIMEOUT * 60000)) || + !lastSyncTime) { // sync is still due -> use RTC as fallback source + if (!syncTime(get_rtctime(), rtc)) // sync with RTC time + ESP_LOGW(TAG, "no valid time"); + TimeIsSynced = false; } } #endif @@ -42,30 +47,26 @@ void time_sync() { int syncTime(time_t const t, uint8_t const timesource) { // symbol to display current time source - const char timeSetSymbols[] = {'G', 'R', 'L', '~' }; + const char timeSetSymbols[] = {'G', 'R', 'L', '~'}; if (TimeIsValid(t)) { TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse setTime(t); adjustTime(1); // forward time to next second - LastSyncTime = now(); // store time of this sync + lastSyncTime = now(); // store time of this sync timeSource = timeSetSymbols[timesource]; - ESP_LOGD(TAG, "Time was set to %02d:%02d:%02d", hour(t), minute(t), - second(t)); + ESP_LOGD(TAG, "Time source %c set time to %02d:%02d:%02d", timeSource, + hour(t), minute(t), second(t)); return 1; // success } else { - ESP_LOGD(TAG, "Time sync attempt failed"); timeSource = timeSetSymbols[unsynced]; TimeIsSynced = false; + ESP_LOGD(TAG, "Time source %c sync attempt failed", timeSource); return 0; } // failure } -int syncTime(uint32_t const t, uint8_t const timesource) { // t is UTC time in seconds epoch - return syncTime(static_cast(t), timesource); -} - // helper function to sync moment on timepulse int wait_for_pulse(void) { // sync on top of next second with 1pps timepulse @@ -153,8 +154,8 @@ time_t compiledUTC(void) { } // helper function to convert gps date/time into time_t -time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, - uint8_t mm, uint8_t ss) { +time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm, + uint8_t ss) { tmElements_t tm; tm.Year = CalendarYrToTm(YYYY); // year offset from 1970 in time.h tm.Month = MM;