GPS msec handling added (experimental)
This commit is contained in:
parent
139738a14d
commit
7fa9269d0b
@ -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
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -209,21 +209,24 @@ 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
|
||||||
|
if (mytimesource != _rtc)
|
||||||
set_rtctime(time_to_set);
|
set_rtctime(time_to_set);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user