Benchmarks of Real Time Clocks – Raspberry Pi and Arduino
In this posting, we are looking at four Real Time Clocks (RTC) and doing benchmarks and comparisons of all four devices.
A realtime clock is necessary for any project requiring accurate time keeping especially when you don’t always have an Internet connection. For example, a Raspberry Pi being sent up in a balloon or a Pi working in the remote caribbean, like Project Curacao. The Raspberry Pi keeps pretty good time, but only if it is connected to the Internet. If you turn it off at say 10:43 and then turn it on at 12:34 the clock starts at 10:43 and goes forward, unless the Pi is connected to the Internet. The Pi uses an Internet service called NNTP to set the clock on power up if the Internet is available. It then calls the NTP servers (some are actually hosted by the National Institute of Standards and Technology (NIST) and linked to their atomic clocks). You aren’t going to get atomic clock accuracy using NTP, but it’s pretty good. We use the NTP to update the Raspberry Pi so we can use it to estimate the error rates of our RTCs.
The clear winner in our testing was the DS3231.
Introduction to our Four Real Time Clocks
We chose four popular RTCs to do our testing. Our criteria was they had to have:
- I2C interfaces
- Existing Breakout boards
- Able to work at 5V and 3.3V – at least on the I2C bus
The chosen RTC boards were: The DS1307, the PCF8563, the DS3231 and the PCF8563. Each of these boards have different features and options.
Feature Comparison
Below is a scan of the I2C bus for the devices. Note that you don’t see the DS1307 here because it conflicts with 0x68. In addition 0x56 is the EPROM address on the MCP79400 board.
pi@MouseAir2 /var/www $ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- 51 -- -- -- -- 56 -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f 70: -- -- -- -- -- -- -- --
The Test Jig
We hand wired up a prototype board shown in Illustration 2 to mount the 4 RTC boards and connect them to the Raspberry Pi I2C
bus. The underside of the board is shown below and the full board with all of the RTCs mounted is shown poised on interesting reading material. In Illustration 3.
The Accuracy Test Software
To automatically test the RTCs, we constructed a program that first set each clock and then logged every 10 minutes the time differences and the calculated Parts Per Million (PPM) between the RTCs and the NNTP corrected Raspberry Pi clock into a MySQL database. All completely done on the Raspberry Pi. You can download the RTCEval.py software at https://github.com/switchdoclabs/RTCEval. The clock on the Raspberry Pi is not very accurate but the NNTP daemon will correct the time on a regular basis making the PI a pretty good clock as long as you are connected to the Internet.
The Results
Because the DS1307 I2C address conflicts with the DS321 I2C address, we had to run the DS1307 separately.
First we ran a test of the DS1307 for five days (429,179 seconds) comparing the DS1307 time with the Raspberry Pi time using the RTCEval aoftware and then again for 292,000 seconds and used the second test in Illustration 4.
The DS1307 was running 7 seconds fast by the end of the first test and 5 seconds fast by the end of the second test. That means the DS1307 device gains about a second a day. This comes out to about 15 ppm (parts per million). You calculate this by ((error in seconds)/(total seconds)) * 1,000,000. The data sheet says about 23 parts per million so our tests seem reasonable.
The other three RTCs were run for 3.4 million seconds to determine their error rates.
The graph in Illustration 5 shows the total accumulated errors of each of the RTCs. The straight lines with no data are from one time the mains power failed rebooting the Raspberry Pi and the second time when we killed the RTCEval.py process running in the background by updating the Raspberry Pi and rebooting without thinking about the test running. The RTCEval.py software is designed to pick right up and continue testing and logging when it is restarted.
A couple of interesting things can be seen in the Illustration 5 graph. The first thing is the DS3231 is much more accurate than either of the other RTCs by a goodly amount. The second thing is that the lines are all amazingly straight (also called linear). This means under this test condition the errors are accumulating at a constant amount. The “zigging” of the graph is mostly caused by the fact that we only can gauge by full integer seconds (the resolution of all the RTCs is only one second so we round off the Raspberry Pi’s time to integer seconds also in RTCEval.py). Another way of thinking about that is that the RTCs are all pretty good time keepers in amongst themselves. They are drifting consistently away from the Raspberry Pi Time.
Next we look at the total PPM (Parts Per Million error). This is calculated by taking the total error count of seconds and dividing it by the total number of seconds. If our RTCs are stable, then this should converge to a flat line. That’s pretty much true (as you could see in Illustration 5) but you can detect a little drift in the PCF8563 and in the MCP79400. The DS3231 is amazingly flat and accurate.
This final graph, Illustration 7 shows the first 250,000 seconds (left off Illustration 4) and shows the way the RTCEval.py measurement algorithm quickly converges to an excellent approximation of the PPM that changes little in the next 3.2 million seconds.
How Were These Graphs Made?
These graphs were completely produced on the Raspberry Pi using Python, MySQL and a fantastic graphic package called MatPlotLib. We have written a tutorial on how to do this on SwitchDoc at https://www.switchdoc.com/2014/09/graphs-raspberry-pi-raspiconnect/.
[callout size=”col-12″ title=”Making MatPlotLib Graphs on the Raspberry Pi” description=”These graphs were generated using MatPlotLib on the Raspberry Pi. If you want to see another example of how to do this using a MySQL database using time as the X Axis, check out https://www.switchdoc.com/2014/01/matplotlib-raspberry-pi-mysql-and-project-curacao/ for a full example and you can also see how to put these graphs on your control panel using RasPiConnect (www.milocreek.com).” button_size=”normal” button_rounded=”false” button_color=”orange”]
PPM Error Table
After looking at all the data and creating the graphs, we can generate a table of the accuracy results.
Notes: With RTCEval.py, We can only detect at 3 million seconds a minimum of 1/3 of a PPM. Hence, the DS3231 is rated at < 0.3 PPM. It could be better than that. The MCP79400 was 4 PPM, but rock solid. It could be trimmed by the use of the internal trimming register to do better than that.
Comments on each Device
The most accurate device out of the box was clearly the DS3231. It is the only one that is temperature compensated. This is the device that we have chosen to replace the flaky DS1307 in the Project Curacao box. Based on my charts, if you are willing to apply a trim to the device, you could improve the MCP79400 substantially also. Since our line for the PCF8563 was virtually straight in Illustration 5, you could provide a time adjustment say every 24 or 48 hours by software to keep it in line.
All of these devices are definitely usable. Each have different features that may prove to be important, such as interrupts, additional storage, or trim registers.
[callout size=”col-12″ title=”Danger! DS1307″ description=”Don’t hook up the Adafruit DS1307 board to your Raspberry Pi without clipping the pullup resistors. You will burn out your I2C bus if you do. Read the SwitchDoc labs column in Raspberry Pi Geek Magazine Issue 07 to see how to clip the resistors and use the Adafruit DS1307 on your Raspberry Pi.” button_size=”normal” button_rounded=”false” button_color=”orange”]
Conclusion
The RTC test code and MatPlotLib code is up on github.com/switchdoclabs/RTCTest as are all of the python RTC libraries for all of the tested RTCs. For example code for each RTC, go to the SwitchDoc Labs website under:
https://www.switchdoc.com/2014/07/python-driver-ds1307-real-time-clock/
https://www.switchdoc.com/2014/07/raspberry-pi-python-library-mcp79400-real-time-clock/
https://www.switchdoc.com/2014/08/raspberry-pi-python-library-ds3231/
https://www.switchdoc.com/2014/08/raspberry-pi-python-library-pcf8563/
Suggestions for Further Work
A very interesting test would be to dramatically change the temperature during the test (by putting it in the freezer or running a hairdryer over the board) and see how temperature affects the accuracy. Since the DS3231 is temperature compensated, the results would be very insightful.
Question from Readers:
(Q): In on of your last blogs, you talked about how 5V outputs can damage Raspberry Pi GPIO inputs. Why is this?
(A): The Raspberry PI has protection diodes between the pin and 3.3V and ground. Positive voltages greater than 3V3 + one “diode drop” (normally 0.5V) will be shorted to 5V, this means that if you put a 5V power supply on the GPIO pin you will “feed” the 3V3 supply with 4.5 Volt (5V – the diode drop of 0.5V) and that may damage 3V3 logic. We have blown out pins on my Raspberry Pi doing just this. Other people have turned the Pi into a Brick. Only use 3.3V outputs connected to your Raspberry Pi GPIO pins without putting a voltage level converter between the devices. Note: You can DRIVE most 5V device inputs with the Raspberry Pi 3.3V GPIO outputs. Most devices will read 3.3V inputs as a logic one.
If you have a suggestion for a posting or would like to see a specific board or product reviewed, please send us an email at customerservice@switchdoc.com. If you have specific questions to ask, please post on the SwitchDoc Blog (www.switchdoc.com) so everybody can learn from your question.
I think you meant NTP when you said NNTP in the opening.
Absolutely I did. Thank you for that catch. I’ve got that wired in my brain incorrectly.
SDL