migration to ezTime lib

This commit is contained in:
cyberman54 2021-05-09 00:02:41 +02:00
parent 85f1b74678
commit 3e00fecb28
17 changed files with 68 additions and 85 deletions

View File

@ -2,6 +2,7 @@
#define _DCF77_H
#include "globals.h"
#include "timekeeper.h"
#define DCF77_FRAME_SIZE (60)
#define DCF77_PULSE_LENGTH (100)

View File

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

View File

@ -5,8 +5,7 @@
#include <Arduino.h>
// Time functions
#include "microTime.h"
#include <Timezone.h>
#include <ezTime.h>
#include <RtcDateTime.h>
#include <Ticker.h>

View File

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

View File

@ -2,6 +2,7 @@
#define _MOBALINE_H
#include "globals.h"
#include "timekeeper.h"
#include "dcf77.h"
#define MOBALINE_FRAME_SIZE (33)

View File

@ -3,7 +3,6 @@
#include "globals.h"
#include "rtctime.h"
#include "TimeLib.h"
#include "irqhandler.h"
#include "timesync.h"
#include "gpsread.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 / <blank> = 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

View File

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