Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea : Improve accuracy aiming sub millisecond #144

Open
jcdevaux opened this issue Feb 17, 2022 · 9 comments
Open

Idea : Improve accuracy aiming sub millisecond #144

jcdevaux opened this issue Feb 17, 2022 · 9 comments

Comments

@jcdevaux
Copy link

jcdevaux commented Feb 17, 2022

Hi Rop !
First, I'd like to thank you for that nice library.

Millis() and micros()

As far as I can see in sources, you use millis() to compute a timestamp offset from last NTP sync to produce an NTP corrected accurate date aiming ms accuracy (ezTime.cpp:103, 384, ...).

First, why not using micros() instead of millis() as even on smallest Arduino boards @16 MHz (@8 MHz) we got 4 µs (8µs) resolution ?

Local crystal drift compensation

Second, when you use your millis() values, you logically divide by 1000 (which we can call CONSTANT_MS_TO_S).

Couldn't we compensate crystal drift altering that CONSTANT_MS_TO_S value using two (or more) distant NTP sync ?
Something like (in µs) : (micros_sync2-micros_sync1)/((ntp2-ntp1)*1000000) or even with millis(). Kind of temperature compensated crystal but using NTP.

Do you think this will allow to acheive sub millisecond accuracy time sync in local networks ?

Looking forward to hearing from you !

@alwynallan
Copy link

I have modified ezTime with microsecond resolution, and linear interpolation of a set (32) of recent NTP sync events. It also gradually increases the sync interval until it's only checking every 8 hours. The result is accuracy better than 1ms and compensation for crystal drift. It's only tested on ESP32. If there's interest I could clean it up and document it and submit it for merging here. This is an example of the performance (I have a Stratum 0 NTP server on my LAN, but its good on pool.ntp.org too).

image

@ropg
Copy link
Owner

ropg commented Mar 16, 2022

Yay, nice!

Yes please.

@jcdevaux
Copy link
Author

Hi there ! That's nice !

Your linear regression of NTP offset describes a constant drift of you ESP32. That's why you can increase delay between NTP sync. This is not true when you have some temperature variations for example if your crystal is not temperature compensated.

@ropg
Copy link
Owner

ropg commented Mar 16, 2022

Naturally: keeping a constant eye on it is much better...

@jcdevaux
Copy link
Author

How did you mesure your overall accuracy @alwynallan ?

@alwynallan
Copy link

Thanks for encouragement. I'll have it cleaned up and submitted in a week.

Regarding accuracy, I've been using this approach in an ESP8266 application for years. There are statistical techniques to put confidence bands on the locus of the regression line, and reasonable to assume that the accuracy is the half-width of the band at the current time. In my current application the accuracy is limited by millisecond resolution of the time, but usually settles around 2ms as seen below. With microsecond resolution I'm sure it'll be better that 1ms. Below is a typical chart from my ESP8266 application.

image

Regarding quartz crystals they are very strange when studied closely over a long period of time. Identical parts can have positive and negative temperature coefficients, and they can have different natural modes that they stay in for weeks, and then suddenly change, with slightly different frequencies. The also change frequency slightly as they age. The consumer-grade parts are usually "binned" so they'll be within spec (say +-20ppm) but seldom in the middle of the range. I have some that slowly change frequency in a repeating sinusoidal pattern, but the period is 2.5 days, while the temperature variation has a 1-day period. Regression does a good job smoothing all this out and improving on both the crystals and NTP.

@jcdevaux
Copy link
Author

An idea about the source of the 2.5 days period ? I agree that temperature is around 1-day period if it's due to ambiant temperature. Is your MCU core load constant ?
What about supply voltage fluctuation ?

For our readers, here 2 interesting links about crystal drift for Arduino and ESP32 :

@alwynallan
Copy link

alwynallan commented Mar 24, 2022 via email

@jcdevaux
Copy link
Author

jcdevaux commented Mar 24, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants