Författare:
Per Stenebo
Skapad:
2015-05-13 21:03:35
Ändrad:
2022-02-03 20:20:48
en

Real Time Clock

Tutorial: |  Adding a Real Time Clock to Raspberry Pi

 

Något utdaterad guide

Kjell & Co verkar ha slutat sälja denna RTC-modulen. Hittar den på amazon, sök på DS3231.
RTC-modulen håller bara en viss tid utan extern matning (monterad i en Raspi som är igång).
Jag har en där batteriet har dött, verkar vara CR-2032 med lödfanor.

rtcMini RTC-modul

Activate I2C

| learn.adafruit.comforumpost |

sudo apt install python-smbus i2c-tools

sudo raspi-config Advanced options -> I2C

sudo nano /etc/modules

# Added for i2c
i2c-bcm2708
i2c-dev
# Added for RTC
rtc-ds1307

sudo nano /boot/config.txt

The following lines should exist and not be outcommented:

dtparam=i2c_arm=on
...
dtparam=i2c1=on

Activate with: sudo reboot

Test i2c (man page), check adress (68 with RTC mounted, -- if not):

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

 

Configure RTC

| hwclock man page | learn.adafruit.com | thepihut.com |

Run the following commands as root by becoming root:

sudo su

The RTC module must be loaded by the kernel by running:

modprobe rtc-ds1307

Create device, i2c-0 for v1, i2c-1 for v2:

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

i2cdetect -y 1 now return UU where 68 where before.

Check that system time is correct:

date

Force update from NTP-server by restarting daemon if needed:

/etc/init.d/ntp restart

Read current time in RTC:

hwclock -r

If you get "hwclock: Cannot access the Hardware Clock via any known method." then you did not run the command as root or rtc-ds1307 module is not loaded, check loaded modules with lsmod.

Write current time to the RTC:

hwclock --debug -w

hwclock from util-linux 2.25.2
Using the /dev interface to the clock.
Last drift adjustment done at 1452273563 seconds after 1969
Last calibration done at 1452273563 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time from /dev/rtc to change
...got clock tick
Time read from Hardware Clock: 2000/08/18 04:46:50
Hw clock time : 2000/08/18 04:46:50 = 966574010 seconds since 1969
missed it - 1453208050.987545 is too far past 1453208050.500000 (0.487545 > 0.001000)
1453208051.500000 is close enough to 1453208051.500000 (0.000000 < 0.002000)
Set RTC to 1453208051 (1453208050 + 1; refsystime = 1453208050.000000)
Setting Hardware Clock to 12:54:11 = 1453208051 seconds since 1969
ioctl(RTC_SET_TIME) was successful.
Not adjusting drift factor because it has been less than a day since the last calibration.

Disable NTP to auto-start at boot, it might corrupt the RTC memory, we will start it later:

sudo update-rc.d -f ntp remove

sudo systemctl disable ntp.service

This problem seems only to affect Raspbian Jessie, I have not encountered it on the previous release Wheezy.

Add the DS1307 device creation at boot:

nano /etc/rc.local

# Create RTC device:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
# Set system time from RTC:
hwclock -s
# Start ntp daemon:
/etc/init.d/ntp start
systemctl start ntp.service # Does not work here

right before exit 0

Remove the fake-hwclock package (it restores system time to last known), it somehow disables getting time from RTC:

sudo apt --purge remove fake-hwclock

 

Test

Let the pi be powered off and without power supply for a while, then boot again without access to any NTP server and check the system time with:

date

To be sure that the pi doesn't get a fresh time from anything other than our RTC it's safest to connect directly with monitor and keyboard, or via serial console, and boot without any network at all (or GPS).

 

Delete device

0x68 is the I2C address of the DS1307 Real Time Clock chip, /i2c-0/ for v1, /i2c-1/ for v2:

echo 0x68 > /sys/class/i2c-adapter/i2c-1/delete_device

 

Troubleshooting

RTC did not work as expected on Raspbian Jessie, sometimes it worked after a short power outage, sometimes not. It never worked after a longer poweroff (like >30 min). After disabling autostart of the ntp daemon it worked.

To facilitate troubleshooting of this problem I put this text to /etc/rc.local (replacing the commands given above):

echo "Debug info from $0" > /tmp/test_rc.local
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
echo "RTC time: $(hwclock -r)" >> /tmp/test_rc.local
echo "System time before set: $(date)" >> /tmp/test_rc.local
hwclock -s --debug >> /tmp/test_rc.local 2>&1
echo "System time after set: $(date)" >> /tmp/test_rc.local
/etc/init.d/ntp start >> /tmp/test_rc.local 2>&1

hwclock -s --debug gave the following output:

hwclock from util-linux 2.25.2
Using the /dev interface to the clock.
Last drift adjustment done at 1452272974 seconds after 1969
Last calibration done at 1452272974 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time from /dev/r
tc to change
...got clock tick
Time read from Hardware Clock: 2066/01/01 00:00:22
Invalid values in hardware clock: 2066/01/01 00:00:22
Unable to set system clock.

Disable autostart of ntp:

sudo update-rc.d -f ntp remove

Start NTP after system time is set from RTC. Add the following to /etc/rc.local, after hwclock -w and before exit 0:

/etc/init.d/ntp start

 

Other debug hints

Check i2c adress (compare command output to the same command above):

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

"UU": This address is currently in use by a driver. This strongly suggests that there is a chip at this address.

Check loaded kernel modules: lsmod

Module                  Size  Used by
cfg80211              499834  0 
rfkill                 22491  1 cfg80211
bcm2835_gpiomem         3703  0 
uio_pdrv_genirq         3690  0 
uio                    10002  1 uio_pdrv_genirq
rtc_ds1307             10383  0 
i2c_bcm2708             6252  0 
i2c_dev                 6730  0 
ipv6                  360374  20 

Check boot messages: dmesg | grep 'i2c\|ds1307\|rtc'

[    4.267457] i2c /dev entries driver
[    4.295014] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100000)
[   44.228321] rtc-ds1307 1-0068: rtc core: registered ds1307 as rtc0
[   44.228387] rtc-ds1307 1-0068: 56 bytes nvram
[   44.228501] i2c i2c-1: new_device: Instantiated device ds1307 at 0x68

Check device: ls -l /dev | grep rtc

lrwxrwxrwx  1 root root         4 Jan  8 12:37 rtc -> rtc0
crw-------  1 root root  254,   0 Jan  8 12:37 rtc0

 

hwclock

hwclock -r --debug

hwclock from util-linux 2.25.2
Using the /dev interface to the clock.
Last drift adjustment done at 1452272731 seconds after 1969
Last calibration done at 1452272731 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time from /dev/rtc to change
...got clock tick
Time read from Hardware Clock: 2016/01/08 17:08:57
Hw clock time : 2016/01/08 17:08:57 = 1452272937 seconds since 1969
Fri 08 Jan 2016 18:08:57 GMT-1  -0.051350 seconds

hwclock -w --debug

hwclock from util-linux 2.25.2
Using the /dev interface to the clock.
Last drift adjustment done at 1452272731 seconds after 1969
Last calibration done at 1452272731 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time from /dev/rtc to change
...got clock tick
Time read from Hardware Clock: 2016/01/08 17:09:35
Hw clock time : 2016/01/08 17:09:35 = 1452272975 seconds since 1969
missed it - 1452272974.999120 is too far past 1452272974.500000 (0.499120 > 0.001000)
1452272975.500000 is close enough to 1452272975.500000 (0.000000 < 0.002000)
Set RTC to 1452272975 (1452272974 + 1; refsystime = 1452272974.000000)
Setting Hardware Clock to 17:09:35 = 1452272975 seconds since 1969
ioctl(RTC_SET_TIME) was successful.
Not adjusting drift factor because it has been less than a day since the last calibration.

hwclock -s --debug

hwclock from util-linux 2.25.2
Using the /dev interface to the clock.
Last drift adjustment done at 1452272731 seconds after 1969
Last calibration done at 1452272731 seconds after 1969
Hardware clock is on UTC time
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc does not have interrupt functions. Waiting in loop for time from /dev/rtc to change
...got clock tick
Time read from Hardware Clock: 2016/01/08 17:05:56
Hw clock time : 2016/01/08 17:05:56 = 1452272756 seconds since 1969
Calling settimeofday:
        tv.tv_sec = 1452272756, tv.tv_usec = 0
        tz.tz_minuteswest = -60

 

Kommentarer till sidan RTC