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 gps_storelocation(gpsStatus_t *gps_store);
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();
#endif

View File

@ -12,7 +12,7 @@ TaskHandle_t GpsTask;
#ifdef GPS_SERIAL
HardwareSerial GPS_Serial(1); // use UART #1
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
static uint16_t nmea_txDelay_ms = 0;
#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)) {
// nmea telegram serial delay compensation; not sure if we need this?
// if (gps.time.age() > nmea_txDelay_ms)
// gps_store->timedate.Second = gps.time.second() + 1;
// else
gps_store->time_age = gps.time.age() + nmea_txDelay_ms;
gps_store->timedate.Second = gps.time.second();
gps_store->timedate.Minute = gps.time.minute();
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
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));
ESP_LOGD(TAG, "GPS time: %d", t);
ESP_LOGD(TAG, "GPS time: %d | time age: %d", t, value.time_age);
return t;
} // 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_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_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
#define TIME_SYNC_SAMPLES 1 // number of time requests for averaging

View File

@ -1,4 +1,5 @@
#include "timekeeper.h"
#include "paxcounter.conf"
#if !(HAS_LORA)
#if (TIME_SYNC_LORASERVER)
@ -25,29 +26,17 @@ void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
void calibrateTime(void) {
time_t t = 0;
timesource_t timeSource;
uint16_t t_msec = 0;
#if (HAS_GPS)
// fetch recent time from last NMEA record
t = fetch_gpsTime(gps_status);
t = fetch_gpsTime(gps_status, &t_msec);
if (t) {
#ifdef HAS_RTC
set_rtctime(t); // calibrate RTC
#endif
timeSource = _gps;
goto finish;
}
#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
#if (HAS_LORA) && (TIME_SYNC_LORASERVER)
send_timesync_req();
@ -56,15 +45,18 @@ void calibrateTime(void) {
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
#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:
if (t) { // sync successful
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);
}
setMyTime(t, t_msec, timeSource); // set time
} // 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
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);
ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec",
millis() / 1000.0, time_to_set, t_msec);
time_t time_to_set = (time_t)(t_sec);
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
if (t_msec)
if (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
set_rtctime(time_to_set);
if (mytimesource != _rtc)
set_rtctime(time_to_set);
#endif
// 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
timeSource = timesource;
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat
ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted",
millis() / 1000.0);
} else
ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated",
millis() / 1000.0);
timeSource = mytimesource; // set global variable
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync);
ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c",
millis() / 1000.0, timeSetSymbols[timeSource]);
} else {
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync);
ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c",
millis() / 1000.0, timeSetSymbols[timeSource]);
}
}
void timesync_init() {