Last modified: November 12, 2019. First version March 14, 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 I
2C 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
bus 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
Starting with
Stretch,
ntp
is no longer installed in
Raspbian. It has been
replaced with a simple SNTP client
systemd-timesyncd
which
updates the system time on a regular basis. At the same time, it
updates the hardware clock. Consequently, what follows is not
necessary; the hardware clock is in sync with the NTP server while
the system is under power. To be honest, it might not have been necessary in
the first place!
November 12, 2019
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