Description
The DS3231M is a low-cost, extremely accurate I2C real-time clock (RTC) with temperature compensation. It incorporates a battery input and maintains accurate timekeeping when main power to the device is interrupted.
The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred through an I2C bus.
Next up?
After reading this guide, you may be interested in reading:
Parts List
- Raspberry Pi 2
- MicroSD card
- DS3231M RTC Module
Overview
This guide assumes you have an installed and functioning Raspberry Pi. If not please see the RPi Initial Setup Guide. Here, we cover:
- Using the DS3231M module as the RTC for a raspberry pi.
- This allows correct timekeeping, even without an Internet connection, through power down cycles.
- Extracting valid ambient temperature readings from the RTC.
- Internally, the temperature is stored in 2s-complement format in the address registers. The temperature is also only updated every 64 seconds or by setting a bit flag.
- Alarms and calendars will not be covered in this guide.
- The DS3231 is very capable of calendar and interrupt alarms. These types of alarms are useful for many devices, such as microcontrollers, but not as useful for a microcomputer like the pi.
Using the clock will be demonstrated using python and shell programming. This will include:
- Setting up I2C on the pi and addressing the RTC
- Upon boot, initializing and using the RTC for timekeeping
- Reading and setting the time
- Converting and reading the temperature using register addressing and bit logic
The steps to follow are:
- Connect the RTC
- Configure I2C on your Pi
- Load the clock at boot
- Set date and time
- Converting and reading the temperature
- Conclusion
- References
Connect the RTC
WARNING: The pi must be powered down whenever you are connecting or disconnecting pins.
The RTC DS3231M has the following pinouts which should be connected as shown:
- 32K - 32kHz Output, don't use unless you have a special need.
- SQW - Active-Low Interrupt or Square-Wave, not used for this guide. These are more useful for microcontrollers.
- SCL - Serial Clock Input, connect to SCL
- SDA - Serial Data Input/Output, connect to SDA
- VCC - Supply voltage, connect to 3.3V.
- GND - Ground, connect to ground
Refer to the following images of the RTC and the pi's GPIO pinouts.
Configure I2C on your Pi
Unless you have done so previously, I2C must be enabled on your pi.
Install the utilities
sudo apt-get update
sudo apt-get install python-smbus
sudo apt-get install i2c-tools
Enable kernel support
sudo raspi-config
.- Choose Advanced Options then I2C and select yes to enable the interface.
Edit the module file
sudo nano /etc/modules
- Add the following to the to the end of this file
i2c-bcm2708
i2c-dev
rtc-ds1307
Test the bus
Check your I2C bus with, sudo i2cdetect -y 1
. The output should be similar to
Load the clock at boot
sudo nano /etc/rc.local
- Add the following lines before exit 0
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
hwclock -s
- Reboot
Set date and time
When connected to the Internet, the pi automatically gets the date and time from time servers. These are quite accurate. With the command hwclock -s
in rc.local, we have set the pi to override this time to match the RTC. This is fine once we have the correct time on the RTC. So let's set it to the correct time.
sudo nptd -g -q
- set the pi's system time to Internet timedate
- check the system timesudo hwclock -r
- check the date and time of the RTCsudo hwclock -w
- write the system time to the RTCsudo hwclock -s
- set the system time from the RTC
Converting and reading the temperature
The DS3231M has an operating temperature range of -45 C to 85 C. The RTC stores its temperature data in two registers. The upper 8 bits, representing an integer, are stored in two's complement form in register 11h. The lower 2 bits, representing the fractional portion, are in register 12h.
The RTC automatically converts the temperature (updates the registers) every 64s. The maximum allowed by the chip is once every second. A convert may be forced by setting the CONV bit of the Control register (0Eh) to 1. Once the convert is completed, the CONV is set to 0 and the temperature may be read.
The following python code is used to convert, read, and display the temperature.
## python
import smbus
import os
# Release RTC 3231
os.system('sudo rmmod rtc_ds1307')
# Setup RTC 3231 for temperature reading
bus = smbus.SMBus(1)
address = 0x68
CONV = 32
# Force a conversion and wait until it completes
def convTemp(address):
byte_control = bus.read_byte_data(address,0x0E)
if byte_control&CONV == 0:
bus.write_byte_data(address, 0x0E, byte_control|CONV)
byte_control = bus.read_byte_data(address,0x0E)
while byte_control&CONV != 0:
time.sleep(1)
byte_control = bus.read_byte_data(address,0x0E)
return True
# Get temperature in degrees C
def getTemp(address):
convTemp(address)
byte_tmsb = bus.read_byte_data(address,0x11)
byte_tlsb = bus.read_byte_data(address,0x12)
tinteger = (byte_tmsb & 0x7f) + ((byte_tmsb & 0x80) >> 7) * -2**8
tdecimal = (byte_tmsb >> 7) * 2**(-1) + ((byte_tmsb & 0x40) >> 6) * 2**(-2)
return tinteger + tdecimal
Celsius = getTemp(address)
Fahrenheit = 9.0/5.0 * Celsius + 32
print Fahrenheit, "*F /", Celsius, "*C"
Conclusion
Your pi now as a battery backed, accurate RTC installed and working. This allows quality data-logging and other applications. Additionally, the temperature data from the RTC is available for your use. In Basic GPIO on the Raspberry Pi, temperature data is used to light LEDs and send alerts.