Raspberry Pi Pico: DS3231 RTC (Real-Time Clock) – Get Time and Set Alarms (MicroPython)
Introduction
In this tutorial, we will interface the DS3231 Real-Time Clock (RTC) module with the Raspberry Pi Pico using MicroPython. The DS3231 is a highly accurate RTC module with a built-in temperature-compensated crystal oscillator. We will learn how to get the current time and set alarms using MicroPython.
Components Required
- Raspberry Pi Pico
- DS3231 RTC module
- Jumper wires
- Breadboard (optional)
Understanding the DS3231 RTC Module
The DS3231 is an I2C-based RTC module that keeps track of time even when the power is turned off. It has a battery backup and provides timekeeping functions in seconds, minutes, hours, day, date, month, and year.
DS3231 Pinout:
DS3231 Pin | Raspberry Pi Pico Pin |
---|---|
VCC | 3.3V |
GND | GND |
SDA | GP20 (I2C0 SDA) |
SCL | GP21 (I2C0 SCL) |
Circuit Diagram
Connect the DS3231 module to the Raspberry Pi Pico as per the table above. Ensure that the SDA and SCL lines are properly connected.
Installing MicroPython and Thonny IDE
If you haven’t already installed MicroPython on your Raspberry Pi Pico, follow these steps:
- Download the MicroPython UF2 file from the official Raspberry Pi website.
- Press and hold the BOOTSEL button on the Pico and connect it to your PC.
- Copy the UF2 file to the Pico’s storage.
- Install Thonny IDE and select “MicroPython (Raspberry Pi Pico)” as the interpreter.
MicroPython Code for DS3231 RTC
Initializing the DS3231 and Getting Time
from machine import Pin, I2C
import utime
DS3231_I2C_ADDR = 0x68
def bcd_to_decimal(bcd):
return (bcd // 16) * 10 + (bcd % 16)
def decimal_to_bcd(decimal):
return (decimal // 10) * 16 + (decimal % 10)
i2c = I2C(0, scl=Pin(21), sda=Pin(20), freq=100000)
def get_time():
data = i2c.readfrom_mem(DS3231_I2C_ADDR, 0x00, 7)
seconds = bcd_to_decimal(data[0])
minutes = bcd_to_decimal(data[1])
hours = bcd_to_decimal(data[2])
day = bcd_to_decimal(data[3])
date = bcd_to_decimal(data[4])
month = bcd_to_decimal(data[5])
year = bcd_to_decimal(data[6]) + 2000
return "{:02d}:{:02d}:{:02d} {:02d}/{:02d}/{:04d}".format(hours, minutes, seconds, date, month, year)
while True:
print("Current Time: ", get_time())
utime.sleep(1)
Setting the Time on DS3231
def set_time(year, month, date, day, hours, minutes, seconds):
data = bytearray([decimal_to_bcd(seconds),
decimal_to_bcd(minutes),
decimal_to_bcd(hours),
decimal_to_bcd(day),
decimal_to_bcd(date),
decimal_to_bcd(month),
decimal_to_bcd(year - 2000)])
i2c.writeto_mem(DS3231_I2C_ADDR, 0x00, data)
# Example: Set time to 27 March 2025, Thursday, 12:30:45
set_time(2025, 3, 27, 4, 12, 30, 45)
print("Time Set Successfully!")
Setting an Alarm
The DS3231 provides two alarms (Alarm 1 and Alarm 2). Here’s an example of setting Alarm 1 to trigger at a specific time:
def set_alarm1(hours, minutes, seconds):
data = bytearray([decimal_to_bcd(seconds),
decimal_to_bcd(minutes),
decimal_to_bcd(hours),
0x80]) # Alarm once per day
i2c.writeto_mem(DS3231_I2C_ADDR, 0x07, data)
print("Alarm Set!")
# Set alarm for 6:00:00
set_alarm1(6, 0, 0)
Conclusion
In this tutorial, we learned how to interface the DS3231 RTC module with the Raspberry Pi Pico using MicroPython. We covered reading the current time, setting the time, and configuring alarms. The DS3231 module ensures accurate timekeeping and is useful for projects requiring precise time tracking.