GPS msec handling added (experimental)

This commit is contained in:
cyberman54 2019-08-03 14:01:25 +02:00
parent 139738a14d
commit 7fa9269d0b
5 changed files with 40 additions and 45 deletions

View File

@ -21,7 +21,7 @@ int gps_init(void);
void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store); void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store);
void gps_storelocation(gpsStatus_t *gps_store); void gps_storelocation(gpsStatus_t *gps_store);
void gps_loop(void *pvParameters); void gps_loop(void *pvParameters);
time_t fetch_gpsTime(gpsStatus_t value); time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec);
int gps_config(); int gps_config();
#endif #endif

View File

@ -12,7 +12,7 @@ TaskHandle_t GpsTask;
#ifdef GPS_SERIAL #ifdef GPS_SERIAL
HardwareSerial GPS_Serial(1); // use UART #1 HardwareSerial GPS_Serial(1); // use UART #1
static uint16_t nmea_txDelay_ms = static uint16_t nmea_txDelay_ms =
tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS; (tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS);
#else #else
static uint16_t nmea_txDelay_ms = 0; static uint16_t nmea_txDelay_ms = 0;
#endif #endif
@ -82,10 +82,7 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) {
if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) {
// nmea telegram serial delay compensation; not sure if we need this? gps_store->time_age = gps.time.age() + nmea_txDelay_ms;
// if (gps.time.age() > nmea_txDelay_ms)
// gps_store->timedate.Second = gps.time.second() + 1;
// else
gps_store->timedate.Second = gps.time.second(); gps_store->timedate.Second = gps.time.second();
gps_store->timedate.Minute = gps.time.minute(); gps_store->timedate.Minute = gps.time.minute();
gps_store->timedate.Hour = gps.time.hour(); gps_store->timedate.Hour = gps.time.hour();
@ -99,10 +96,11 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) {
} }
// function to fetch current time from struct; note: this is costly // function to fetch current time from struct; note: this is costly
time_t fetch_gpsTime(gpsStatus_t value) { time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec) {
*msec = 1000 - value.time_age;
time_t t = timeIsValid(makeTime(value.timedate)); time_t t = timeIsValid(makeTime(value.timedate));
ESP_LOGD(TAG, "GPS time: %d", t); ESP_LOGD(TAG, "GPS time: %d | time age: %d", t, value.time_age);
return t; return t;
} // fetch_gpsTime() } // fetch_gpsTime()

View File

@ -72,7 +72,7 @@
#define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off #define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off
#define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0]
#define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0] #define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0]
#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] #define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0]
// settings for syncing time with timeserver applications // settings for syncing time with timeserver applications
#define TIME_SYNC_SAMPLES 1 // number of time requests for averaging #define TIME_SYNC_SAMPLES 1 // number of time requests for averaging

View File

@ -1,4 +1,5 @@
#include "timekeeper.h" #include "timekeeper.h"
#include "paxcounter.conf"
#if !(HAS_LORA) #if !(HAS_LORA)
#if (TIME_SYNC_LORASERVER) #if (TIME_SYNC_LORASERVER)
@ -25,29 +26,17 @@ void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
void calibrateTime(void) { void calibrateTime(void) {
time_t t = 0; time_t t = 0;
timesource_t timeSource; uint16_t t_msec = 0;
#if (HAS_GPS) #if (HAS_GPS)
// fetch recent time from last NMEA record // fetch recent time from last NMEA record
t = fetch_gpsTime(gps_status); t = fetch_gpsTime(gps_status, &t_msec);
if (t) { if (t) {
#ifdef HAS_RTC
set_rtctime(t); // calibrate RTC
#endif
timeSource = _gps; timeSource = _gps;
goto finish; goto finish;
} }
#endif #endif
// no time from GPS -> fallback to RTC time while trying lora sync
#ifdef HAS_RTC
t = get_rtctime();
if (t) {
timeSource = _rtc;
goto finish
}
#endif
// kick off asychronous Lora timeserver timesync if we have // kick off asychronous Lora timeserver timesync if we have
#if (HAS_LORA) && (TIME_SYNC_LORASERVER) #if (HAS_LORA) && (TIME_SYNC_LORASERVER)
send_timesync_req(); send_timesync_req();
@ -56,15 +45,18 @@ void calibrateTime(void) {
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
#endif #endif
// no time from GPS -> fallback to RTC time while trying lora sync
#ifdef HAS_RTC
t = get_rtctime();
if (t) {
timeSource = _rtc;
goto finish;
}
#endif
finish: finish:
if (t) { // sync successful setMyTime(t, t_msec, timeSource); // set time
setMyTime(t, 0, timeSource); // set time
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync);
ESP_LOGD(TAG, "time = %d | source: %c", t, timeSetSymbols[timeSource]);
} else { // sync failed, we want to retry shortly
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync);
}
} // calibrateTime() } // calibrateTime()

View File

@ -209,22 +209,25 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) {
// adjust system time, calibrate RTC and RTC_INT pps // adjust system time, calibrate RTC and RTC_INT pps
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
timesource_t timesource) { timesource_t mytimesource) {
time_t time_to_set = (time_t)(t_sec + 1); time_t time_to_set = (time_t)(t_sec);
ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec",
millis() / 1000.0, time_to_set, t_msec);
if (timeIsValid(time_to_set)) { if (timeIsValid(time_to_set)) {
ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0,
time_to_set, t_msec);
// wait until top of second with millisecond precision // wait until top of second with millisecond precision
if (t_msec) if (t_msec) {
vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); vTaskDelay(pdMS_TO_TICKS(1000 - t_msec));
time_to_set++;
}
// set RTC time and calibrate RTC_INT pulse on top of second // if we got a timesource, set RTC time and calibrate RTC_INT pulse on top of
// second
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(time_to_set); if (mytimesource != _rtc)
set_rtctime(time_to_set);
#endif #endif
// sync pps timer to top of second // sync pps timer to top of second
@ -235,13 +238,15 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
setTime(time_to_set); // set the time on top of second setTime(time_to_set); // set the time on top of second
timeSource = timesource; timeSource = mytimesource; // set global variable
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync);
ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted", ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c",
millis() / 1000.0); millis() / 1000.0, timeSetSymbols[timeSource]);
} else } else {
ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated", timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync);
millis() / 1000.0); ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c",
millis() / 1000.0, timeSetSymbols[timeSource]);
}
} }
void timesync_init() { void timesync_init() {