timesync timings adjusted

This commit is contained in:
Verkehrsrot 2019-04-07 21:54:19 +02:00
parent 0f32911b2d
commit f337366fb3
3 changed files with 21 additions and 20 deletions

View File

@ -17,7 +17,7 @@ Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
NOTICE: NOTE:
Parts of the source files in this repository are made available under different Parts of the source files in this repository are made available under different
licenses. Refer to LICENSE.txt file in repository for more details. licenses. Refer to LICENSE.txt file in repository for more details.
@ -31,8 +31,8 @@ ledloop 0 3 blinks LEDs
spiloop 0 2 reads/writes data on spi interface spiloop 0 2 reads/writes data on spi interface
IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
timesync_req 1 4 processes realtime time sync requests clockloop 1 4 generates realtime telegrams for external clock
clockloop 1 3 generates realtime telegrams for external clock timesync_req 1 3 processes realtime time sync requests
irqhandler 1 2 display, timesync, etc. tasks triggered by timer irqhandler 1 2 display, timesync, etc. tasks triggered by timer
gpsloop 1 2 reads data from GPS via serial or i2c gpsloop 1 2 reads data from GPS via serial or i2c
bmeloop 1 1 reads data from BME sensor via i2c bmeloop 1 1 reads data from BME sensor via i2c
@ -44,6 +44,9 @@ Low priority numbers denote low priority tasks.
Tasks using i2c bus all must have same priority, because using mutex semaphore Tasks using i2c bus all must have same priority, because using mutex semaphore
(irqhandler, bmeloop) (irqhandler, bmeloop)
NOTE: Changing any timings will have impact on time accuracy of whole code.
So don't do it if you do not own a digital oscilloscope.
// ESP32 hardware timers // ESP32 hardware timers
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS) 0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS)

View File

@ -196,7 +196,7 @@ void clock_init(void) {
"clockloop", // name of task "clockloop", // name of task
2048, // stack size of task 2048, // stack size of task
(void *)&userUTCTime, // start time as task parameter (void *)&userUTCTime, // start time as task parameter
3, // priority of the task 4, // priority of the task
&ClockTask, // task handle &ClockTask, // task handle
1); // CPU core 1); // CPU core
@ -213,7 +213,6 @@ void clock_loop(void *taskparameter) { // ClockTask
static bool led1_state = false; static bool led1_state = false;
uint32_t printtime; uint32_t printtime;
time_t t = *((time_t *)taskparameter), last_printtime = 0; // UTC time seconds time_t t = *((time_t *)taskparameter), last_printtime = 0; // UTC time seconds
TickType_t startTime;
#ifdef HAS_DCF77 #ifdef HAS_DCF77
uint8_t *DCFpulse; // pointer on array with DCF pulse bits uint8_t *DCFpulse; // pointer on array with DCF pulse bits
@ -229,8 +228,6 @@ void clock_loop(void *taskparameter) { // ClockTask
xTaskNotifyWait(0x00, ULONG_MAX, &printtime, xTaskNotifyWait(0x00, ULONG_MAX, &printtime,
portMAX_DELAY); // wait for timepulse portMAX_DELAY); // wait for timepulse
startTime = xTaskGetTickCount();
t = time_t(printtime); // UTC time seconds t = time_t(printtime); // UTC time seconds
// no confident or no recent time -> suppress clock output // no confident or no recent time -> suppress clock output
@ -251,7 +248,7 @@ void clock_loop(void *taskparameter) { // ClockTask
#if defined HAS_IF482 #if defined HAS_IF482
vTaskDelayUntil(&startTime, txDelay); // wait until moment to fire vTaskDelay(txDelay); // wait until moment to fire
IF482.print(IF482_Frame(t + 1)); // note: if482 telegram for *next* second IF482.print(IF482_Frame(t + 1)); // note: if482 telegram for *next* second
#elif defined HAS_DCF77 #elif defined HAS_DCF77

View File

@ -54,7 +54,7 @@ void process_timesync_req(void *taskparameter) {
while (1) { while (1) {
// clear timestamp array before next sync run // reset all timestamps before next sync run
time_offset_ms = myClock_msecTick::zero(); time_offset_ms = myClock_msecTick::zero();
for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++) for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++)
time_sync_tx[i] = time_sync_rx[i] = myClock_timepoint(); time_sync_tx[i] = time_sync_rx[i] = myClock_timepoint();
@ -69,21 +69,22 @@ void process_timesync_req(void *taskparameter) {
payload.addByte(time_sync_seqNo); payload.addByte(time_sync_seqNo);
SendPayload(TIMEPORT, prio_high); SendPayload(TIMEPORT, prio_high);
// process answer, wait for notification from recv_timesync_ans() // wait for notification from recv_timesync_ans()
if ((xTaskNotifyWait(0x00, ULONG_MAX, &seq_no, if ((xTaskNotifyWait(0x00, ULONG_MAX, &seq_no,
pdMS_TO_TICKS(TIME_SYNC_TIMEOUT * 1000)) == pdMS_TO_TICKS(TIME_SYNC_TIMEOUT * 1000)) ==
pdFALSE) || pdFALSE) ||
(seq_no != time_sync_seqNo)) (seq_no != time_sync_seqNo))
goto error; // no valid sequence received before timeout goto error; // no valid sequence received before timeout
else { // calculate time diff from collected timestamps // process answer
else {
k = seq_no % TIME_SYNC_SAMPLES; k = seq_no % TIME_SYNC_SAMPLES;
// cumulate timepoint diffs // calculate time diff from collected timestamps
time_offset_ms += time_point_cast<milliseconds>(time_sync_rx[k]) - time_offset_ms += time_point_cast<milliseconds>(time_sync_rx[k]) -
time_point_cast<milliseconds>(time_sync_tx[k]); time_point_cast<milliseconds>(time_sync_tx[k]);
// wrap around seqNo keeping it in time port range // wrap around seqNo, keeping it in time port range
time_sync_seqNo = (time_sync_seqNo < TIMEANSWERPORT_MAX) time_sync_seqNo = (time_sync_seqNo < TIMEANSWERPORT_MAX)
? time_sync_seqNo + 1 ? time_sync_seqNo + 1
: TIMEANSWERPORT_MIN; : TIMEANSWERPORT_MIN;
@ -100,18 +101,18 @@ void process_timesync_req(void *taskparameter) {
// LMIC_sendAlive(); // LMIC_sendAlive();
} }
} }
} // end for() collect timestamp samples } // end of for loop to collect timestamp samples
// begin of time critical section: lock I2C bus to ensure accurate timing // begin of time critical section: lock app irq's and I2C bus
if (!mask_user_IRQ()) if (!mask_user_IRQ())
goto error; // failure goto error; // failure
// average time offset from collected diffs // average time offset over all collected diffs
time_offset_ms /= TIME_SYNC_SAMPLES; time_offset_ms /= TIME_SYNC_SAMPLES;
// calculate time offset with millisecond precision using LMIC's time base, // calculate time offset with millisecond precision using LMIC's time base,
// since we use LMIC's ostime_t txEnd as tx timestamp. // since we use LMIC's ostime_t txEnd as tx timestamp.
// Finally apply calibration const for processing time. // Also apply calibration const to compensate processing time.
time_offset_ms += time_offset_ms +=
milliseconds(osticks2ms(os_getTime())) + milliseconds(TIME_SYNC_FIXUP); milliseconds(osticks2ms(os_getTime())) + milliseconds(TIME_SYNC_FIXUP);
@ -123,7 +124,7 @@ void process_timesync_req(void *taskparameter) {
setMyTime(time_to_set, time_to_set_fraction_msec); setMyTime(time_to_set, time_to_set_fraction_msec);
// end of time critical section: release I2C bus // end of time critical section: release I2C bus and re-enable app irq's
unmask_user_IRQ(); unmask_user_IRQ();
goto finish; goto finish;
@ -187,7 +188,7 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) {
// construct the timepoint when message was seen on gateway // construct the timepoint when message was seen on gateway
time_sync_rx[k] += seconds(timestamp_sec) + milliseconds(timestamp_msec); time_sync_rx[k] += seconds(timestamp_sec) + milliseconds(timestamp_msec);
// guess timepoint is recent if newer than code compile date // we guess timepoint is recent if it newer than code compile date
if (timeIsValid(myClock::to_time_t(time_sync_rx[k]))) { if (timeIsValid(myClock::to_time_t(time_sync_rx[k]))) {
ESP_LOGD(TAG, "[%0.3f] Timesync request #%d rcvd at %d.%03d", ESP_LOGD(TAG, "[%0.3f] Timesync request #%d rcvd at %d.%03d",
millis() / 1000.0, k, timestamp_sec, timestamp_msec); millis() / 1000.0, k, timestamp_sec, timestamp_msec);
@ -246,7 +247,7 @@ void timesync_init() {
"timesync_req", // name of task "timesync_req", // name of task
2048, // stack size of task 2048, // stack size of task
(void *)1, // task parameter (void *)1, // task parameter
4, // priority of the task 3, // priority of the task
&timeSyncReqTask, // task handle &timeSyncReqTask, // task handle
1); // CPU core 1); // CPU core
} }