Overview
The DS3231 is an extremely accurate I2C real-time clock with an integrated temperature-compensated crystal oscillator (TCXO). Where a typical RTC drifts seconds per day, the DS3231 holds time to within ±2 ppm (under 1 minute per year). The onboard CR2032 backup battery keeps the clock running even when system power is off — pop the module on, set the time once, and it just remembers.
This module also includes an AT24C32 32 Kbit (4 KB) EEPROM for general-purpose non-volatile storage, accessible on the same I2C bus. Each chip uses a different address, so they don't conflict. You'll find this module everywhere in data logging, alarm systems, scheduled automation, and clock projects where accuracy matters.
At a Glance
Specifications
| Parameter | Value |
| RTC IC | DS3231SN (Maxim/ADI) |
| EEPROM IC | AT24C32 (4 KB / 32 Kbit) |
| Operating Voltage | 3.3V - 5.5V |
| Battery Backup | CR2032 lithium coin cell, 3V |
| Time Accuracy | ±2 ppm (0°C - 40°C), ±3.5 ppm (-40°C - +85°C) |
| Onboard Temperature Sensor | ±3°C accuracy, 0.25°C resolution |
| Communication | I2C (100 kHz / 400 kHz) |
| I2C Addresses | 0x68 (RTC), 0x57 (EEPROM) |
| Alarms | 2 programmable, with INT/SQW interrupt |
| Square Wave Output | 1, 1024, 4096, or 8192 Hz on SQW pin |
| 32 kHz Output | 32.768 kHz on 32K pin |
| Pins | 32K, SQW, SCL, SDA, VCC, GND (also pass-through on right) |
Pinout Diagram
Wiring Guide
Arduino Wiring
Standard 4-wire I2C connection. The module already includes pull-up resistors on SDA/SCL, so no externals are needed for short bus runs. The 32K and SQW pins are optional outputs.
| DS3231 Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
| SQW | D2 (optional, for alarm interrupt) |
ESP32 Wiring
The DS3231 works on 3.3V, so power and signals match the ESP32 perfectly with no level shifting.
| DS3231 Pin | ESP32 Pin |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO 21 |
| SCL | GPIO 22 |
Raspberry Pi Wiring
Wire to the Pi's primary I2C bus. Enable I2C in raspi-config first. The Pi can also use this module as a hardware RTC at the kernel level — a popular setup for headless data loggers without internet.
| DS3231 Pin | Raspberry Pi Pin |
|---|---|
| VCC | Pin 1 (3.3V) |
| GND | Pin 6 (GND) |
| SDA | Pin 3 (GPIO 2) |
| SCL | Pin 5 (GPIO 3) |
dtoverlay=i2c-rtc,ds3231 to /boot/config.txt, then disable the fake-hwclock service.
Raspberry Pi Pico Wiring
Use I2C0 on GP4/GP5 with internal pull-ups (the module's own pull-ups are sufficient).
| DS3231 Pin | Pico Pin |
|---|---|
| VCC | 3V3 (OUT) |
| GND | GND |
| SDA | GP4 (I2C0 SDA) |
| SCL | GP5 (I2C0 SCL) |
Code Examples
Arduino — Set and Read Time
// DS3231 RTC - Arduino Example
// Library: RTClib by Adafruit
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("DS3231 not found!");
while (1);
}
// Run ONCE to set time, then comment out and re-upload:
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
if (rtc.lostPower()) {
Serial.println("Setting time to compile time...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
DateTime now = rtc.now();
Serial.print(now.year()); Serial.print('/');
Serial.print(now.month()); Serial.print('/');
Serial.print(now.day()); Serial.print(' ');
Serial.print(now.hour()); Serial.print(':');
Serial.print(now.minute()); Serial.print(':');
Serial.println(now.second());
Serial.print("Temp: ");
Serial.print(rtc.getTemperature());
Serial.println(" C");
delay(1000);
}
Raspberry Pi (Python)
#!/usr/bin/env python3
# Install: pip install adafruit-circuitpython-ds3231
# Enable I2C: sudo raspi-config
import time
import board, busio
import adafruit_ds3231
i2c = busio.I2C(board.SCL, board.SDA)
rtc = adafruit_ds3231.DS3231(i2c)
# Set time once (uncomment, run, then re-comment):
# t = time.struct_time((2026, 5, 3, 12, 0, 0, 0, -1, -1))
# rtc.datetime = t
while True:
t = rtc.datetime
print(f"{t.tm_year}-{t.tm_mon:02d}-{t.tm_mday:02d} "
f"{t.tm_hour:02d}:{t.tm_min:02d}:{t.tm_sec:02d}")
print(f"Temp: {rtc.temperature:.2f} C")
time.sleep(1)
Raspberry Pi Pico (MicroPython)
# DS3231 on Pico - MicroPython
# Save ds3231_micropython.py from the micropython-stubs repo, or use this minimal driver
from machine import I2C, Pin
import time
I2C_ADDR = 0x68
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
def bcd2dec(b):
return (b // 16) * 10 + (b % 16)
def dec2bcd(d):
return (d // 10) * 16 + (d % 10)
def get_time():
data = i2c.readfrom_mem(I2C_ADDR, 0x00, 7)
sec = bcd2dec(data[0] & 0x7F)
minute = bcd2dec(data[1])
hour = bcd2dec(data[2] & 0x3F)
day = bcd2dec(data[4])
month = bcd2dec(data[5] & 0x1F)
year = 2000 + bcd2dec(data[6])
return (year, month, day, hour, minute, sec)
while True:
print(get_time())
time.sleep(1)
Frequently Asked Questions
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));, upload once, then re-comment and upload again. This sets the RTC to your computer's clock at compile time.rtc.setAlarm1() in RTClib, wire SQW to a digital input, and use an interrupt handler. The MCU can sleep and the RTC will wake it up.