Documentation

DS3231 AT24C32 Precision RTC I2C Module with CR2032 Battery | ShillehTek Product Manual
Documentation / DS3231 AT24C32 Precision RTC I2C Module with CR2032 Battery | ShillehTek Product Manual

DS3231 AT24C32 Precision RTC I2C Module with CR2032 Battery | ShillehTek Product Manual

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

Operating Voltage
3.3V - 5.5V
Accuracy
±2 ppm (0-40°C)
Interface
I2C
RTC Address
0x68
EEPROM Address
0x57 (AT24C32, 4 KB)
Battery Backup
CR2032 included

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

DS3231 AT24C32 RTC module pinout showing 32K, SQW, SCL, SDA, VCC, and GND pins on both sides

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)
Tip: Insert the CR2032 battery positive side up (printed marking visible). With the battery in place, the clock keeps running for 5+ years even with the Arduino unpowered.

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)
Note: To use it as a kernel RTC (so the Pi gets its time from the DS3231 at boot), add 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_arduino.ino
// 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)

ds3231_rpi.py
#!/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_pico.py
# 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

Why does the time reset every time I power on?
Either the CR2032 battery is missing/dead, or it's installed backwards. Pop it out and check that the "+" side (with the printed text) faces up. A fresh battery should hold the clock for 5+ years.
How do I set the time the first time?
In Arduino: uncomment 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.
What's the AT24C32 EEPROM for?
It's general-purpose non-volatile storage on the same I2C bus (address 0x57). You can use it for config data, small log buffers, or anything else you'd put in a microcontroller's EEPROM. It survives power-off but doesn't have wear-leveling — avoid writing the same byte millions of times.
Why does i2cdetect show 0x68 and 0x57?
0x68 is the DS3231 RTC chip and 0x57 is the AT24C32 EEPROM. Both share the I2C bus on this module — that's normal and expected.
Can it generate alarms / interrupt my microcontroller?
Yes. The DS3231 has two programmable alarms with second / minute / hour / day granularity. Set the alarm with 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.
How accurate is the temperature sensor?
±3°C — fine for ambient indoor logging, but not precision metrology. The chip uses it internally to compensate the crystal oscillator, which is why it stays so accurate. If you need real temperature accuracy, pair this with a DS18B20 or BMP280.