User Tools

Site Tools


realtimeclock

Realtime Clock (RTC)

The raspberry Pi is only working with a fake hw clock for counting seconds and is relying on an internet connection to update the time from time to time for not having too many differences between the real time and the local time.

To get a more precise or stable clock, especially when there is not always internet available, install a Realtime Clock (RTC) on the pi. The RTC, as it's described here, is an I²C connected RTC (DS3231/DS1307), powered by a small battery when the Pi is turned off.

Preparation

First of all and pretty often forgotton if not freshly installed, the system has to be updated and to test and work with I²C the corresponding i²c tools nned to be installed, if not yet installed:

sudo apt-get update; sudo apt-get dist-upgrade
sudo apt-get install i2c-tools libi2c-dev 

It has to be ensured that the I²C modul/device tree setup is done and loaded, so that I²C is activated for the Raspberry Pi, this can easily be done by using sudo raspi-config. To verify, ensure having the following entry in in /boot/config.txt:

dtparam=i2c_arm=on

If that's done, reboot the Pi and verify I²C is working and the connected RTC is found at “some” address on the second I²C bus (first is 0 and second is 1) by calling i2cdetect -y 1. The result should look like:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                        

Here I²C is up and running and some device is found at address 0x68, which is in this case the RTC.

Setting up RTC

If I²C is up and running and the RTC is found at address 0x68, the device can easily be “contacted” by just simply reading first data-address (0x00) from it, to ensure it's working:

pi@RTC-Pi:~ $ i2cget -y 1 0x68 0x00
0x42

Every second that address is read, the value changes as the first data-address is representing the seconds from the RTC.

A more precise table of what is written where and can be accessed by the corresponding data-address can be taken from the datasheet:

DS3231 datasheet extract

Remind: This only works, if the device is not already in use by another tool/script/system.

In the next step the RTC has to be added as a new I²C device to the system, which can easily be done by executing this as root (super user level can be reached by first e.g. calling sudo su - ):

echo 'ds1307 0x68' > /sys/class/i2c-adapter/i2c-1/new_device

If the device shall be added as someone else than root, just wrap the command a little and execute with sudo in front:

sudo bash -c "echo 'ds1307 0x68' > /sys/class/i2c-adapter/i2c-1/new_device"

Testing, the last step was successfull, it just needes to be checked, whether there is a new I²C device added, example output could be:

pi@RTC-Pi:~ $ cat /sys/bus/i2c/devices/1-0068/rtc/rtc0/name 
ds1307
pi@RTC-Pi:~ $ cat /sys/bus/i2c/devices/1-0068/rtc/rtc0/date 
2016-03-20
pi@RTC-Pi:~ $ cat /sys/bus/i2c/devices/1-0068/rtc/rtc0/time 
16:41:30

As additional check, the last rows in dmesg proving success, will look like:

[...]
[  939.081661] i2c i2c-1: new_device: Instantiated device ds1307 at 0x68
[  939.095693] rtc-ds1307 1-0068: rtc core: registered ds1307 as rtc0
[  939.095732] rtc-ds1307 1-0068: 56 bytes nvram

If this was successfully done, the RTC is installed and can be used as hw clock.

Test and use RTC

If Pi was powerless, then freshly rebooted and RTC is setup as new I²C device, it usually does not have any useful time set.

Fastest way to set date and time is having the Pi connected to the web, grab current time from web and sync it to the RTC.

With the following commands, the current date/time is first checked and printed…

pi@RTC-Pi:~# date
So 20. Mär 17:38:34 CET 2016

…then the current date/time is read from the RTC…

pi@RTC-Pi:~# sudo hwclock -r
Sa 01 Jan 2000 01:25:50 CET  -0.021127 seconds

…next, setting the current date/time to the RTC and read it again, to ensure it's correct…

pi@RTC-Pi:~# sudo hwclock -w
 
pi@RTC-Pi:~# sudo hwclock -r
So 20 Mär 2016 17:39:08 CET  -0.959692 seconds

…and finally activate the sync, so tell system to sync system time with RTC:

pi@RTC-Pi:~# sudo hwclock -s


If the RTC battery is installed and hwclock was once setup following the former procedure, the following lines can easily be added to the /etc/rc.local (before 'exit 0') to ensure, each time the Pi boots RTC is ready and system relies on it:

echo 'ds1307 0x68' > /sys/class/i2c-adapter/i2c-1/new_device
hwclock -s


Script to execute

To speed all this up, when I²C bus is up and loaded, the following simple script can be downloaded to execute all neccessary steps (including the initial time sync):

init-rtc.sh
#!/bin/bash
echo "Activate and initiate RTC-HW-clock..."
echo "Current system date time is:" $(date)
echo "Adding RTC to list of new I²C devices..."
sudo bash -c "echo 'ds1307 0x68' > /sys/class/i2c-adapter/i2c-1/new_device"
echo "RTC is currently set to:" $(sudo hwclock -r)
echo "Setting current date/time in RTC clock..." $(sudo hwclock -w)
echo "RTC is now set to:" $(sudo hwclock -r)
echo "Tell system to sync system time with RTC..."  $(sudo hwclock -s)
echo "System is running now with HW clock and current date/time is:" $(date)
echo "Done!"
realtimeclock.txt · Last modified: 21.03.2016 10:18 by andreas