Clocks, school bells, timed pumps and data loggers all need to know the real time after a power cut — something the Nano cannot do on its own. The DS3231 keeps time on a coin cell and talks I2C on A4/A5.
On first run (or after a battery change) the sketch sets the clock from your PC’s time at compile, then prints the date, time and the chip’s own temperature sensor once a second.
Wiring
| Arduino Nano | DS3231 real-time clock (RTC) module | Wire | Notes |
|---|---|---|---|
| 5V | VCC | red | |
| GND | GND | black | |
| A4 | SDA | blue | |
| A5 | SCL | yellow |
2.3–5.5 V part, 5 V board. The module pulls SDA/SCL up to its own VCC. On a 3.3 V board, power it from 3.3 V — the DS3231 keeps excellent time at 3.3 V.
Board quirks
- The popular ZS-042 board has a charging circuit (a diode and 200 Ω resistor) that pushes current into the coin cell. With 5 V on VCC and a normal non-rechargeable CR2032, that is unsafe. Either fit a rechargeable LIR2032, or remove the resistor/diode.
- The module also carries an AT24C32 EEPROM at 0x57 — an I2C scanner shows two addresses, and that is normal.
- The time is set from the moment the sketch was compiled, so it is a few seconds behind. Upload straight after compiling.
- Leave 32K and SQW unconnected. SQW can wake a sleeping Nano once a second or on an alarm, via D2 (INT0).
- The DS3231 drifts about a minute a year — far better than
millis()on a Nano, whose resonator can drift minutes a day.
Code
// DS3231 RTC on an Arduino Nano: sets itself from the compile time after a battery change,
// then prints the date, time and the DS3231's own temperature every second.
// VCC → 5V, GND → GND, SDA → A4, SCL → A5.
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(115200);
if (!rtc.begin()) {
Serial.println(F("DS3231 not found - check A4/A5"));
for (;;) {}
}
if (rtc.lostPower()) {
Serial.println(F("RTC lost power - setting it to the sketch's compile time"));
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
rtc.disable32K(); // the 32K output is not needed
}
void loop() {
DateTime now = rtc.now();
char buf[] = "DD-MM-YYYY hh:mm:ss";
Serial.print(now.toString(buf));
Serial.print(F(" RTC temp: "));
Serial.print(rtc.getTemperature(), 2);
Serial.println(F(" C"));
delay(1000);
}// DS3231 RTC on an Arduino Nano: sets itself from the compile time after a battery change,
// then prints the date, time and the DS3231's own temperature every second.
// VCC → 5V, GND → GND, SDA → A4, SCL → A5.
#include <Wire.h>
#include <RTClib.h>
RTC_DS3231 rtc;
void setup() {
Serial.begin(115200);
if (!rtc.begin()) {
Serial.println(F("DS3231 not found - check A4/A5"));
for (;;) {}
}
if (rtc.lostPower()) {
Serial.println(F("RTC lost power - setting it to the sketch's compile time"));
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
rtc.disable32K(); // the 32K output is not needed
}
void loop() {
DateTime now = rtc.now();
char buf[] = "DD-MM-YYYY hh:mm:ss";
Serial.print(now.toString(buf));
Serial.print(F(" RTC temp: "));
Serial.print(rtc.getTemperature(), 2);
Serial.println(F(" C"));
delay(1000);
}Library: RTClib (Adafruit) — compiled with RTClib 2.1.4.
Expected serial output
RTC lost power - setting it to the sketch's compile time
03-11-2026 14:22:07 RTC temp: 28.25 C
03-11-2026 14:22:08 RTC temp: 28.25 CRTC lost power - setting it to the sketch's compile time 03-11-2026 14:22:07 RTC temp: 28.25 C 03-11-2026 14:22:08 RTC temp: 28.25 C
Common errors
DS3231 not found
SDA/SCL on A6/A7 or swapped. Full fix.
Time resets after every power cut
No coin cell, a flat cell, or a CR2032 drained by the charging circuit. Replace it and fix the circuit as above.