timesource display

This commit is contained in:
Klaus K Wilting 2019-02-23 21:51:24 +01:00
parent d0de4ae3bc
commit 60467ca195
8 changed files with 36 additions and 35 deletions

View File

@ -4,7 +4,9 @@
#include <U8x8lib.h> #include <U8x8lib.h>
#include "cyclic.h" #include "cyclic.h"
extern uint8_t volatile DisplayState; extern uint8_t DisplayState;
extern char timeSource;
extern HAS_DISPLAY u8x8; extern HAS_DISPLAY u8x8;
void init_display(const char *Productname, const char *Version); void init_display(const char *Productname, const char *Version);

View File

@ -2,6 +2,7 @@
#define _RTCTIME_H #define _RTCTIME_H
#include "globals.h" #include "globals.h"
#include "timemanager.h"
#include <Wire.h> // must be included here so that Arduino library object file references work #include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h> #include <RtcDS3231.h>

View File

@ -13,18 +13,20 @@
#include "dcf77.h" #include "dcf77.h"
#endif #endif
time_t tmConvert_t(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, enum timesources { pps, rtc, lora, unsynced };
uint8_t mm, uint8_t ss);
void clock_init(void); void clock_init(void);
void clock_loop(void *pvParameters); 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); int syncTime(time_t const t, uint8_t const timesource);
int syncTime(uint32_t t); 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);
int TimeIsValid(time_t t); int TimeIsValid(time_t const t);
time_t compiledUTC(void); time_t compiledUTC(void);
time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh,
uint8_t mm, uint8_t ss);
#endif // _timemanager_H #endif // _timemanager_H

View File

@ -45,7 +45,8 @@ const char lora_datarate[] = {"121110090807FSNA"};
const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun", const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
uint8_t volatile DisplayState = 0; uint8_t DisplayState = 0;
char timeSource = '?';
// helper function, prints a hex key on display // helper function, prints a hex key on display
void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) { void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) {
@ -129,16 +130,6 @@ void init_display(const char *Productname, const char *Version) {
void refreshtheDisplay() { void refreshtheDisplay() {
// time display symbols
const char timeNotSetSymbol = '?';
#if defined HAS_IF482
const char timeIsSetSymbol = '+';
#elif defined HAS_DCF77
const char timeIsSetSymbol = '*';
#else
const char timeIsSetSymbol = '#';
#endif
uint8_t msgWaiting; uint8_t msgWaiting;
char timeIsSet, timeState; char timeIsSet, timeState;
char buff[16]; // 16 chars line buffer char buff[16]; // 16 chars line buffer
@ -227,8 +218,7 @@ void refreshtheDisplay() {
u8x8.printf("%-16s", display_line6); u8x8.printf("%-16s", display_line6);
#else // we want a systime display instead LoRa status #else // we want a systime display instead LoRa status
t = myTZ.toLocal(now()); t = myTZ.toLocal(now());
timeIsSet = timeIsSet = (timeStatus() == timeNotSet) ? '#' : timeSource;
(timeStatus() == timeNotSet) ? timeNotSetSymbol : timeIsSetSymbol;
timeState = TimePulseTick ? ' ' : timeIsSet; timeState = TimePulseTick ? ' ' : timeIsSet;
TimePulseTick = false; TimePulseTick = false;
u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t), u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t),

View File

@ -86,7 +86,7 @@ time_t get_gpstime(void) {
gps.time.isValid() ? "yes" : "no"); gps.time.isValid() ? "yes" : "no");
// use recent gps time // use recent gps time
t = tmConvert_t(gps.date.year(), gps.date.month(), gps.date.day(), t = tmConvert(gps.date.year(), gps.date.month(), gps.date.day(),
gps.time.hour(), gps.time.minute(), gps.time.second()); gps.time.hour(), gps.time.minute(), gps.time.second());
ESP_LOGD(TAG, "GPS time: %02d.%02d.%04d %02d:%02d:%02d", gps.date.day(), ESP_LOGD(TAG, "GPS time: %02d.%02d.%04d %02d:%02d:%02d", gps.date.day(),

View File

@ -460,7 +460,7 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
// Update userUTCTime, considering the difference between the GPS and UTC // Update userUTCTime, considering the difference between the GPS and UTC
// time, and the leap seconds // time, and the leap seconds
// !!! DANGER !!! This code will expire in the year when next leap second happenes // !!! DANGER !!! This code will expire in next year with leap second
*pUserUTCTime = lmicTimeReference.tNetwork + 315964800; *pUserUTCTime = lmicTimeReference.tNetwork + 315964800;
// Current time, in ticks // Current time, in ticks
ostime_t ticksNow = os_getTime(); ostime_t ticksNow = os_getTime();
@ -472,12 +472,11 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
*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)) { // do we have a valid time? if (syncTime(*pUserUTCTime, lora)) { // do we have a valid time?
#ifdef HAS_RTC #ifdef HAS_RTC
if (TimeIsSynced) if (TimeIsSynced)
set_rtctime(now()); // UTC time set_rtctime(now()); // UTC time
#endif #endif
LastSyncTime = now(); // remember time of this sync event
ESP_LOGI(TAG, "LORA has set the system time"); ESP_LOGI(TAG, "LORA has set the system time");
} else } else
ESP_LOGI(TAG, "Unable to sync system time with LORA"); ESP_LOGI(TAG, "Unable to sync system time with LORA");

View File

@ -84,7 +84,7 @@
// settings for syncing time of node and external time sources // settings for syncing time of node and external time sources
#define TIME_SYNC_INTERVAL 10 // sync time each .. minutes from external time source (GPS/LORA) [default = 10], comment out means off #define TIME_SYNC_INTERVAL 10 // sync time each .. minutes from external time source (GPS/LORA) [default = 10], comment out means off
#define TIME_SYNC_TIMEOUT 30 // fallback to rtc for timesync after .. minutes no sync with external time source #define TIME_SYNC_TIMEOUT 30 // fallback to rtc for timesync after .. minutes no sync with external time source
//#define TIME_SYNC_LORA 1 // use LORA network for timesync, comment out means off [default = off] #define TIME_SYNC_LORA 1 // use LORA network for timesync, comment out means off [default = off]
// time zone, see https://github.com/JChristensen/Timezone/blob/master/examples/WorldClock/WorldClock.ino // 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 DAYLIGHT_TIME {"CEST", Last, Sun, Mar, 2, 120} // Central European Summer Time

View File

@ -14,11 +14,12 @@ void time_sync() {
if ((lastTimeSync >= (TIME_SYNC_INTERVAL * 60000)) || !LastSyncTime) { if ((lastTimeSync >= (TIME_SYNC_INTERVAL * 60000)) || !LastSyncTime) {
// is it time to sync with external source? // is it time to sync with external source?
#ifdef HAS_GPS #ifdef HAS_GPS
syncTime(get_gpstime()); // attempt sync with GPS time if (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, &userUTCTime); LMIC_requestNetworkTime(user_request_network_time_callback,
&userUTCTime);
#endif #endif
} }
@ -28,8 +29,8 @@ void time_sync() {
} 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 ((lastTimeSync >= (TIME_SYNC_TIMEOUT * 60000)) ||
!LastSyncTime) { // sync is still due -> use RTC as fallback source !LastSyncTime) { // sync is still due -> use RTC as fallback source
syncTime(get_rtctime()); // sync with RTC time if (syncTime(get_rtctime(), rtc)) // sync with RTC time
TimeIsSynced = false; TimeIsSynced = false;
} }
} }
#endif #endif
@ -38,25 +39,31 @@ void time_sync() {
} // time_sync() } // time_sync()
// helper function to sync time on start of next second // helper function to sync time on start of next second
int syncTime(time_t t) { int syncTime(time_t const t, uint8_t const timesource) {
// symbol to display current time source
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];
ESP_LOGD(TAG, "Time was set to %02d:%02d:%02d", hour(t), minute(t), ESP_LOGD(TAG, "Time was set to %02d:%02d:%02d", hour(t), minute(t),
second(t)); second(t));
return 1; // success return 1; // success
} else { } else {
ESP_LOGD(TAG, "Time sync attempt failed"); ESP_LOGD(TAG, "Time sync attempt failed");
timeSource = timeSetSymbols[unsynced];
TimeIsSynced = false; TimeIsSynced = false;
return 0; return 0;
} }
// failure // failure
} }
int syncTime(uint32_t t) { // t is UTC time in seconds epoch int syncTime(uint32_t const t, uint8_t const timesource) { // t is UTC time in seconds epoch
return syncTime(static_cast<time_t>(t)); return syncTime(static_cast<time_t>(t), timesource);
} }
// helper function to sync moment on timepulse // helper function to sync moment on timepulse
@ -132,7 +139,7 @@ void IRAM_ATTR CLOCKIRQ(void) {
} }
// helper function to check plausibility of a time // helper function to check plausibility of a time
int TimeIsValid(time_t t) { int TimeIsValid(time_t const t) {
// is it a time in the past? we use compile date to guess // is it a time in the past? we use compile date to guess
ESP_LOGD(TAG, "t=%d, tt=%d, valid: %s", t, compiledUTC(), ESP_LOGD(TAG, "t=%d, tt=%d, valid: %s", t, compiledUTC(),
(t >= compiledUTC()) ? "yes" : "no"); (t >= compiledUTC()) ? "yes" : "no");
@ -146,7 +153,7 @@ 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_t(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 ss) { uint8_t mm, 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
@ -217,7 +224,7 @@ void clock_loop(void *pvParameters) { // ClockTask
#elif defined HAS_DCF77 #elif defined HAS_DCF77
if (second(t) == DCF77_FRAME_SIZE - 1) // is it time to load new frame? if (second(t) == DCF77_FRAME_SIZE - 1) // is it time to load new frame?
DCFpulse = DCF77_Frame(t1(t)); // generate next frame DCFpulse = DCF77_Frame(t1(t)); // generate next frame
if (DCFpulse[DCF77_FRAME_SIZE] == if (DCFpulse[DCF77_FRAME_SIZE] ==
minute(t1(t))) // have recent frame? (pulses could be missed!) minute(t1(t))) // have recent frame? (pulses could be missed!)