ESP8266: Extremely bad clock accuracy
Currently most time functions heavily depend on the built-in RTC in ESP8266.
However, the current implementation of RTC is sub-optimal (more on this later).
As a result, the clock accuracy is, basically, horrible.
I found this problem when I am trying to implement a clock using ESP8266 and MicroPython.
The clock drifts 1 second every 30~80 seconds!
I wrote a small test code to illustrate the problem:
import time
import ntptime
def run():
# Initialize time with ntp
ts_ntp = ntptime.time()
ts_time = time.time()
ts_diff = ts_ntp - ts_time
print("Initial time offset = %d"%(ts_diff))
cnt = 0
while True:
# Wait 10 sec
time.sleep_ms(10000)
cnt+= 1
try:
ts_ntp = ntptime.time() - ts_diff
ts_time = time.time()
print("%.3d: Time drift = %d"%(cnt, ts_ntp - ts_time))
except Exception as e:
print("Error query NTP time: %s"%e)
It basically compares the system time with NTP every 10 seconds and output time drift.
Ideally, the time drift should be zero.
On my ESP8266, the output look like:
001: Time drift = 0
...
007: Time drift = 2
...
013: Time drift = 3
...
018: Time drift = 4
...
022: Time drift = 5
...
028: Time drift = 6
...
032: Time drift = 7
033: Time drift = 8
...
038: Time drift = 9
...
060: Time drift = 14
...
The source of inaccuracy is the use of system_rtc_clock_cali_proc().
ESP8266's rtc frequency is subject to environmental factors, such as temperature, voltage, etc, but the current code just obtain a single value of system_rtc_clock_cali_proc(), and store it for use indefinitely.
While a more proper implementation of rtc can probably solve the problem, actually there is a much simpler alternative -- the system clock. ESP8266 provides a system clock, which is independent from the rtc. According to Timekeeping on ESP8266 & arduino uno WITHOUT an RTC, the accuracy of ESP8266's system clock is pretty good (1 sec / day).
I am working on a patch, which enable access to ESP8266's system clock, and see if it helps!
esp8266: RTC support + linker script update
Note that the internal RTC has extreme drift (~1 second over 1 minute), so I am not really sure if the last commit is even worth merging.