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 TimerHandle_t WifiChanTimer;
extern Timezone myTZ;
extern time_t LastSyncTime, userUTCTime;
extern time_t lastSyncTime, userUTCTime;
// application includes
#include "led.h"

View File

@ -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);

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
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

View File

@ -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

View File

@ -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

View File

@ -9,13 +9,17 @@ 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,
@ -27,9 +31,10 @@ 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
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;
}
}
@ -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<time_t>(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;