Code for RTC time sync added

This commit is contained in:
Klaus K Wilting 2019-01-21 16:16:39 +01:00
parent a0c5bb5086
commit 5bc2ffab09
4 changed files with 64 additions and 63 deletions

View File

@ -2,9 +2,14 @@
#define _RTCTIME_H #define _RTCTIME_H
#include "globals.h" #include "globals.h"
#include <Time.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>
#ifdef HAS_GPS
#include "gpsread.h"
#endif
typedef enum { typedef enum {
useless = 0, // waiting for good enough signal useless = 0, // waiting for good enough signal
dirty = 1, // time data available but inconfident dirty = 1, // time data available but inconfident
@ -15,10 +20,11 @@ typedef enum {
int rtc_init(void); int rtc_init(void);
void sync_rtctime(void); void sync_rtctime(void);
int set_rtctime(uint32_t UTCTime, clock_state_t state); int set_rtctime(uint32_t UTCTime);
int set_rtctime(RtcDateTime now, clock_state_t state); int set_rtctime(RtcDateTime now);
void sync_rtctime(void); void sync_rtctime(void);
time_t get_rtctime(void); time_t get_rtctime(void);
float get_rtctemp(void); float get_rtctemp(void);
time_t gpsTimeSync(void);
#endif // _RTCTIME_H #endif // _RTCTIME_H

View File

@ -123,32 +123,34 @@ void reset_counters() {
void do_timesync() { void do_timesync() {
#ifdef TIME_SYNC_INTERVAL #ifdef TIME_SYNC_INTERVAL
// sync time & date by GPS if we have valid gps time // set system time to time source GPS, if we have valid gps time
#ifdef HAS_GPS #ifdef HAS_GPS
if (gps.time.isValid()) { if (gps.time.isValid()) {
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(), setTime(gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.date.day(), gps.date.month(), gps.date.year()); gps.date.day(), gps.date.month(), gps.date.year());
// set RTC time to time source GPS, if RTC is present
#ifdef HAS_RTC #ifdef HAS_RTC
RtcDateTime now; RtcDateTime t;
now.year = gps.time.year(); t.year = gps.time.year();
now.month = gps.date.month(); t.month = gps.date.month();
now.dayOfMonth = gps.date.day(); t.dayOfMonth = gps.date.day();
now.hour = gps.time.hour(); t.hour = gps.time.hour();
now.minute = gps.time.minute(); t.minute = gps.time.minute();
now.second = gps.time.second(); t.second = gps.time.second();
set_rtctime(now, synced_GPS); set_rtctime(t);
#endif #endif
ESP_LOGI(TAG, "Time synced by GPS to %02d:%02d:%02d", hour(), minute(), time_t t = now();
second()); ESP_LOGI(TAG, "GPS has set system time to %02d/%02d/%d %02d:%02d:%02d",
month(t), day(t), year(t), hour(t), minute(t), second(t));
return; return;
} else { } else {
ESP_LOGI(TAG, "No valid GPS time"); ESP_LOGI(TAG, "No valid GPS time");
} }
#endif // HAS_GPS #endif // HAS_GPS
// sync time by LoRa Network if network supports DevTimeReq // set system time to time source LoRa Network, if network supports DevTimeReq
#ifdef LMIC_ENABLE_DeviceTimeReq #ifdef LMIC_ENABLE_DeviceTimeReq
// Schedule a network time request at the next possible time // Schedule a network time sync request at the next possible time
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
ESP_LOGI(TAG, "Network time request scheduled"); ESP_LOGI(TAG, "Network time request scheduled");
#endif #endif

View File

@ -456,8 +456,10 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
// Update system time with time read from the network // Update system time with time read from the network
setTime(*pUserUTCTime); setTime(*pUserUTCTime);
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(*pUserUTCTime, synced_LORA); set_rtctime(*pUserUTCTime);
#endif #endif
ESP_LOGI(TAG, "Time synced by LoRa network to %02d:%02d:%02d", hour(), time_t t = now();
minute(), second()); ESP_LOGI(TAG,
"LORA Network has set system time to %02d/%02d/%d %02d:%02d:%02d",
month(t), day(t), year(t), hour(t), minute(t), second(t));
} }

View File

@ -7,10 +7,8 @@ static const char TAG[] = "main";
RtcDS3231<TwoWire> Rtc(Wire); RtcDS3231<TwoWire> Rtc(Wire);
clock_state_t RTC_state = useless;
// initialize RTC // initialize RTC
int rtc_init() { int rtc_init(void) {
// return = 0 -> error / return = 1 -> success // return = 0 -> error / return = 1 -> success
@ -27,7 +25,6 @@ int rtc_init() {
ESP_LOGW(TAG, ESP_LOGW(TAG,
"RTC has no valid RTC date/time, setting to compilation date"); "RTC has no valid RTC date/time, setting to compilation date");
Rtc.SetDateTime(compiled); Rtc.SetDateTime(compiled);
RTC_state = useless;
} }
if (!Rtc.GetIsRunning()) { if (!Rtc.GetIsRunning()) {
@ -36,12 +33,10 @@ int rtc_init() {
} }
RtcDateTime now = Rtc.GetDateTime(); RtcDateTime now = Rtc.GetDateTime();
RTC_state = reserve;
if (now < compiled) { if (now < compiled) {
ESP_LOGI(TAG, "RTC date/time is older than compilation date, updating)"); ESP_LOGI(TAG, "RTC date/time is older than compilation date, updating)");
Rtc.SetDateTime(compiled); Rtc.SetDateTime(compiled);
RTC_state = useless;
} }
// configure RTC chip // configure RTC chip
@ -62,77 +57,60 @@ error:
} // rtc_init() } // rtc_init()
int set_rtctime(uint32_t UTCTime, clock_state_t state) { int set_rtctime(uint32_t UTCTime) {
// return = 0 -> error / return = 1 -> success // return = 0 -> error / return = 1 -> success
// block i2c bus access // block i2c bus access
while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) { while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) {
#ifdef TIME_SYNC_INTERVAL_RTC
// shortly stop sync.
setSyncProvider(NULL);
#endif
Rtc.SetDateTime(RtcDateTime(UTCTime)); Rtc.SetDateTime(RtcDateTime(UTCTime));
#ifdef TIME_SYNC_INTERVAL_RTC
// restart sync.
setSyncProvider(get_rtctime);
#endif
xSemaphoreGive(I2Caccess); // release i2c bus access xSemaphoreGive(I2Caccess); // release i2c bus access
RTC_state = state;
return 1; return 1;
} }
return 0; return 0;
} // set_rtctime() } // set_rtctime()
int set_rtctime(RtcDateTime now, clock_state_t state) { int set_rtctime(RtcDateTime t) {
// return = 0 -> error / return = 1 -> success // return = 0 -> error / return = 1 -> success
// block i2c bus access // block i2c bus access
while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) { while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) {
#ifdef TIME_SYNC_INTERVAL_RTC Rtc.SetDateTime(t);
// shortly stop sync.
setSyncProvider(NULL);
#endif
Rtc.SetDateTime(now);
#ifdef TIME_SYNC_INTERVAL_RTC
// restart sync.
setSyncProvider(get_rtctime);
#endif
xSemaphoreGive(I2Caccess); // release i2c bus access xSemaphoreGive(I2Caccess); // release i2c bus access
RTC_state = state;
return 1; return 1;
} }
return 0; return 0;
} // set_rtctime() } // set_rtctime()
time_t get_rtctime() { time_t get_rtctime(void) {
time_t rslt = now(); // never call now() in this function, would cause recursion!
time_t tt = 0;
// block i2c bus access // block i2c bus access
while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) { if (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) {
if (!Rtc.IsDateTimeValid()) if (!Rtc.IsDateTimeValid()) {
ESP_LOGW(TAG, "RTC lost confidence in the DateTime"); ESP_LOGW(TAG, "RTC lost confidence in the DateTime");
else } else {
rslt = (time_t)(Rtc.GetDateTime()).Epoch32Time(); RtcDateTime t = Rtc.GetDateTime();
tt = t.Epoch32Time();
}
xSemaphoreGive(I2Caccess); // release i2c bus access xSemaphoreGive(I2Caccess); // release i2c bus access
return rslt; return tt;
} }
return rslt; return tt;
} // get_rtc() } // get_rtctime()
void sync_rtctime() { void sync_rtctime(void) {
time_t t = get_rtctime();
ESP_LOGI(TAG, "RTC has set system time to %02d/%02d/%d %02d:%02d:%02d",
month(t), day(t), year(t), hour(t), minute(t), second(t));
#ifdef TIME_SYNC_INTERVAL_RTC #ifdef TIME_SYNC_INTERVAL_RTC
setSyncInterval((time_t)TIME_SYNC_INTERVAL_RTC); setSyncProvider(&get_rtctime);
//setSyncProvider(get_rtctime); // <<<-- BUG here, causes watchdog timer1 group reboot setSyncInterval(TIME_SYNC_INTERVAL_RTC);
setSyncProvider(NULL); // dummy supressing time sync, to be removed after bug is solved
if (timeStatus() != timeSet) { if (timeStatus() != timeSet) {
ESP_LOGE(TAG, "Unable to sync with the RTC"); ESP_LOGE(TAG, "Unable to sync with the RTC");
} else { } else {
ESP_LOGI(TAG, "RTC has set the system time"); time_t t = now();
ESP_LOGI(TAG, "RTC has set system time to %02d/%02d/%d %02d:%02d:%02d",
month(t), day(t), year(t), hour(t), minute(t), second(t));
} }
#endif #endif
} // sync_rtctime; } // sync_rtctime;
float get_rtctemp() { float get_rtctemp(void) {
// block i2c bus access // block i2c bus access
while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) { while (xSemaphoreTake(I2Caccess, DISPLAYREFRESH_MS) == pdTRUE) {
RtcTemperature temp = Rtc.GetTemperature(); RtcTemperature temp = Rtc.GetTemperature();
@ -142,4 +120,17 @@ float get_rtctemp() {
return 0; return 0;
} // get_rtc() } // get_rtc()
time_t gpsTimeSync(void) {
#ifdef HAS_GPS
tmElements_t tm;
tm.Second = gps.time.second();
tm.Minute = gps.time.minute();
tm.Hour = gps.time.hour();
tm.Day = gps.date.day();
tm.Month = gps.date.month();
tm.Year = CalendarYrToTm(gps.date.year());
return makeTime(tm);
#endif // HAS_GPS
}
#endif // HAS_RTC #endif // HAS_RTC