Software apps and online services
A project requiring an accurate time has several options:
1) Using a Real Time Clock (RTC) as there are many available and quite affordable (several Euros). Native RTC accuracy is ranging from several seconds per month (e.g DS3231), up to ~20 seconds per day (DS1307)!
2) Retrieve the accurate time (atomic clock time) from internet time servers or from GPS. In both cases you need a specialized module and access to the time provider, which is not always simple or possible.
We choose the first option in this project and one relatively old RTC: PCF8523 installed in this case on an also relatively old Adafruit Adalogger Featherwing, being some of the first modules I used. Anyway, the principles are the same for all RTCs, and some ideas could be generalized.
In such a project there are two microprocessors working together:
1) the micro-controller (MCU) showing the time on a display and capable to keep time itself with some accuracy (20-40 s/month). There are projects based on time libraries which once set, show the time with relative good accuracy, using only the MCU's quartz frequency as reference.
2) the RTC counting pulses and computing the time (and alarm condition) with high efficiency (a cell battery lasts for about 2 years). The accuracy depends on: a) the particular quartz frequency (ideally 32768.00 Hz), b) possibility to adjust this frequency and c) the possible internal compensation for the thermal drift.
From the above, one idea is how to part the job between the two microprocessors. Some projects (found even on Hackster.io) make the MCU read the time from the RTC every second, which is waste of resources. Better is to read the RTC time once in a while and use a time library to keep time in MCU in-between. There is one such library on GitHub, as far as I know. In the present code, RTC is read once per minute and software corrected.
Second idea and most important is how to improve the RTC accuracy such that no manual adjustment would be required sooner than 1-2 years (when you have to change the cell battery anyway ! ). In this welcomed case, you can set the RTC only once through the Serial Monitor. The next setup would be, when you will change the RTC battery! No setup buttons!
Here we focus on PCF8523 which is provided with an OFFSET register (0x0E). This register can be used to implement several functions, like (see PCF8523.pdf available from NXP Semiconductors):
• Aging adjustment
• Temperature compensation
• Accuracy tuning
In my case PCF8523 has a daily error somewhere between +7 and +8s. Correction is then 20 (according to the same document), which is 20 also in two's complement form, needed to be written in (0x0E) in mode0 (see document). One unit (LSB) of compensation means roughly 0.5 s/day or nearly 15 s/month. This means you could set your RTC, in the worst case scenario, to about 7.5 s/month accuracy, which is better than an average quartz watch. But this also means a maximum possible error of 90 seconds /year, which could prove to be unacceptable. After setting the offset 0x0E = 20 my PCF8523 had a remnant error of +5 s/month (about 1 min/year!!). What can be done about this in the MCU, since the RTC reached its limits!
Well, a monthly correction of 5 seconds would be perfect! The main problem is that I turn off the MCU when I do not need it, or if the Li-Po battery is depleting. The only surviving memory is in the RTC registers: keep there the year, month (and the day if possible) when you last setup the RTC. Do not forget about the still present issue of Daylight Saving Time (DST)! So, when you turn on your MCU, it will read the time from the RTC, make the DST hour correction and the number of seconds correction according to the number of months elapsed since the last setup. That would be perfect. See the image above, proving the accuracy obtained after 3 months: about 1 second error, taking as reference the excellent site time.is . Later updates of the project could be even more accurate!