Raspberry Pi: Adding a Real-Time Clock on Raspbian Jessie

Updated version of this for Raspbian Stretch here.

The Raspberry Pi is a great computing device at a great price – but to keep costs down, sacrifices had to be made.  One of those sacrifices was a so-called “real-time clock” or RTC.  Without one, the device forgets the time as soon as it’s powered down or rebooted.  Fortunately, Internet connectivity is available in most cases and NTP can be used to synchronize the clock.  In cases where Internet connectivity will be spotty or nonexistent, it may be a good idea to install a real-time clock.

There are many guides to configuring this in Raspbian Wheezy, but I was not able to find much for Jessie.  Jessie is different from Wheezy in that it runs systemd, which is a completely new way to manage the system and services. I’d also like to note that this was all done on a Raspberry Pi model 2.

The RTC

I purchased a bunch of RTCs from eBay.  Search for Raspberry Pi DS3231 – they can be had for about $2 apiece.  Here’s what it looks like:

Raspberry Pi Realtime Clock

 

Install the RTC Device

You’ll want to install the RTC on the inside row of pins at the “bottom” of the connector, like so:

raspberry-pi-real-time-clock-rtc-ds3231-31-300x210

 

 

Install the Software

You’ll want two packages: i2c-tools and python-smbus. To install:

sudo apt-get install i2c-tools python-smbus

Configure the Device

First, go into the raspi-config utility by typing

sudo raspi-config

You’ll see a screen that looks like this:

Screen Shot 2015-10-29 at 9.03.49 PM

Select Advanced Options, then I2C.  Select Yes to enable it, and Yes to automatically load the kernel module.

Then, to be safe, add these lines to /etc/modules-load.d/rtc-i2c.conf:

# /etc/modules-load.d/rtc-i2c.conf
i2c-dev
i2c_bcm2708

Configure udev to set the system time from the RTC when the device appears:

# /etc/udev/rules.d/rtc-i2c.rules
#
ACTION=="add", SUBSYSTEM=="rtc", ATTRS{hctosys}=="0", RUN+="/sbin/hwclock -s --utc"

Load the kernel modules immediately:

sudo modprobe i2c-bcm2708 
sudo modprobe i2c-dev
sudo modprobe rtc-ds1307

Finally, check to see if the device is available:

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: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

The “68” is the i2c address of the clock module.

Systemd

Next, we’ll need to set up a systemd service called rtc-i2c.service. This will cause systemd to create the RTC device on boot.  And remember, when udev sees the device appear, it will call the hwclock utility to set the system clock from the hardware clock.

First, the config file:

# /etc/conf.d/rtc-i2c
#
CHIP="ds1307"
ADDRESS="0x68"
BUS="1"

Then, the actual systemd service unit:

# /lib/systemd/system/rtc-i2c.service

[Unit]
Description=Initialize i2c hardware RTC device driver
DefaultDependencies=no
Requires=systemd-modules-load.service
After=systemd-modules-load.service
Before=sysvinit.target
ConditionPathExists=/sys/class/i2c-adapter
Conflicts=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/conf.d/rtc-i2c
ExecStart=/bin/sh -c "echo ${CHIP} ${ADDRESS} > /sys/class/i2c-adapter/i2c-${BUS}/new_device"

[Install]
WantedBy=sysinit.target

Finally, enable the service we just created:

sudo systemctl enable rtc-i2c.service

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.

Credits

Many thanks to github user h0tw1r3 for the systemd instructions which came from this gist.

5/5 - (4 votes)

Related posts

2 comments

  • Pcln Rule

    Could you please give a hit as I’m trying to use an Arduino DS1207 RTC module but I’m not able to get it work ;( I’m on Jessie too but with a RPi1, rev.1 (2011). I’ve made the edits to use the Bus0 (not Bus1 as it is with RPi2+) but still – once I modprobe rtc-ds1307 and the i2cdetect throws “UU” instead of 68 and I’m not able to read or write from/to the RTC module 🙁