Tuesday, December 23, 2014

Installing hardware RTC (DS3231) to Raspberry Pi

Installing hardware RTC (DS3231) to Raspberry Pi


As we know, Raspberry Pi does not have RTC. We can use w: ntpd for date and time synchronizing with NTP servers. But what we can do if we do not want to use NTP? What we can do if we want to use our RPi standalone?
Also, Raspbian OS (which based on Debian) uses "fake hwclock" module:

Some machines don't have a working realtime clock (RTC) unit, or no driver for the hardware that does exist. fake-hwclock is a simple set of scripts to save the kernel's current clock periodically (including at shutdown) and restore it at boot so that the system clock keeps at least close to realtime. This will stop some of the problems that may be caused by a system believing it has travelled in time back to 1970, such as needing to perform filesystem checks at every boot.

But we need to have real hwdclock and abilities for standalone work! :) Let's do it!


Looking for hardware

First, we need find and buy hardware. We can use many solutions (based on DS1307, DS3231, NXP PCF2127AT, NXP PCF2127T, NXP PCF2129AT, NXP PCF2129T) but in this case we will use DS3231.

Then, we need buy this RTC. If we will try to search by "Raspberry Pi RTC module buy" request we will found very expensive solutions - 10-15 USD or more. It's very expensive and we can make bargain deal. What we need to do - look for DIY DS3231 modules. We can use modules for Arduino. They have much lower cost. For example, we can buy DS3231 from aliexpress.com only for 1-2 USD. The main difference - connectors. We must connect all pins from DS3231 to the our Raspberry Pi.

DS3231 DIY module


 Now we need attach DS3231 DIY module to our Raspberry Pi. I'm using Raspberry Pi model B (Rev 1) with 256 Mb RAM on board. So, now we must find pin numbers for GPIO. You can find this information here http://pi4j.com/pins/model-b-rev1.html My pin-out looks like this:

pin-out for RPi model B rev 1 (256 MiB RAM)

For using DS3231 via I2C we must use only 4 wires: Vcc, GND, SDA and SCL. As you see, all of them located near each other: 3.3 VDC Power, SDA0 (I2C), SCL0 (I2C) and 0V (Ground). After wires attached it will look like this:

Be careful when wiring, you can damage your RTC when wiring in wrong way.
After attaching and powering RPi you will see that diode on DS3231 will be ON. Also, you can see that my RPi have passive cooling system :)



I had problems configuring DS3231 via I2C and used few tricks for main target achieving.

Installing I2C library

First, I installed i2c library which used for DS3231 searching and connection checking. All instructions which I used you can find there http://skpang.co.uk/blog/archives/575 

This tutorial says:

Make sure your Raspberry Pi is connected to the internet when installing the drivers. The new Raspbian distro already have the I2C driver installed but they are disabled by default. To enable it all you need to do is comment out a line by putting # in front. At the prompt type.

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Press CTRL X then y to save and exit. Next edit the modules file by:

sudo nano /etc/modules
Add i2c-dev to a new line.


Press CTRL X then y to save and exit.
Now install the i2c-tools package by:

sudo apt-get install i2c-tools
If you get a 404 error do an update first:

sudo apt-get update
then run the install the i2c-tools again.
Note : The installation could take a few minutes to do, depend on how busy the server is.
Now add a new user to the i2c group:

sudo adduser pi i2c
Reboot the machine by:

sudo shutdown -r now
After the reboot test to see any device connected by:

sudo i2cdetect -y 0
If your board is the Rev 2 type this:

sudo i2cdetect -y 1
You should see something like this:
----- TUTORIAL END ----
 After all these operations I scanned I2C bus for devices and got this output

I2C bus

So,  I see that I have RTC on 0x68 address and I2C communications is OK. Now we can continue and set-up our new device.

After I2C setup by previous commands we have i2c module loaded at startup. So, now we must only configure our DS3231. I found this command (many times)

sudo echo ds3231 0x68 | sudo tee /sys/class/i2c-adapter/i2c-1/new_device
But there is no i2c-1 on my Raspberry Pi because I have model B revision 1. So, this command

sudo echo ds3231 0x68 | sudo tee /sys/class/i2c-adapter/i2c-1/new_device

will work only for Model B rev 2 and model B+

As a result, command must be like this (for Model B Rev 1):
echo ds3231 0x68 | sudo tee /sys/class/i2c-adapter/i2c-0/new_device 

After that we can test how linux can communicate with you new RTC:
sudo hwclock

You should see a response with what the chip thinks is the date. Mine said 1970 or some such. No problem. If you have correct date & time in your RPi now you can write your system time to the DS3232.

sudo hwclock -w

If you have problems with system date and time you must fix it before writing it to the DS3231. You can use NTP:

sudo ntpd -gq

or set it manualy 

sudo date -s "Sep 27 2014 12:46:00"
After fixing, you can write your system time to the DS3232: sudo hwclock -w
Now we have initialized RTC on our DS3231 DIY module. The last step - use hardware RTC and disable "fake hwclock" and NTP.

Using nano, we must setup boot scripts:

sudo nano /etc/rc.local

And write to the end of file (for Model B rev 1)

sudo echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
sudo hwclock -s

sudo echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
sudo hwclock -s

for Model B (rev 2) and B+ 

My /etc/rc.local

After all these operations we have almost all configured. Last touch is NTP and "fake hwclock" disabling.

sudo update-rc.d ntp disable
sudo update-rc.d fake-hwclock disable

We can still sync the system time from the internet using:

sudo ntpd -gq 

And then write it to the DS3231 RTC using:

sudo hwclock -w

Hope it was useful for you! Enjoy!

No comments:

Post a Comment