March 14, 2017
Modified: May 15, 2017
 

During a storm, we were deprived of electricity for 18 hours. Once the current was restored, there was a three-day delay before the link to our ISP was reestablished. During this period without television, telephone and, above all, without Internet a problem with the Raspberry Pi as a home automation server became apparent. Since this small computer does not have a physical clock and since it was impossible to obtain the correct time from an NTP server on the network, schedules events triggered by the time of the day no longer worked properly in Domoticz. At restart, the Raspberry Pi boot code had set the time to a default value, something like noon, September 1st, 1969, not knowing the current time or date.

The obvious solution was to install a hardware real-time clock (RTC). Such a hardware clock, equipped with a battery, is independent of the system and works even when the computer is turned off. I added a DS3231 module for Raspberry Pi that is easily found from "overseas" suppliers.


Source : unknown, these photos were "borrowed" from forgotten de Web sites.

While very inexpensive, this module has two defects. First, the battery is permanently attached and therefore will not be easily replaced. Second, access to pin 7 (GPIO4) of the Raspberry Pi GPIO header is lost. The module uses the I2C (or I2C) protocol with the SDA and SCL connections on pins 3 and 5 respectively GPIO header. Power supply are pins 1 (3.3V) and 9 (ground). Pin 7 is covered by the module connector without being used by the module.

The picture above shows how to connect the clock module to the Raspberry Pi GPIO header. This could hardly be easier. However, you must activate the I2C interface used by the module, add a library and startup support for the new hardware.

Activating the I2C Interface

The activation of the interface is done with the raspi-config configuration tool. I did this on two different models of the Raspberry Pi.

I) Activation of the I2C interface on a Raspberry Pi Model B + v1.2 in March 2017.

pi@rpi2b:~ $ sudo raspi-config ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Expand Filesystem Ensures that all of the SD card s │ │ 2 Change User Password Change password for the default u │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choose option 5. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ P1 Camera Enable/Disable connection to the │ │ P2 SSH Enable/Disable remote command lin │ │ P3 VNC Enable/Disable graphical remote a │ │ P4 SPI Enable/Disable automatic loading │ │ P5 I2C Enable/Disable automatic loading │ │ P6 Serial Enable/Disable shell and kernel m │ │ P7 1-Wire Enable/Disable one-wire interface │ │ P8 Remote GPIO Enable/Disable remote access to G │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choose option P5. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Expand Filesystem Ensures that all of the SD card s │ │ 2 Change User Password Change password for the default u │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ If this is not already done select the local time zone by choosing option 4. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ I1 Change Locale Set up language and regional sett │ │ I2 Change Timezone Set up timezone to match your loc │ │ I3 Change Keyboard Layout Set the keyboard layout to match │ │ I4 Change Wi-fi Country Set the legal channels used in yo │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choose option I2. In my case, the nearest city is Moncton in Canada. Consequently, I selected America as the geographic area and then scrolled down to the city. ┌─────────────────────────┤ Configuring tzdata ├──────────────────────────┐ │ Please select the geographic area in which you live. Subsequent │ │ configuration questions will narrow this down by presenting a list of │ │ cities, representing the time zones in which they are located. │ │ │ │ Geographic area: │ │ │ │ Africa │ │ America │ │ Antarctica │ │ Australia │ │ System V timezones │ │ US │ │ None of the above │ │ │ │ │ │ <Ok> <Cancel> │ │ │ └─────────────────────────────────────────────────────────────────────────┘ Package configuration ┌───────────────────────┤ Configuring tzdata ├───────────────────────┐ │ Please select the city or region corresponding to your time zone. │ │ │ │ Time zone: │ │ │ │ Jamaica │ │ Juneau ▒ │ │ Kentucky/Louisville ▒ │ │ Kentucky/Monticello ▒ │ │ Metlakatla ▒ │ │ Mexico_City ▒ │ │ Miquelon ▒ │ │ Moncton ▒ │ │ │ │ <Ok> <Cancel> │ │ │ └────────────────────────────────────────────────────────────────────┘ Current default time zone: 'America/Moncton' Local time is now: Fri Mar 24 13:28:34 ADT 2017. Universal Time is now: Fri Mar 24 16:28:34 UTC 2017. pi@rpi2b:~ $ date Fri 24 Mar 13:30:34 ADT 2017

II) Activation of the I2C interface on a Raspberry Pi 3 in May 2017.

The procedure is essentially the same, there is a small difference in the initial configuration screen.

pi@rpi2b:~ $ sudo raspi-config ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Change User Password Change password for the default u │ │ 2 Hostname Set the visible name for this Pi │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 Update Update this tool to the latest ve │ │ 9 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ P1 Camera Enable/Disable connection to the │ │ P2 SSH Enable/Disable remote command lin │ │ P3 VNC Enable/Disable graphical remote a │ │ P4 SPI Enable/Disable automatic loading │ │ P5 I2C Enable/Disable automatic loading │ │ P6 Serial Enable/Disable shell and kernel m │ │ P7 1-Wire Enable/Disable one-wire interface │ │ P8 Remote GPIO Enable/Disable remote access to G │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────┐ │ │ │ Would you like the ARM I2C interface to be enabled? │ │ │ │ <Yes> <No> │ │ │ └──────────────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────────────┐ │ │ │ The ARM I2C interface is enabled │ │ │ │ <Ok> │ │ │ └──────────────────────────────────────────────────────────┘ Select the time zone if this is not already done. Its option 4. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ 1 Change User Password Change password for the default u │ │ 2 Hostname Set the visible name for this Pi │ │ 3 Boot Options Configure options for start-up │ │ 4 Localisation Options Set up language and regional sett │ │ 5 Interfacing Options Configure connections to peripher │ │ 6 Overclock Configure overclocking for your P │ │ 7 Advanced Options Configure advanced settings │ │ 8 Update Update this tool to the latest ve │ │ 9 About raspi-config Information about this configurat │ │ │ │ <Select> <Finish> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Choose option I2. In my case, the nearest city is Moncton in Canada. Consequently, I selected America as the geographic area and then scrolled down to the city. ┌─────────┤ Raspberry Pi Software Configuration Tool (raspi-config) ├──────────┐ │ │ │ I1 Change Locale Set up language and regional sett │ │ I2 Change Timezone Set up timezone to match your loc │ │ I4 Change Wi-fi Country Set the legal channels used in yo │ │ │ │ <Select> <Back> │ │ │ └──────────────────────────────────────────────────────────────────────────────┘ Package configuration ┌─────────────────────────┤ Configuring tzdata ├──────────────────────────┐ │ Please select the geographic area in which you live. Subsequent │ │ configuration questions will narrow this down by presenting a list of │ │ cities, representing the time zones in which they are located. │ │ │ │ Geographic area: │ │ │ │ Africa │ │ America ▮ │ │ Antarctica ▒ │ │ Australia ▒ │ │ Arctic Ocean ▒ │ │ Asia ▒ │ │ Atlantic Ocean ▒ │ │ Europe │ │ │ │ <Ok> <Cancel> │ │ │ └─────────────────────────────────────────────────────────────────────────┘

Installation of the I2C library

Formally speaking, we will install a driver, python-smbus, for the System Management Bus protocol which handles a subset of the I2C protocol. "[The] Python module allows SMBus access through the I2C /dev interface on Linux hosts. The host kernel must have I2C support, I2C device interface support, and a bus adapter driver. (ref)". I am not too sure what that all means, but the following works:

pi@rpi2b:~ $ sudo apt-get update pi@rpi2b:~ $ sudo apt-get install -y python-smbus i2c-tools pi@rpi2b:~ $ sudo reboot
After rebooting we can verify that the I2C interface is activated.

pi@rpi2b:~ $ lsmod | grep i2c_ i2c_bcm2708 5740 0 i2c_dev 6578 0
Do not worry about the values in the last two columns, we are just verifying that the two drivers are active.

Strictly speaking, i2c-tools is not mandatory. But the tools can be used to verify for the presence of I2C devices:

pi@rpi2b:~ $ 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

This confirms that the clock is present and that its address is 0x68 ($ 68). UU may appear instead of 68 in the table. This means that the hardware clock is already working. Of course, the hardware clock must be connected to the GPIO header otherwise it will not be detected.

If you have an original Raspberry Pi (pre October 2012) then the I2C port is 0, not 1, so the previous command should be sudo i2cdetect -y 0.

Support for the New Hardware

It is now necessary to add the appropriate modules to the Linux kernel at startup. This is done by adding their name to a text file named modules in the /etc directory. It may be that file does not exist or that it is empty so far:

pi@rpi2b:~ $ sudo nano /etc/modules
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. i2c-dev rtc-ds1307

This is not an error, the rtc-ds1307 kernel module works with the DS3231 clock as well as with the older DS1307 chip. It remains to add two lines to the rc.local file that will be executed at startup. The first adds the ds1307 module to the I2C device list, the second updates the system date and time from the real-time clock.

pi@rpi2b:~ $ sudo nano /etc/rc.local
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address #_IP=$(hostname -I) || true #if [ "$_IP" ]; then # printf "My IP address is %s\n" "$_IP" #fi echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device hwclock -s exit 0

If at startup there is an error about echo in rc.local, something about a permissions issue for example, then try

pi@rpi2b:~ $ sudo apt-get update pi@rpi2b:~ $ sudo apt-get dist-upgrade

This step was necessary when I installed the clock on the Raspberry Pi 3. This is probably because I simply copied the SD card from the Raspberry Pi model B + then made an apt-get update and apt-get upgrade rather installing the operating system directly.

hwclock

The hwclock utility is used on the last line of rc.local to synchronize the system date from the hardware clock. With this utility you can

Display the current time and date of the hardware clock
sudo hwclock [-r | --show]
The local time and date, in relation to the local time zone, are shown.

Set the time and date of the hardware clock
sudo hwclock --set --date "29 Oct 1997 13:00"
Format : dd mmm yyyy hh:mm
dd is the day of the month - 2 numbers
mmm is the month - 3 lettres
yyyy is the year - 4 numbers
hh is the hour - 2 numbers
mm is the minute - 2 numbers. Seconds must not be specified.
This does not change the time and date of the system. The values ​​of these system parameters can be displayed with the date command.

Copy the time and date of the hardware clock to the system
sudo hwclock (-s | --hctosys)

Copy the system time and date to the hardware clock
sudo hwclock (-w | --systohc)

One must be root to access the hardware clock as the following example demonstrates.

pi@rpi2b:~ $ hwclock hwclock: Cannot access the Hardware Clock via any known method. hwclock: Use the --debug option to see the details of our search for an access method. pi@rpi2b:~ $ sudo hwclock Mon 15 May 2017 19:38:06 ADT -0.656742 seconds

hwclock has other features; see the man page for more information.

NTP and the Hardware Clock

The system time and date can be updated from the network with the ntpd service. When these system parameters are up to date, hwclock can be used to update the hardware clock as explained above.

pi@rpi2b:~ $ sudo ntpd -gq pi@rpi2b:~ $ sudo hwclock -w

It might be a good thing to add these two commands to crontab for regular execution if the hardware clock tended to deviate too much from the right time.

I guess something like this should work:

pi@rpi2b:~ $ crontab -e ... select the editor you want to use, the default is nano which has been used throught this guide.
# For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command 45 * * * * sudo ntpd -gq; sudo hwclock -w

Systematically, the hardware clock will be set to the time and date obtained from the network, fifteen minutes before the hour.

References