Per Stenebo
2015-05-13 21:03:35
2022-02-03 20:20:48
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.
Mini RTC-modul
Activate I2C
| learn.adafruit.com | forumpost |
sudo apt install python-smbus i2c-tools
sudo raspi-config Advanced options -> I2C
sudo nano /etc/modules
# Added for i2ci2c-bcm2708i2c-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 startsystemctl 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
