Table of Contents
- What Is the DS3231 RTC Module?
- Why DS3231 Over DS1307?
- Technical Specifications
- Wiring DS3231 to Arduino
- Installing the RTClib Library
- Setting the Time on DS3231
- Building a Data Logger with DS3231
- Using DS3231 Alarms
- Reading the Onboard Temperature Sensor
- Frequently Asked Questions
- Conclusion
Every data logger needs one thing above all else: accurate timestamps. Without reliable timekeeping, your sensor readings are just numbers without context. You cannot correlate temperature spikes with time-of-day events, you cannot calculate flow rates over intervals, and you cannot produce meaningful logs for analysis. This is exactly where the DS3231 RTC (Real-Time Clock) module becomes indispensable. Unlike the commonly used DS1307, the DS3231 features a temperature-compensated crystal oscillator (TCXO) built directly into the chip, delivering timekeeping accuracy of ±2 ppm — roughly ±1 minute per year. In this comprehensive guide, we cover everything from wiring to advanced alarm features to help you build precision data loggers with Arduino.
What Is the DS3231 RTC Module?
The DS3231 is a low-cost, extremely accurate I2C real-time clock manufactured by Maxim Integrated. It maintains seconds, minutes, hours, day, date, month, and year information, with automatic leap year correction valid through the year 2100. The chip includes a battery backup input (CR2032 coin cell) that keeps the clock running even when the main power is removed.
Most DS3231 breakout modules (often labeled ZS-042 or similar) come with a CR2032 battery holder, a 32 kHz output pin, an SQW/INT square wave / interrupt output pin, and an optional EEPROM chip (AT24C32) sharing the same I2C bus — giving you 4KB of non-volatile storage for free on the same module.
The key differentiator of the DS3231 is its integrated crystal. Conventional RTC chips like the DS1307 rely on an external 32.768 kHz crystal. Temperature changes affect crystal frequency, causing drift. The DS3231 addresses this by measuring its own temperature every 64 seconds and applying a correction factor to the crystal trimming capacitors, automatically compensating for thermal drift. This is why it is classified as a TCXO (Temperature-Compensated Crystal Oscillator) RTC.
Why DS3231 Over DS1307?
This is one of the most common questions in the Arduino community. Here is a direct comparison:
| Feature | DS1307 | DS3231 |
|---|---|---|
| Accuracy | ±20 ppm (~10 min/year) | ±2 ppm (~1 min/year) |
| Crystal | External 32.768 kHz | Integrated TCXO |
| Temperature Compensation | None | Yes (automatic) |
| Temperature Sensor | No | Yes (±3°C accuracy) |
| Alarms | None | 2 alarms (daily/weekly) |
| Supply Voltage | 4.5V – 5.5V only | 2.3V – 5.5V |
| I2C Speed | 100 kHz | 400 kHz |
| Price Premium | Baseline | Slightly higher |
For any serious data logging application where timestamps matter, the DS3231 is the clear winner. The DS1307 is fine for hobby projects where occasional time drift is acceptable, but for environmental monitoring, industrial data acquisition, or scientific logging, DS3231 is the professional choice.
Technical Specifications
| Parameter | Value |
|---|---|
| Supply Voltage (VCC) | 2.3V – 5.5V |
| Timekeeping Accuracy | ±2 ppm (0°C to +40°C) |
| I2C Address (RTC) | 0x68 |
| I2C Address (EEPROM) | 0x57 |
| Battery Backup | CR2032 (typical 8–10 years) |
| Temperature Sensor | ±3°C accuracy, 0.25°C resolution |
| Number of Alarms | 2 (configurable) |
| SQW Output Frequencies | 1 Hz, 1.024 kHz, 4.096 kHz, 8.192 kHz |
| Operating Temperature | -40°C to +85°C |
Wiring DS3231 to Arduino
The DS3231 module communicates over I2C with four essential connections:
| DS3231 Pin | Arduino Uno/Nano | Arduino Mega |
|---|---|---|
| VCC | 5V or 3.3V | 5V or 3.3V |
| GND | GND | GND |
| SDA | A4 | Pin 20 |
| SCL | A5 | Pin 21 |
| SQW/INT | D2 (optional) | D2 (optional) |
Most DS3231 breakout modules have 4.7kΩ pull-up resistors already on SDA and SCL. No external pull-ups are needed. Insert a CR2032 battery into the module before connecting it to ensure the clock maintains time when power is cut.
Installing the RTClib Library
The most widely used library for DS3231 in Arduino is RTClib by Adafruit. Install it via the Library Manager:
- Go to Sketch → Include Library → Manage Libraries
- Search for “RTClib”
- Install the one by Adafruit
RTClib supports both DS1307 and DS3231 with the same API, making it easy to migrate between chips. The library abstracts time as a DateTime object, so you can easily extract year, month, day, hour, minute, and second as individual integers.
Setting the Time on DS3231
The DS3231 retains time as long as the battery is connected, so you only need to set it once. Use the following sketch to set the time to the computer’s current time at compile time:
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("Couldn't find DS3231!");
while(1);
}
// Set time to compile time (uncomment once, then comment again)
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Alternatively, set a specific time:
// rtc.adjust(DateTime(2026, 3, 11, 14, 30, 0)); // 2026-03-11 14:30:00
}
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());
delay(1000);
}
Important: Uncomment the rtc.adjust() line, upload the sketch, then immediately re-comment it and upload again. If you leave it uncommented, every time the Arduino resets it will reset the clock to the original compile time.
DS18B20 Programmable Resolution Temperature Sensor
The perfect companion for DS3231 data loggers — the DS18B20 provides ±0.5°C accurate temperature readings over a single-wire bus, ideal for environmental logging.
Building a Data Logger with DS3231
A classic data logger pairs the DS3231 RTC with an SD card module and a sensor. Here is a complete sketch that logs temperature and humidity from a DHT11 sensor to an SD card with DS3231 timestamps:
#include <Wire.h>
#include <RTClib.h>
#include <SD.h>
#include <DHT.h>
#define DHTPIN 4
#define DHTTYPE DHT11
#define SD_CS_PIN 10
RTC_DS3231 rtc;
DHT dht(DHTPIN, DHTTYPE);
File dataFile;
void setup() {
Serial.begin(9600);
dht.begin();
if (!rtc.begin()) {
Serial.println("DS3231 not found!");
while(1);
}
if (!SD.begin(SD_CS_PIN)) {
Serial.println("SD card initialization failed!");
while(1);
}
// Write CSV header
dataFile = SD.open("log.csv", FILE_WRITE);
if (dataFile) {
dataFile.println("Timestamp,Temperature_C,Humidity_pct");
dataFile.close();
}
Serial.println("Data logger ready.");
}
void loop() {
DateTime now = rtc.now();
float temp = dht.readTemperature();
float hum = dht.readHumidity();
// Format timestamp: YYYY-MM-DD HH:MM:SS
char timestamp[20];
snprintf(timestamp, sizeof(timestamp), "%04d-%02d-%02d %02d:%02d:%02d",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
// Print to Serial
Serial.print(timestamp);
Serial.print(",");
Serial.print(temp);
Serial.print(",");
Serial.println(hum);
// Write to SD card
dataFile = SD.open("log.csv", FILE_WRITE);
if (dataFile) {
dataFile.print(timestamp);
dataFile.print(",");
dataFile.print(temp);
dataFile.print(",");
dataFile.println(hum);
dataFile.close();
}
delay(60000); // Log every minute
}
This produces a clean CSV file you can open directly in Microsoft Excel or Google Sheets for analysis and charting. The DS3231 ensures every entry is timestamped accurately to within seconds per year.
Using DS3231 Alarms
The DS3231 has two independent alarms that can trigger the SQW/INT pin LOW when the time matches the alarm setting. This is extremely useful for wake-up timers in battery-powered data loggers:
#include <Wire.h>
#include <DS3232RTC.h> // Alternative library with full alarm support
DS3232RTC rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
// Clear any pending alarms
rtc.alarm(ALARM_1);
rtc.alarm(ALARM_2);
rtc.alarmInterrupt(ALARM_1, true);
rtc.alarmInterrupt(ALARM_2, false);
// Set Alarm 1 to trigger every minute when seconds == 0
rtc.setAlarm(ALM1_MATCH_SECONDS, 0, 0, 0, 1);
Serial.println("Alarm set for every minute.");
}
void loop() {
if (rtc.alarm(ALARM_1)) {
DateTime now = rtc.get();
Serial.print("Alarm triggered at: ");
Serial.println(now.timestamp());
// Take sensor reading here
}
}
Alarms are essential for low-power designs where the Arduino sleeps between readings. Connect the SQW pin to an interrupt-capable pin (D2 or D3 on Uno), put the Arduino to sleep, and the DS3231 alarm will wake it up at the exact scheduled time.
Reading the Onboard Temperature Sensor
The DS3231 measures its own die temperature every 64 seconds as part of its compensation routine. You can read this value for a rough ambient temperature estimate:
float temp = rtc.getTemperature();
Serial.print("DS3231 Temperature: ");
Serial.print(temp);
Serial.println(" C");
The onboard sensor is rated at ±3°C accuracy — not precise enough for scientific measurements, but useful as a board-level temperature reference or to verify the thermal compensation is working correctly.
DHT11 Temperature and Humidity Sensor Module
Log both temperature and humidity data alongside DS3231 timestamps. The DHT11 is a plug-and-play sensor perfect for environmental data loggers.
Frequently Asked Questions
How long does the CR2032 battery last in the DS3231?
Maxim’s datasheet calculates battery life at approximately 8–10 years under typical conditions, with the DS3231 drawing only 500 nA from the backup battery. In practice, most users report 5–7 years before needing a replacement, depending on temperature extremes.
Why does my DS3231 lose time after power off?
Check that the CR2032 battery is properly seated and has charge. Some ZS-042 modules have a charging circuit that can slowly drain standard CR2032 batteries (they are non-rechargeable). If you have a ZS-042, you may need to remove or bypass the charging diode and resistor to prevent reverse charging.
Can I use DS3231 with ESP32 or ESP8266?
Yes, absolutely. Both platforms support I2C and 3.3V logic, and the DS3231 works at 3.3V. Use the RTClib or DS3231 library just as with Arduino. On ESP8266, SDA defaults to GPIO4 and SCL to GPIO5. On ESP32, you can use any GPIO pair configured for I2C.
What is the EEPROM chip on the DS3231 module for?
The AT24C32 EEPROM on most breakout boards provides 4KB (32Kbit) of non-volatile storage on the same I2C bus at address 0x57. You can store calibration data, configuration settings, or small data buffers there without needing an SD card.
Is the DS3231 accurate enough for scientific data logging?
At ±2 ppm (roughly 1 minute per year), the DS3231 is suitable for most scientific and engineering data logging applications. For applications requiring sub-second accuracy over years, GPS-disciplined oscillators or network time synchronization (NTP) are more appropriate.
Can two DS3231 modules share the same I2C bus?
Not without an I2C multiplexer, since the address is fixed at 0x68. Use a TCA9548A I2C multiplexer to connect multiple DS3231 modules to one Arduino if needed.
Conclusion
The DS3231 RTC module is the gold standard for timekeeping in Arduino data logger projects. Its temperature-compensated crystal oscillator, dual alarms, onboard temperature sensor, and wide voltage range make it far superior to older RTC chips for any application where accurate timestamps matter. Whether you are logging environmental data, automating timed processes, or building wake-up timers for battery-powered sensors, the DS3231 delivers professional-grade reliability at an hobbyist-friendly price.
Pair it with a DS18B20 or DHT11 sensor, an SD card module, and an Arduino, and you have a complete, standalone data logger capable of running for months on battery backup. The ±2 ppm accuracy means your timestamps will be accurate for years without re-synchronization.
Find temperature sensors, humidity sensors, and other measurement modules to pair with the DS3231 in your next data logging project. Shop all sensors at Zbotic →
Add comment