From 3e00fecb28f2ab12f2876c243202d3aeb5f9d2a8 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 9 May 2021 00:02:41 +0200 Subject: [PATCH] migration to ezTime lib --- include/dcf77.h | 1 + include/display.h | 2 +- include/globals.h | 3 +-- include/if482.h | 3 ++- include/mobaserial.h | 1 + include/timekeeper.h | 1 - platformio_orig.ini | 3 +-- src/dcf77.cpp | 28 +++++++++++++--------------- src/display.cpp | 16 ++++------------ src/gpsread.cpp | 16 ++++++++-------- src/if482.cpp | 15 ++++++--------- src/ledmatrixdisplay.cpp | 9 +++------ src/main.cpp | 5 +++++ src/mobaserial.cpp | 11 +++++------ src/paxcounter_orig.conf | 5 +---- src/timekeeper.cpp | 21 +++++++++------------ src/timesync.cpp | 13 +++++++------ 17 files changed, 68 insertions(+), 85 deletions(-) diff --git a/include/dcf77.h b/include/dcf77.h index 4159d040..964389ee 100644 --- a/include/dcf77.h +++ b/include/dcf77.h @@ -2,6 +2,7 @@ #define _DCF77_H #include "globals.h" +#include "timekeeper.h" #define DCF77_FRAME_SIZE (60) #define DCF77_PULSE_LENGTH (100) diff --git a/include/display.h b/include/display.h index 67191c5b..2b00aa44 100644 --- a/include/display.h +++ b/include/display.h @@ -88,7 +88,7 @@ void dp_refresh(bool nextPage = false); void dp_init(bool verbose = false); void dp_shutdown(void); void dp_message(const char *msg, int line, bool invers); -void dp_drawPage(time_t t, bool nextpage); +void dp_drawPage(bool nextpage); void dp_println(int lines = 1); void dp_printf(const char *format, ...); void dp_setFont(int font, int inv = 0); diff --git a/include/globals.h b/include/globals.h index 95816f41..6ef437ed 100644 --- a/include/globals.h +++ b/include/globals.h @@ -5,8 +5,7 @@ #include // Time functions -#include "microTime.h" -#include +#include #include #include diff --git a/include/if482.h b/include/if482.h index 4f6447e7..c1826b8b 100644 --- a/include/if482.h +++ b/include/if482.h @@ -2,10 +2,11 @@ #define _IF482_H #include "globals.h" +#include "timekeeper.h" #define IF482_FRAME_SIZE (17) #define IF482_SYNC_FIXUP (10) // calibration to fixup processing time [milliseconds] -String IRAM_ATTR IF482_Frame(time_t tt); +String IRAM_ATTR IF482_Frame(time_t t); #endif \ No newline at end of file diff --git a/include/mobaserial.h b/include/mobaserial.h index c3b47ab8..a9d56897 100644 --- a/include/mobaserial.h +++ b/include/mobaserial.h @@ -2,6 +2,7 @@ #define _MOBALINE_H #include "globals.h" +#include "timekeeper.h" #include "dcf77.h" #define MOBALINE_FRAME_SIZE (33) diff --git a/include/timekeeper.h b/include/timekeeper.h index ac85223f..2fc2c879 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -3,7 +3,6 @@ #include "globals.h" #include "rtctime.h" -#include "TimeLib.h" #include "irqhandler.h" #include "timesync.h" #include "gpsread.h" diff --git a/platformio_orig.ini b/platformio_orig.ini index c76c1b96..b3885347 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -83,8 +83,7 @@ lib_deps_sensors = lib_deps_basic = https://github.com/SukkoPera/Arduino-Rokkit-Hash.git bblanchon/ArduinoJson @ ^6 - jchristensen/Timezone @ ^1.2.4 - https://github.com/cyberman54/microTime.git + m5ez/ezTime @ ^0.8.3 makuna/RTC @ ^2.3.5 spacehuhn/SimpleButton lewisxhe/AXP202X_Library @ ^1.1.3 diff --git a/src/dcf77.cpp b/src/dcf77.cpp index 45924528..e579b216 100644 --- a/src/dcf77.cpp +++ b/src/dcf77.cpp @@ -20,11 +20,9 @@ static const char TAG[] = __FILE__; void DCF77_Pulse(time_t t, uint8_t const *DCFpulse) { TickType_t startTime = xTaskGetTickCount(); - uint8_t sec = second(t); + uint8_t sec = myTZ.second(t); - t = myTZ.toLocal(now()); - ESP_LOGD(TAG, "[%02d:%02d:%02d.%03d] DCF second %d", hour(t), minute(t), - second(t), millisecond(), sec); + ESP_LOGD(TAG, "[%s] DCF second: %d", myTZ.dateTime("H:i:s.v").c_str(), sec); // induce a DCF Pulse for (uint8_t pulse = 0; pulse <= 2; pulse++) { @@ -53,7 +51,7 @@ void DCF77_Pulse(time_t t, uint8_t const *DCFpulse) { } // for } // DCF77_Pulse() -uint8_t *IRAM_ATTR DCF77_Frame(time_t const tt) { +uint8_t *IRAM_ATTR DCF77_Frame(time_t const t) { // array of dcf pulses for one minute, secs 0..16 and 20 are never touched, so // we keep them statically to avoid same recalculation every minute @@ -64,35 +62,35 @@ uint8_t *IRAM_ATTR DCF77_Frame(time_t const tt) { dcf_0, dcf_0, dcf_0, dcf_0, dcf_0, dcf_0, dcf_1}; uint8_t Parity; - time_t t = myTZ.toLocal(tt); // convert to local time // ENCODE DST CHANGE ANNOUNCEMENT (Sec 16) DCFpulse[16] = dcf_0; // not yet implemented // ENCODE DAYLIGHTSAVING (secs 17..18) - DCFpulse[17] = myTZ.locIsDST(t) ? dcf_1 : dcf_0; - DCFpulse[18] = myTZ.locIsDST(t) ? dcf_0 : dcf_1; + DCFpulse[17] = myTZ.isDST(t) ? dcf_1 : dcf_0; + DCFpulse[18] = myTZ.isDST(t) ? dcf_0 : dcf_1; // ENCODE MINUTE (secs 21..28) - Parity = dec2bcd(minute(t), 21, 27, DCFpulse); + Parity = dec2bcd(myTZ.minute(t), 21, 27, DCFpulse); DCFpulse[28] = setParityBit(Parity); // ENCODE HOUR (secs 29..35) - Parity = dec2bcd(hour(t), 29, 34, DCFpulse); + Parity = dec2bcd(myTZ.hour(t), 29, 34, DCFpulse); DCFpulse[35] = setParityBit(Parity); // ENCODE DATE (secs 36..58) - Parity = dec2bcd(day(t), 36, 41, DCFpulse); - Parity += dec2bcd((weekday(t) - 1) ? (weekday(t) - 1) : 7, 42, 44, DCFpulse); - Parity += dec2bcd(month(t), 45, 49, DCFpulse); - Parity += dec2bcd(year(t) - 2000, 50, 57, DCFpulse); + Parity = dec2bcd(myTZ.day(t), 36, 41, DCFpulse); + Parity += dec2bcd((myTZ.weekday(t) - 1) ? (myTZ.weekday(t) - 1) : 7, 42, 44, + DCFpulse); + Parity += dec2bcd(myTZ.month(t), 45, 49, DCFpulse); + Parity += dec2bcd(myTZ.year(t) - 2000, 50, 57, DCFpulse); DCFpulse[58] = setParityBit(Parity); // ENCODE MARK (sec 59) DCFpulse[59] = dcf_Z; // !! missing code here for leap second !! // timestamp this frame with it's minute - DCFpulse[60] = minute(t); + DCFpulse[60] = myTZ.minute(t); return DCFpulse; diff --git a/src/display.cpp b/src/display.cpp index e535e405..34046274 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -39,9 +39,6 @@ MY_FONT_STRETCHED: 16x32px = 8 chars / line // local Tag for logging static const char TAG[] = __FILE__; -// helper array for converting month values to text -const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; uint8_t DisplayIsOn = 0; uint8_t displaybuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0}; static uint8_t plotbuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0}; @@ -191,9 +188,6 @@ void dp_refresh(bool nextPage) { if (!DisplayIsOn && (DisplayIsOn == cfg.screenon)) return; - const time_t t = - myTZ.toLocal(now()); // note: call now() here *before* locking mutex! - // block i2c bus access if (!I2C_MUTEX_LOCK()) ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", _seconds()); @@ -212,7 +206,7 @@ void dp_refresh(bool nextPage) { } #endif - dp_drawPage(t, nextPage); + dp_drawPage(nextPage); dp_dump(displaybuf); I2C_MUTEX_UNLOCK(); // release i2c bus access @@ -220,7 +214,7 @@ void dp_refresh(bool nextPage) { } // mutex } // refreshDisplay() -void dp_drawPage(time_t t, bool nextpage) { +void dp_drawPage(bool nextpage) { // write display content to display buffer // nextpage = true -> flip 1 page @@ -330,9 +324,7 @@ void dp_drawPage(time_t t, bool nextpage) { #if (TIME_SYNC_INTERVAL) timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource]; TimePulseTick = false; - - dp_printf("%02d.%3s %4d", day(t), printmonth[month(t)], year(t)); - dp_printf(" %02d:%02d:%02d", hour(t), minute(t), second(t)); + dp_printf("%s", myTZ.dateTime("d.M Y H:i:s").c_str()); // display inverse timeState if clock controller is enabled #if (defined HAS_DCF77) || (defined HAS_IF482) @@ -450,7 +442,7 @@ void dp_drawPage(time_t t, bool nextpage) { dp_setFont(MY_FONT_LARGE); dp_setTextCursor(0, 4); - dp_printf("%02d:%02d:%02d", hour(t), minute(t), second(t)); + dp_printf("%s", myTZ.dateTime("H:i:s").c_str()); break; // ---------- page 5: pax graph ---------- diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 79c0847d..a8f96635 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -111,16 +111,16 @@ time_t get_gpstime(uint16_t *msec) { uint32_t zdatime = atof(gpstime.value()); // convert time to maketime format and make time - tm.Second = zdatime % 100; // second - tm.Minute = (zdatime / 100) % 100; // minute - tm.Hour = zdatime / 10000; // hour - tm.Day = atoi(gpsday.value()); // day - tm.Month = atoi(gpsmonth.value()); // month - tm.Year = CalendarYrToTm(atoi(gpsyear.value())); // year offset from 1970 + tm.Second = zdatime % 100; // second + tm.Minute = (zdatime / 100) % 100; // minute + tm.Hour = zdatime / 10000; // hour + tm.Day = atoi(gpsday.value()); // day + tm.Month = atoi(gpsmonth.value()); // month + tm.Year = atoi(gpsyear.value()) - 1970; // year offset from 1970 t = makeTime(tm); - ESP_LOGD(TAG, "GPS time/date = %02d:%02d:%02d / %02d.%02d.%2d", tm.Hour, - tm.Minute, tm.Second, tm.Day, tm.Month, tm.Year + 1970); + ESP_LOGD(TAG, "GPS date/time: %s", + UTC.dateTime(t, "d.M Y H:i:s T").c_str()); // add protocol delay with millisecond precision t += delay_ms / 1000 - 1; // whole seconds diff --git a/src/if482.cpp b/src/if482.cpp index 7511a821..afbc16cc 100644 --- a/src/if482.cpp +++ b/src/if482.cpp @@ -14,7 +14,7 @@ IF482.cpp depends on code in RTCTIME.cpp. /* IF482 Generator to control clocks with IF482 telegram input (e.g. BÜRK BU190) - + Example IF482 telegram: "OAL160806F170400" @@ -84,9 +84,8 @@ not evaluated by model BU-190, use "F" instead for this model // Local logging tag static const char TAG[] = __FILE__; -String IRAM_ATTR IF482_Frame(time_t printTime) { +String IRAM_ATTR IF482_Frame(time_t t) { - time_t t = myTZ.toLocal(printTime); char mon, out[IF482_FRAME_SIZE + 1]; switch (timeStatus()) { // indicates if time has been set and recently synced @@ -102,13 +101,11 @@ String IRAM_ATTR IF482_Frame(time_t printTime) { } // switch // generate IF482 telegram - 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)); + snprintf(out, sizeof(out), "O%cL%s\r", mon, myTZ.dateTime(t, UTC_TIME, "ymdwHis").c_str()); + + ESP_LOGD(TAG, "[%s] IF482 date/time: %s", myTZ.dateTime("H:i:s.v").c_str(), + out); - t = myTZ.toLocal(now()); - ESP_LOGD(TAG, "[%02d:%02d:%02d.%03d] IF482 = %s", hour(t), minute(t), - second(t), millisecond(), out); return out; } diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index 61b4fc89..2abd38aa 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -12,7 +12,7 @@ static const char TAG[] = __FILE__; uint8_t MatrixDisplayIsOn = 0; static uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8] = {0}; static unsigned long ulLastNumMacs = 0; -static time_t ulLastTime = myTZ.toLocal(now()); +static time_t ulLastTime = now(); hw_timer_t *matrixDisplayIRQ = NULL; @@ -47,7 +47,6 @@ void init_matrix_display(bool reverse) { void refreshTheMatrixDisplay(bool nextPage) { static uint8_t DisplayPage = 0, col = 0, row = 0; uint8_t level; - char buff[16]; // if Matrixdisplay is switched off we don't refresh it to relax cpu if (!MatrixDisplayIsOn && (MatrixDisplayIsOn == cfg.screenon)) @@ -117,13 +116,11 @@ void refreshTheMatrixDisplay(bool nextPage) { case 1: - const time_t t = myTZ.toLocal(now()); + const time_t t = now(); if (ulLastTime != t) { ulLastTime = t; matrix.clear(); - snprintf(buff, sizeof(buff), "%02d:%02d:%02d", hour(t), minute(t), - second(t)); - DrawNumber(String(buff)); + DrawNumber(myTZ.dateTime("H:i:s").c_str()); } break; diff --git a/src/main.cpp b/src/main.cpp index f1a977a8..fd364858 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -118,6 +118,11 @@ void setup() { // load device configuration from NVRAM and set runmode do_after_reset(); + // set time zone to user value from paxcounter.conf +#ifdef TIME_SYNC_TIMEZONE + myTZ.setPosix(TIME_SYNC_TIMEZONE); +#endif + // hash 6 byte device MAC to 4 byte clientID uint8_t mac[6]; esp_eth_get_mac(mac); diff --git a/src/mobaserial.cpp b/src/mobaserial.cpp index 7c330e15..bffdea09 100644 --- a/src/mobaserial.cpp +++ b/src/mobaserial.cpp @@ -18,11 +18,10 @@ static const char TAG[] = __FILE__; void MOBALINE_Pulse(time_t t, uint8_t const *DCFpulse) { TickType_t startTime = xTaskGetTickCount(); - uint8_t sec = second(t); + uint8_t sec = myTZ.second(t); - t = myTZ.toLocal(now()); - ESP_LOGD(TAG, "[%02d:%02d:%02d.%03d] MOBALINE bit %d", hour(t), minute(t), - second(t), millisecond(), sec); + ESP_LOGD(TAG, "[%s] MOBALINE sec: %d", myTZ.dateTime("H:i:s.v").c_str(), + sec); // induce 3 pulses for (uint8_t pulse = 0; pulse <= 3; pulse++) { @@ -68,13 +67,13 @@ uint8_t *IRAM_ATTR MOBALINE_Frame(time_t const tt) { static uint8_t DCFpulse[DCF77_FRAME_SIZE + 1]; - time_t t = myTZ.toLocal(tt); // convert to local time + time_t t = myTZ.tzTime(tt); // convert to local time // ENCODE HEAD (bit 0)) DCFpulse[0] = dcf_Z; // not yet implemented // ENCODE DAYLIGHTSAVING (bit 1) - DCFpulse[1] = myTZ.locIsDST(t) ? dcf_1 : dcf_0; + DCFpulse[1] = myTZ.isDST(t) ? dcf_1 : dcf_0; // ENCODE DATE (bits 2..20) dec2bcd(false, year(t) - 2000, 2, 9, DCFpulse); diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index b1235d11..988cbb1c 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -88,10 +88,7 @@ #define TIME_SYNC_CYCLE 60 // delay between two time samples [seconds] #define TIME_SYNC_TIMEOUT 400 // timeout waiting for timeserver answer [seconds] #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] - -// time zone, see https://github.com/JChristensen/Timezone/blob/master/examples/WorldClock/WorldClock.ino -#define DAYLIGHT_TIME {"CEST", Last, Sun, Mar, 2, 120} // Central European Summer Time -#define STANDARD_TIME {"CET ", Last, Sun, Oct, 3, 60} // Central European Standard Time +#define TIME_SYNC_TIMEZONE "CET-1CEST,M3.4.0/2,M10.4.0/3" // Timezone in POSIX format (example shows Germany/Berlin) // Ports on which the device sends and listenes on LoRaWAN and SPI #define COUNTERPORT 1 // counts diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 885716d5..031259a0 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -8,7 +8,7 @@ #endif #endif -#define _COMPILETIME myTZ.toUTC(RtcDateTime(__DATE__, __TIME__).Epoch32Time()) +#define _COMPILETIME compileTime() // Local logging tag static const char TAG[] = __FILE__; @@ -17,10 +17,8 @@ static const char TAG[] = __FILE__; // G = GPS / R = RTC / L = LORA / ? = unsynced / = sync unknown const char timeSetSymbols[] = {'G', 'R', 'L', '?', ' '}; -// set Time Zone for user setting from paxcounter.conf -TimeChangeRule myDST = DAYLIGHT_TIME; -TimeChangeRule mySTD = STANDARD_TIME; -Timezone myTZ(myDST, mySTD); +// set Time Zone +Timezone myTZ; bool volatile TimePulseTick = false; timesource_t timeSource = _unsynced; @@ -115,7 +113,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, CLOCKIRQ(); // fire clock pps, this advances time 1 sec } - setTime(time_to_set); // set the time on top of second + UTC.setTime(time_to_set); // set the time on top of second timeSource = mytimesource; // set global variable timesyncer.attach(TIME_SYNC_INTERVAL * 60, setTimeSyncIRQ); @@ -173,7 +171,6 @@ uint8_t timepulse_init() { } // timepulse_init void timepulse_start(void) { - #ifdef GPS_INT // start external clock gps pps line attachInterrupt(digitalPinToInterrupt(GPS_INT), CLOCKIRQ, RISING); #elif defined RTC_INT // start external clock rtc @@ -193,7 +190,7 @@ void IRAM_ATTR CLOCKIRQ(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - SyncToPPS(); // advance systime, see microTime.h + // syncToPPS(); // currently not used // advance wall clock, if we have #if (defined HAS_IF482 || defined HAS_DCF77) @@ -213,10 +210,10 @@ void IRAM_ATTR CLOCKIRQ(void) { portYIELD_FROM_ISR(); } -// helper function to check plausibility of a time +// helper function to check plausibility of a given epoch time time_t timeIsValid(time_t const t) { // is it a time in the past? we use compile date to guess - return (t >= _COMPILETIME ? t : 0); + return (t < myTZ.tzTime(_COMPILETIME) ? 0 : t); } // helper function to calculate serial transmit time @@ -301,7 +298,7 @@ void clock_loop(void *taskparameter) { // ClockTask t = time_t(printtime); // new adjusted UTC time seconds // send IF482 telegram - IF482.print(IF482_Frame(t + 1)); // note: telegram is for *next* second + IF482.print(IF482_Frame(t + 2)); // note: telegram is for *next* second #elif defined HAS_DCF77 @@ -310,7 +307,7 @@ void clock_loop(void *taskparameter) { // ClockTask if (minute(nextmin(t)) == // do we still have a recent frame? DCFpulse[DCF77_FRAME_SIZE]) // (timepulses could be missed!) - DCF77_Pulse(t, DCFpulse); // then output current second's pulse + DCF77_Pulse(t + 1, DCFpulse); // then output next second's pulse // else we have no recent frame, thus suppressing clock output diff --git a/src/timesync.cpp b/src/timesync.cpp index 55a0d82f..56bb52a7 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -97,8 +97,7 @@ void IRAM_ATTR timesync_processReq(void *taskparameter) { // wait until a timestamp was received if (xTaskNotifyWait(0x00, ULONG_MAX, &rcv_seqNo, pdMS_TO_TICKS(TIME_SYNC_TIMEOUT * 1000)) == pdFALSE) { - ESP_LOGW(TAG, "[d%0.3f] Timesync aborted: timed out", - _seconds()); + ESP_LOGW(TAG, "[d%0.3f] Timesync aborted: timed out", _seconds()); goto Fail; // no timestamp received before timeout } @@ -143,6 +142,9 @@ void IRAM_ATTR timesync_processReq(void *taskparameter) { time_offset_ms += TIME_SYNC_FIXUP; time_offset_ms %= 1000; + ESP_LOGD(TAG, "LORA date/time: %s", + myTZ.dateTime(time_offset_sec, "d.M Y H:i:s T").c_str()); + setMyTime(time_offset_sec, time_offset_ms, _lora); // send timesync end char to show timesync was successful @@ -166,8 +168,8 @@ void IRAM_ATTR timesync_processReq(void *taskparameter) { // store incoming timestamps void timesync_store(uint32_t timestamp, timesync_t timestamp_type) { - ESP_LOGD(TAG, "[%0.3f] seq#%d[%d]: t%d=%d", _seconds(), - time_sync_seqNo, sample_idx, timestamp_type, timestamp); + ESP_LOGD(TAG, "[%0.3f] seq#%d[%d]: t%d=%d", _seconds(), time_sync_seqNo, + sample_idx, timestamp_type, timestamp); timesync_timestamp[sample_idx][timestamp_type] = timestamp; } @@ -232,8 +234,7 @@ void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) { lmic_time_reference_t lmicTime; if (flag != 1) { - ESP_LOGW(TAG, "[%0.3f] Network did not answer time request", - _seconds()); + ESP_LOGW(TAG, "[%0.3f] Network did not answer time request", _seconds()); goto Exit; }