time accuracy improvement

This commit is contained in:
Verkehrsrot 2019-03-19 01:46:20 +01:00
parent 0f311b5ea9
commit ffaa13283b
6 changed files with 32 additions and 26 deletions

View File

@ -112,7 +112,7 @@ extern uint16_t volatile macs_total, macs_wifi, macs_ble,
extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC
extern timesource_t timeSource; extern timesource_t timeSource;
extern hw_timer_t *displayIRQ, *ppsIRQ; extern hw_timer_t *displayIRQ, *ppsIRQ;
extern SemaphoreHandle_t I2Caccess, TimePulse; extern SemaphoreHandle_t I2Caccess;
extern TaskHandle_t irqHandlerTask, ClockTask; extern TaskHandle_t irqHandlerTask, ClockTask;
extern TimerHandle_t WifiChanTimer; extern TimerHandle_t WifiChanTimer;
extern Timezone myTZ; extern Timezone myTZ;

View File

@ -491,13 +491,13 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
if (timeIsValid(*pUserUTCTime)) { if (timeIsValid(*pUserUTCTime)) {
setTime(*pUserUTCTime); setTime(*pUserUTCTime);
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(*pUserUTCTime); // calibrate RTC if we have one set_rtctime(*pUserUTCTime); // calibrate RTC if we have one
#endif #endif
timeSource = _lora; timeSource = _lora;
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat
ESP_LOGI(TAG, "Received recent time from LoRa"); ESP_LOGI(TAG, "Received recent time from LoRa");
} else } else
ESP_LOGI(TAG, "Invalid time received from LoRa"); ESP_LOGI(TAG, "Invalid time received from LoRa");
} // user_request_network_time_callback } // user_request_network_time_callback
#endif // HAS_LORA #endif // HAS_LORA

View File

@ -84,7 +84,7 @@ uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL; hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL;
TaskHandle_t irqHandlerTask, ClockTask; TaskHandle_t irqHandlerTask, ClockTask;
SemaphoreHandle_t I2Caccess, TimePulse; SemaphoreHandle_t I2Caccess;
bool volatile TimePulseTick = false; bool volatile TimePulseTick = false;
time_t userUTCTime = 0; time_t userUTCTime = 0;
timesource_t timeSource = _unsynced; timesource_t timeSource = _unsynced;
@ -113,8 +113,6 @@ void setup() {
if (I2Caccess) if (I2Caccess)
xSemaphoreGive(I2Caccess); // Flag the i2c bus available for use xSemaphoreGive(I2Caccess); // Flag the i2c bus available for use
TimePulse = xSemaphoreCreateBinary(); // as signal that shows time pulse flip
// disable brownout detection // disable brownout detection
#ifdef DISABLE_BROWNOUT #ifdef DISABLE_BROWNOUT
// register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4 // register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4

View File

@ -49,6 +49,10 @@ uint8_t rtc_init(void) {
uint8_t set_rtctime(time_t t) { // t is UTC in seconds epoch time uint8_t set_rtctime(time_t t) { // t is UTC in seconds epoch time
if (I2C_MUTEX_LOCK()) { if (I2C_MUTEX_LOCK()) {
Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000 Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000
#ifdef RTC_INT // sync rtc 1Hz pulse on top of second
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start
#endif
I2C_MUTEX_UNLOCK(); I2C_MUTEX_UNLOCK();
ESP_LOGI(TAG, "RTC time synced"); ESP_LOGI(TAG, "RTC time synced");
return 1; // success return 1; // success

View File

@ -124,7 +124,6 @@ void IRAM_ATTR CLOCKIRQ(void) {
&xHigherPriorityTaskWoken); &xHigherPriorityTaskWoken);
#if defined GPS_INT || defined RTC_INT #if defined GPS_INT || defined RTC_INT
xSemaphoreGiveFromISR(TimePulse, &xHigherPriorityTaskWoken);
TimePulseTick = !TimePulseTick; // flip ticker TimePulseTick = !TimePulseTick; // flip ticker
#endif #endif

View File

@ -109,10 +109,14 @@ void process_timesync_req(void *taskparameter) {
// wait until next cycle // wait until next cycle
vTaskDelay(pdMS_TO_TICKS(TIME_SYNC_CYCLE * 1000)); vTaskDelay(pdMS_TO_TICKS(TIME_SYNC_CYCLE * 1000));
} else { } else {
// send flush to open a receive window for last time_sync_ans // send flush to open a receive window for last time_sync_answer
payload.reset(); // payload.reset();
payload.addByte(0x99); // payload.addByte(0x99);
SendPayload(RCMDPORT, prio_high); // SendPayload(RCMDPORT, prio_high);
// Send a payload-less message to open a receive window for last
// time_sync_answer
void LMIC_sendAlive();
} }
} }
} // for } // for
@ -145,13 +149,15 @@ void process_timesync_req(void *taskparameter) {
ESP_LOGD(TAG, "[%0.3f] waiting %d ms", millis() / 1000.0, wait_ms); ESP_LOGD(TAG, "[%0.3f] waiting %d ms", millis() / 1000.0, wait_ms);
vTaskDelay(pdMS_TO_TICKS(wait_ms)); vTaskDelay(pdMS_TO_TICKS(wait_ms));
#if !defined(GPS_INT) && !defined(RTC_INT)
// sync timer pps to top of second // sync timer pps to top of second
if (ppsIRQ) { timerRestart(ppsIRQ); // reset pps timer
timerRestart(ppsIRQ); // reset pps timer CLOCKIRQ(); // fire clock pps interrupt
CLOCKIRQ(); // fire clock pps interrupt time_to_set++; // advance time 1 second
} #endif
setTime(time_to_set); // set the time on top of second
setTime(++time_to_set); // +1 sec after waiting for top of seceond
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(time_to_set); // calibrate RTC if we have one set_rtctime(time_to_set); // calibrate RTC if we have one
#endif #endif
@ -162,8 +168,7 @@ void process_timesync_req(void *taskparameter) {
ESP_LOGI(TAG, "[%0.3f] Timesync finished, time adjusted by %.3f sec", ESP_LOGI(TAG, "[%0.3f] Timesync finished, time adjusted by %.3f sec",
millis() / 1000.0, myClock_secTick(time_offset).count()); millis() / 1000.0, myClock_secTick(time_offset).count());
} else } else
ESP_LOGI(TAG, ESP_LOGI(TAG, "[%0.3f] Timesync finished, time is up to date",
"[%0.3f] Timesync finished, time is up to date",
millis() / 1000.0); millis() / 1000.0);
} else } else
ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated", ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated",
@ -212,9 +217,9 @@ int recv_timesync_ans(uint8_t buf[], uint8_t buf_len) {
uint16_t timestamp_msec; // convert 1/250th sec fractions to ms uint16_t timestamp_msec; // convert 1/250th sec fractions to ms
uint32_t timestamp_sec; uint32_t timestamp_sec;
// fetch timeserver time from 4 bytes containing the UTC seconds since unix // fetch timeserver time from 4 bytes containing the UTC seconds since
// epoch. Octet order is big endian. Casts are necessary, because buf is an // unix epoch. Octet order is big endian. Casts are necessary, because buf
// array of single byte values, and they might overflow when shifted // is an array of single byte values, and they might overflow when shifted
timestamp_sec = ((uint32_t)buf[4]) | (((uint32_t)buf[3]) << 8) | timestamp_sec = ((uint32_t)buf[4]) | (((uint32_t)buf[3]) << 8) |
(((uint32_t)buf[2]) << 16) | (((uint32_t)buf[1]) << 24); (((uint32_t)buf[2]) << 16) | (((uint32_t)buf[1]) << 24);