timemanager fixes

This commit is contained in:
Klaus K Wilting 2019-02-23 23:39:45 +01:00
parent 60467ca195
commit feda8dd938
6 changed files with 43 additions and 39 deletions

View File

@ -114,7 +114,7 @@ extern SemaphoreHandle_t I2Caccess, TimePulse;
extern TaskHandle_t irqHandlerTask, ClockTask; extern TaskHandle_t irqHandlerTask, ClockTask;
extern TimerHandle_t WifiChanTimer; extern TimerHandle_t WifiChanTimer;
extern Timezone myTZ; extern Timezone myTZ;
extern time_t LastSyncTime, userUTCTime; extern time_t lastSyncTime, userUTCTime;
// application includes // application includes
#include "led.h" #include "led.h"

View File

@ -20,7 +20,6 @@ void clock_loop(void *pvParameters);
void time_sync(void); void time_sync(void);
int wait_for_pulse(void); int wait_for_pulse(void);
int syncTime(time_t const t, uint8_t const timesource); 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); void IRAM_ATTR CLOCKIRQ(void);
int timepulse_init(void); int timepulse_init(void);
void timepulse_start(void); void timepulse_start(void);

View File

@ -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 // triggered by timepulse to ticker out DCF signal
void IF482_Pulse(time_t t) { 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(); TickType_t startTime = xTaskGetTickCount();
static const TickType_t txDelay = pdMS_TO_TICKS(IF482_PULSE_LENGTH) - tx_Ticks(HAS_IF482);
vTaskDelayUntil(&startTime, txDelay); vTaskDelayUntil(&startTime, txDelay); // wait until moment to fire
IF482.print(IF482_Frame(t+1)); // note: if482 telegram for *next* second IF482.print(IF482_Frame(t + 1)); // note: if482 telegram for *next* second
} }
String IRAM_ATTR IF482_Frame(time_t startTime) { String IRAM_ATTR IF482_Frame(time_t startTime) {
time_t t = myTZ.toLocal(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 switch (timeStatus()) { // indicates if time has been set and recently synced
case timeSet: // time is set and is synced case timeSet: // time is set and is synced
@ -113,9 +116,10 @@ String IRAM_ATTR IF482_Frame(time_t startTime) {
} // switch } // switch
// generate IF482 telegram // generate IF482 telegram
snprintf(buf, sizeof(buf), "%02u%02u%02u%1u%02u%02u%02u", year(t) - 2000, snprintf(out, sizeof(out), "O%cL%02u%02u%02u%1u%02u%02u%02u\r", mon,
month(t), day(t), weekday(t), hour(t), minute(t), second(t)); year(t) - 2000, month(t), day(t), weekday(t), hour(t), minute(t),
snprintf(out, sizeof(out), "O%cL%s\r", mon, buf); second(t));
ESP_LOGD(TAG, "IF482 = %s", out); ESP_LOGD(TAG, "IF482 = %s", out);
return 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, TickType_t tx_Ticks(unsigned long baud, uint32_t config, int8_t rxPin,
int8_t txPins) { 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 stopbits = ((config & 0x20) >> 5) + 1;
uint32_t tx_delay = uint32_t txTime =
(2 + datenbits + stopbits) * IF482_FRAME_SIZE * 1000.0 / baud; (databits + stopbits + 2) * IF482_FRAME_SIZE * 1000.0 / baud;
// +2 ms margin for the startbit and the clock's processing time // +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 #endif // HAS_IF482

View File

@ -443,7 +443,7 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
int flagSuccess) { int flagSuccess) {
#ifdef HAS_LORA #ifdef HAS_LORA
// Explicit conversion from void* to uint32_t* to avoid compiler errors // 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; lmic_time_reference_t lmicTimeReference;
if (flagSuccess != 1) { if (flagSuccess != 1) {
@ -468,11 +468,11 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
ostime_t ticksRequestSent = lmicTimeReference.tLocal; ostime_t ticksRequestSent = lmicTimeReference.tLocal;
// Add the delay between the instant the time was transmitted and // Add the delay between the instant the time was transmitted and
// the current time // the current time
uint32_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000; time_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000;
*pUserUTCTime += requestDelaySec; *pUserUTCTime += requestDelaySec;
// Update system time with time read from the network // 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 #ifdef HAS_RTC
if (TimeIsSynced) if (TimeIsSynced)
set_rtctime(now()); // UTC time set_rtctime(now()); // UTC time

View File

@ -72,7 +72,7 @@ TaskHandle_t irqHandlerTask, ClockTask;
SemaphoreHandle_t I2Caccess, TimePulse; SemaphoreHandle_t I2Caccess, TimePulse;
bool volatile TimePulseTick = false; bool volatile TimePulseTick = false;
bool TimeIsSynced = 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, // container holding unique MAC address hashes with Memory Alloctor using PSRAM,
// if present // if present

View File

@ -9,13 +9,17 @@ void time_sync() {
#ifdef TIME_SYNC_INTERVAL #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 #ifdef HAS_GPS
if (syncTime(get_gpstime(), pps)) // attempt sync with GPS time syncTime(get_gpstime(), pps); // attempt sync with GPS time
#endif #endif
#if defined HAS_LORA && defined TIME_SYNC_LORA #if defined HAS_LORA && defined TIME_SYNC_LORA
if (!TimeIsSynced) // no GPS sync -> try lora sync if (!TimeIsSynced) // no GPS sync -> try lora sync
LMIC_requestNetworkTime(user_request_network_time_callback, LMIC_requestNetworkTime(user_request_network_time_callback,
@ -27,9 +31,10 @@ void time_sync() {
if (TimeIsSynced) { // recalibrate RTC, if we have one if (TimeIsSynced) { // recalibrate RTC, if we have one
set_rtctime(now()); set_rtctime(now());
} else { // we switch to fallback time after a while } else { // we switch to fallback time after a while
if ((lastTimeSync >= (TIME_SYNC_TIMEOUT * 60000)) || if ((ageOfTime >= (TIME_SYNC_TIMEOUT * 60000)) ||
!LastSyncTime) { // sync is still due -> use RTC as fallback source !lastSyncTime) { // sync is still due -> use RTC as fallback source
if (syncTime(get_rtctime(), rtc)) // sync with RTC time if (!syncTime(get_rtctime(), rtc)) // sync with RTC time
ESP_LOGW(TAG, "no valid time");
TimeIsSynced = false; TimeIsSynced = false;
} }
} }
@ -42,30 +47,26 @@ void time_sync() {
int syncTime(time_t const t, uint8_t const timesource) { int syncTime(time_t const t, uint8_t const timesource) {
// symbol to display current time source // symbol to display current time source
const char timeSetSymbols[] = {'G', 'R', 'L', '~' }; const char timeSetSymbols[] = {'G', 'R', 'L', '~'};
if (TimeIsValid(t)) { if (TimeIsValid(t)) {
TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse TimeIsSynced = wait_for_pulse(); // wait for next 1pps timepulse
setTime(t); setTime(t);
adjustTime(1); // forward time to next second adjustTime(1); // forward time to next second
LastSyncTime = now(); // store time of this sync lastSyncTime = now(); // store time of this sync
timeSource = timeSetSymbols[timesource]; timeSource = timeSetSymbols[timesource];
ESP_LOGD(TAG, "Time was set to %02d:%02d:%02d", hour(t), minute(t), ESP_LOGD(TAG, "Time source %c set time to %02d:%02d:%02d", timeSource,
second(t)); hour(t), minute(t), second(t));
return 1; // success return 1; // success
} else { } else {
ESP_LOGD(TAG, "Time sync attempt failed");
timeSource = timeSetSymbols[unsynced]; timeSource = timeSetSymbols[unsynced];
TimeIsSynced = false; TimeIsSynced = false;
ESP_LOGD(TAG, "Time source %c sync attempt failed", timeSource);
return 0; return 0;
} }
// failure // failure
} }
int syncTime(uint32_t const t, uint8_t const timesource) { // t is UTC time in seconds epoch
return syncTime(static_cast<time_t>(t), timesource);
}
// helper function to sync moment on timepulse // helper function to sync moment on timepulse
int wait_for_pulse(void) { int wait_for_pulse(void) {
// sync on top of next second with 1pps timepulse // 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 // 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, time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm,
uint8_t mm, uint8_t ss) { uint8_t ss) {
tmElements_t tm; tmElements_t tm;
tm.Year = CalendarYrToTm(YYYY); // year offset from 1970 in time.h tm.Year = CalendarYrToTm(YYYY); // year offset from 1970 in time.h
tm.Month = MM; tm.Month = MM;