Here is how I made it work.
Almost everything here needs to be done as super-user, so use 'sudo bash' or put sudo in front of everything (if not already shown).
The following basic steps are needed:
- Arrange for the 'i2c' drivers to be present if not already;
- there is an additional driver for rtc_ds1307
- remove fake-hwclock. This is a subsystem which will normally be used when you don't have a network to supply the time; it saves the system time in a file when the system is shut down, and loads it from the same file at startup. So the time isn't right, but at least it doesn't go back to zero ( 1 Jan 1970 ) each time you restart. With the RTC installed, the time will start off reasonably correct even without the network.
- arrange for the system to read the time from the RTC at startup.
Please note that this is for the image 2015-05-05-raspian-wheezy, on a rev 2.0 'Pi 1', and a ds1307 rtc attached to the expansion connecter. Some or much of it should apply to other situations (but probably not to older raspian). It is possible that the problem with the RTC being corrupted is specific to the ds1307 driver, so it could be simpler for other chips. And that problem may get fixed at some future release.
Also, these instructions are written for the model 2 PCB, where the I2C bus #1 is in use. If you have a rev1 PCB (which doesn't have the 8-pin 'P5' connector close to P1) you will be attaching the RTC to I2C bus #0. So, whenever you see /i2c-1/
in the below, use /i2c-0/
instead.
First, run raspi-config, and under 'advanced options', you will find a setting to enable the I2C and loading of I2C drivers. Enable them.
Now, you can in principle, add a line to the bottom of /boot/config.txt
: dtoverlay=i2c-rtc,ds1307
, which will load the ds1307 drive; but - as several have found - the loading of the driver will corrupt the contents of the clock, defeating its purpose. I have no idea why, but I looked at the driver source, and found that on startup, it reads the clock and then, if it finds things it doesn't like (such as a 12-hour format instead of 24), it 'corrects' those settings with writes. So, I suspect what may be happening is that the driver load too soon after the I2C has started, and perhaps the clocks aren't set up properly or something, and the communications is corrupted. In any case, that doesn't work with the configuration I have, and so we will cause the driver to be loaded later.
At this point, you can reboot, and using lsmod | grep i2c
you should see the i2c_bcm2708
driver loaded (as asked for in raspi-config).
Next, run this command:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
or (if not already superuser):
sudo sh -c 'echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device'
(sudo echo
won't work since the >
is what needs to be superuser).
This should cause the rtc_ds1307
driver to load, and will create a device /dev/rtc0
. You should now be able to run hwclock
:
sudo hwclock -r
...This displays the time from the RTC. It may well generate an error because your clock is not initialized properly yet. In any case, we will now set it.
(1) make sure the system clock is set using date
. If you are on a network, it should be set already; if not, get out your phone, or your pocket timepiece, and try something like
sudo date -s '18 nov 2015 22:20:24'
when you have the system time set properly -- being careful to get it right for the time zone -- you can do
sudo hwclock -w
which copies it to the RTC.
And then the hwclock -r
should work, and show the time in the RTC, and you should see it advancing if you read it more than once.
Wed 18 Nov 2015 22:48:41 EST -0.181329 seconds
Wed 18 Nov 2015 22:48:53 EST -0.013721 seconds
Note: the clock value is stored relative to the UTC time zone, but it's displayed in local time.
Next step: remove fake-hwclock. First disable it, and make sure the hwclock.sh is enabled:
sudo update-rc.d hwclock.sh enable
sudo update-rc.d fake-hwclock remove
sudo apt-get remove fake-hwclock
sudo rm /etc/cron.hourly/fake-hwclock
sudo rm /etc/init.d/fake-hwclock
hwclock.sh
won't do anything at startup - it detects the presence of udev and assumes udev has done the startup work - but it does do something useful, which is to cause the system time to be written to the RTC at powerup. So, when you do connect to a network, the Pi time will sync to the network, and your RTC drift will get corrected when you shut down.
One thing left - we need to arrange to read the RTC at power-up, so the system time will be set. udev has a thing in it which tries to do that, but which will fail, or be bypassed, because the RTC driver is not loaded.
The way I've set this up, is to add these four lines at the top of /etc/rc.local
(right at the top, below the comments):
echo 'setting up RTC'
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
sleep 0.5
hwclock -s
This will ensure that the driver is loaded, and the system time set from the hardware clock, each time the system starts. The 'sleep 0.5' is there because I found that the hwclock
command won't work without it - the action triggered by writing to /sys/class/i2c-adapter/i2c-1/new_device
(including making /dev/rtc0 exist) apparently takes a bit of time (probably well under 0.5 sec).
And that's it. I'm not really happy with this use of /etc/rc.local
- I'd rather have it set up much earlier, since a lot of stuff happens before rc.local
is executed and it would be much better to have the clock set before those things run. But it's working for me. I'll update this answer if I find a better way.
References
https://www.raspberrypi.org/forums/viewtopic.php?t=97314
https://www.raspberrypi.org/forums/viewtopic.php?p=842661
https://www.raspberrypi.org/forums/viewtopic.php?t=85683
https://www.raspberrypi.org/blog/upcoming-board-revision/
dtparam=i2c1=on
to config.txt as worked for micksulley in January raspberrypi.org/forums/viewtopic.php?f=28&t=97639 - Reboot. Still no /dev/i2c*, still no i2cdetect.sudo invoke-rc.d hwclock.sh start
does nothing, it exits because/run/udev
exists. Butsudo invoke-rc.d hwclock.sh show
reads the clock, andsudo invoke-rc.d hwclock.sh stop
copies the system clock to hardware clock.