In a previous article, I described how to install a DS3231 real-time clock (RTC) in Raspbian Jessie – the following is an updated set of instructions for Stretch.
Purhcase a Raspberry Pi 4B here
First, a brief summary: The Raspberry Pi does not have the necessary hardware to keep track of the current date and time when it’s powered off. When it powers on, the system date is reset to January 1, 1970. Raspbian has a “fake” clock service that, well, fakes it. This is not very accurate, and as such, the system relies on internet connectivity to synchronize its clock correctly. Once the network comes up and ntpd can synchronize the clock, it stays accurate from then on.
If you have an application that relies on accurate time, or you are using a Pi in an environment without internet access, you can purchase an RTC for your raspberry Pi. Adafruit has one here, or you can purchase Chinese knockoffs from eBay for about $2. The part number is DS3231. Mine look like this:
Installed on the Pi (top left, on the GPIO pins):
Install the Software
You’ll need two packages: i2c-tools and python-smbus. We install the adjtimex command to check something later on. To install:
sudo apt-get install i2c-tools python-smbus adjtimex
Configure the Device
Append the following to /boot/config.txt – this tells the system to load the real-time clock driver for a DS3231.
dtoverlay=i2c-rtc,ds3231
Then, go into the raspi-config utility by typing
sudo raspi-config
You’ll see a screen that looks like this:
Select Advanced Options, then I2C. Select Yes to enable it, and Yes to automatically load the kernel module.
Configure udev to set the system time from the RTC when the device appears:
KERNEL=="rtc0", RUN+="/sbin/hwclock --rtc=$root/$name --hctosys"
Reboot the system.
Finally, check to see if the device is available by running i2cdetect -y 1
You should see something like this:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
The “UU” is located at the i2c address of the clock module.
Cleanup
Raspbian by default includes a fake hardware clock, which we don’t need anymore because we have a real one. Remove the package and service:
sudo apt-get remove fake-hwclock update-rc.d -f fake-hwclock remove
Notes
If you run ntpd to sync the time to the internet, it will automatically update the hardware clock every 15 minutes.
The timedatectl command will show the status of the RTC if installed (note lines 3 and 7):
Local time: Wed 2019-12-04 17:24:33 EST Universal time: Wed 2019-12-04 22:24:33 UTC RTC time: Wed 2019-12-04 22:24:38 Time zone: America/New_York (EST, -0500) Network time on: yes NTP synchronized: yes RTC in local TZ: no
Run the adjtimex –print command and look at the status:
mode: 0 offset: 1069404 frequency: -172652 maxerror: 107693 esterror: 1476 status: 8193 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1575498898s 376123298us = 1575498898.376123298
Note that the status (line 6) is 8193 which means ntpd will update the hardware clock every 11 minutes (according to this comment).
Credits
Many thanks to various users on the Raspberry Pi forums and Stack Exchange.
Also thanks to dfries on the raspberry pi forums with this post.