View on GitHub

RTC DS3231 on the Raspberry Pi

Hardware clock, temperature, and alarms

Home

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

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:

  1. Connect the RTC
  2. Configure I2C on your Pi
  3. Load the clock at boot
  4. Set date and time
  5. Converting and reading the temperature
  6. Conclusion
  7. 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.

RTC DS3231M front
RTC DS3231M front
Pi GPIO pinouts
Pi GPIO pinouts
RTC and pi connections
RTC and pi connections

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

i2cdetect output
i2cdetect output

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 time
  • date - check the system time
  • sudo hwclock -r - check the date and time of the RTC
  • sudo hwclock -w - write the system time to the RTC
  • sudo 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.

References

Adding RTC to I2C

Get temperature and conversion