So this sort of got me thinking and I came up with something which is probably wrong in a hundred ways, but it’s an interesting experiment. See https://gist.github.com/hfiennes/07d5f8f53ed4e11d44b02071e9963c48
Essentially, this tries to provide a “more accurate” time on the device by first determining RTT latency (sending timestamps to the device which returns them). It collects 10 samples and checks the standard deviation - if this looks arbitrarily ok, it’ll use RTT/2 to offset the current server time, and sends it to the device. If it looks out of whack then it tried another 10 samples and so on.
The device, upon reception of one of these “corrected time” packets, notes the current hardware.millis() value, and then when get_time() is called, it’ll use the elapsed millisecond count to offset the last received time packet, and returns unix time and microseconds to the application.
For example purposes, the device prints out pre-sync time and post-sync time every time a “corrected time” packet is received, so you can see how much correction is being applied each cycle (the first output is bogus to keep the code clean).
Note that as wifi is hugely variable, this jumps around a lot… an example from an imp004m on my desk:
|2019-01-24T17:57:33 -08:00|[Device]|pre 1548381453.602633 -> post 1548381453.605479, diff 2846us|
|2019-01-24T17:57:44 -08:00|[Device]|pre 1548381464.009479 -> post 1548381464.009072, diff -407us|
|2019-01-24T17:57:50 -08:00|[Device]|pre 1548381470.069072 -> post 1548381470.069140, diff 68us|
|2019-01-24T17:57:59 -08:00|[Device]|pre 1548381479.676140 -> post 1548381479.670571, diff -5569us|
|2019-01-24T17:58:09 -08:00|[Device]|pre 1548381489.665571 -> post 1548381489.671222, diff 5651us|
|2019-01-24T17:58:20 -08:00|[Device]|pre 1548381500.726222 -> post 1548381500.722919, diff -3303us|
|2019-01-24T17:58:33 -08:00|[Device]|pre 1548381513.003919 -> post 1548381513.008424, diff 4505us|
|2019-01-24T17:58:40 -08:00|[Device]|pre 1548381520.041424 -> post 1548381520.041819, diff 395us|
|2019-01-24T17:58:50 -08:00|[Device]|pre 1548381530.123819 -> post 1548381530.120787, diff -3032us|
|2019-01-24T17:59:00 -08:00|[Device]|pre 1548381540.015787 -> post 1548381540.017660, diff 1873us|
|2019-01-24T17:59:10 -08:00|[Device]|pre 1548381550.057660 -> post 1548381550.059011, diff 1351us|
|2019-01-24T17:59:20 -08:00|[Device]|pre 1548381560.080011 -> post 1548381560.079810, diff -201us|
And here’s one from an ethernet-connected imp005:
|2019-01-24T18:06:55 -08:00|[Device]|pre 1548382015.776917 -> post 1548382015.776352, diff -565us|
|2019-01-24T18:07:05 -08:00|[Device]|pre 1548382025.772352 -> post 1548382025.770901, diff -1451us|
|2019-01-24T18:07:15 -08:00|[Device]|pre 1548382035.772901 -> post 1548382035.771540, diff -1361us|
|2019-01-24T18:07:25 -08:00|[Device]|pre 1548382045.776540 -> post 1548382045.775398, diff -1142us|
|2019-01-24T18:07:35 -08:00|[Device]|pre 1548382055.768398 -> post 1548382055.767375, diff -1023us|
|2019-01-24T18:07:45 -08:00|[Device]|pre 1548382065.770375 -> post 1548382065.769359, diff -1016us|
|2019-01-24T18:07:55 -08:00|[Device]|pre 1548382075.772359 -> post 1548382075.771143, diff -1216us|
|2019-01-24T18:08:05 -08:00|[Device]|pre 1548382085.779143 -> post 1548382085.778079, diff -1064us|
|2019-01-24T18:08:15 -08:00|[Device]|pre 1548382095.766079 -> post 1548382095.765539, diff -540us|
|2019-01-24T18:08:25 -08:00|[Device]|pre 1548382105.774539 -> post 1548382105.773151, diff -1388us|
|2019-01-24T18:08:35 -08:00|[Device]|pre 1548382115.766151 -> post 1548382115.764830, diff -1321us|
|2019-01-24T18:08:45 -08:00|[Device]|pre 1548382125.771830 -> post 1548382125.771531, diff -299us|
The offsets here are all lower, but also all in one direction which implies to me that the 005 hardware.millis() is running fast… curious (and something we’ll investigate).
Real NTP does a lot of stats on the time corrections to remove outliers and slowly slews the clock to what hopefully is the right time. None of that is happening here - if the RTTs look stable but the correction packet takes forever to arrive, the device just believes it and the time will be wrong. With more time and ability to understand stats then someone could do a better job of removing outliers on the device side and slewing too.
Still, something fun to play with.