Blog

DS1302 Real-Time Clock (RTC) Module – Complete Guide

Real-Time Clock Module

DS1302 Real-Time Clock (RTC) Module

Battery-Backed Timekeeping with Simple 3-Wire Interface

A microcontroller has no real sense of wall-clock time on its own - millis() only counts time since the last power-up or reset, and that count is lost completely every time power drops. The DS1302 solves this by being a dedicated, self-contained timekeeping chip: it tracks seconds, minutes, hours, day, date, month, and year, with automatic leap-year correction built in, using its own internal oscillator, and critically, it keeps running on a tiny backup coin-cell battery even while the rest of your project is completely powered off - so the correct time survives power cycles, resets, and reprogramming. It communicates over a simple synchronous 3-wire interface (a chip-enable-like line, a clock line, and a single bidirectional data line) rather than I2C, and internally stores its date/time fields in BCD (binary-coded decimal) format, meaning each byte's two nibbles directly represent two decimal digits - a detail your code needs to convert to and from when reading or setting the clock.

Seconds through Year
Tracks
3-Wire Serial
Interface
Battery-Backed
Power Loss

Key features

Battery-Backed Timekeeping

A coin-cell backup keeps the clock running through complete power loss.

Full Calendar Tracking

Seconds, minutes, hours, day, date, month, and year with leap-year correction.

Simple 3-Wire Interface

No I2C address conflicts - a dedicated CE/CLK/DATA connection.

Onboard Trickle Charger

Some breakouts can trickle-charge a rechargeable backup cell.

Built-In RAM

A small block of battery-backed general-purpose RAM for persistent settings.

Low Power Draw

Draws only a few hundred nanoamps from the backup battery when main power is off.

Technical specifications

Supply Voltage 2.0V – 5.5V (main), backed by a 3V coin cell
Interface 3-wire serial (CE, I/O, SCLK)
Tracks Seconds, minutes, hours, day, date, month, year
Data Format BCD (binary-coded decimal)
Leap Year Automatically corrected through 2100
Backup Current Draw ~300nA typical (clock running, main power off)
Onboard RAM 31 x 8-bit battery-backed scratchpad registers
Accuracy Crystal-dependent, typically a few sec/day drift
Package Breakout module with 32.768kHz crystal and battery holder

Pinout

PinFunction
VCC Main power supply
GND Ground
CLK Serial clock
DAT Bidirectional serial data
RST/CE Chip enable - must be HIGH during a transfer

Applications

Data loggers with accurate timestamps Digital clocks and alarm projects Attendance and access-log systems Scheduled automation (irrigation timers, feeders) Battery-backed event logging Offline projects needing correct time after power loss

What's in the box

1x DS1302 RTC module
Coin-cell backup battery

Downloads

Datasheet (PDF) Arduino Ds1302 Library Example
🔌
Pin Connections
1 Table
Pin Connections Table 1
BoardSensor PinConnection
DS1302VCC/GND/CLK/DAT/RST3.3-5V / GND / board digital / board digital / board digital
📟
DS1302 RTC Real Time Clock Module with battery
7 Examples • C/C++ | Boards: Arduino Uno, Arduino Nano, Arduino Mega, ESP32, ESP8266, STM32, Raspberry Pi Pico
DS1302 RTC Real Time Clock Module with battery - Arduino Uno
DS1302 RTC Real Time Clock Module with battery - Arduino Nano
DS1302 RTC Real Time Clock Module with battery - Arduino Mega
DS1302 RTC Real Time Clock Module with battery - ESP32
DS1302 RTC Real Time Clock Module with battery - ESP8266
DS1302 RTC Real Time Clock Module with battery - STM32
DS1302 RTC Real Time Clock Module with battery - Raspberry Pi Pico
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_arduino_uno.inoArduino Uno
745 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=5, DAT=6, RST=7 on Arduino Uno (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(6, 5, 7);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_arduino_nano.inoArduino Nano
746 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=5, DAT=6, RST=7 on Arduino Nano (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(6, 5, 7);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_arduino_mega.inoArduino Mega
746 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=5, DAT=6, RST=7 on Arduino Mega (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(6, 5, 7);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_esp32.inoESP32
745 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=18, DAT=19, RST=21 on ESP32 (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(19, 18, 21);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_esp8266.inoESP8266
747 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=D5, DAT=D6, RST=D7 on ESP8266 (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(D6, D5, D7);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_stm32.inoSTM32
751 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=PB6, DAT=PB7, RST=PB8 on STM32 (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(PB7, PB6, PB8);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
📄 File: ds1302_rtc_real_time_clock_module_with_battery_-_raspberry_pi_pico.inoRaspberry Pi Pico
757 characters
1//ekostra.com
2//electronics store in egypt
3//+201008896258
4
5// CLK=18, DAT=19, RST=20 on Raspberry Pi Pico (bit-banged, so any digital pins work)
6#include <ThreeWire.h>
7#include <RtcDS1302.h>
8
9ThreeWire myWire(19, 18, 20);
10RtcDS1302<ThreeWire> Rtc(myWire);
11
12void setup() {
13 Serial.begin(115200);
14 Rtc.Begin();
15 if (!Rtc.IsDateTimeValid()) {
16 Rtc.SetDateTime(RtcDateTime(__DATE__, __TIME__)); // set to compile time once, then it keeps its own time on battery
17 }
18}
19
20void loop() {
21 RtcDateTime now = Rtc.GetDateTime();
22 Serial.print(now.Year()); Serial.print("-"); Serial.print(now.Month()); Serial.print("-"); Serial.print(now.Day());
23 Serial.print(" "); Serial.print(now.Hour()); Serial.print(":"); Serial.println(now.Minute());
24 delay(1000);
25}
3-wire (bit-banged) real-time clock module with battery backup.
The clock has no idea what the current time is on first use - your sketch needs to explicitly write the correct date and time once, typically taken from your PC's compile-time timestamp, and that set-time code should then be commented out or removed so the sketch doesn't silently reset the clock back to the same fixed value on every subsequent power-up. If the time resets to a default or wrong value every single power cycle on a module that's been sitting unused for a long time, the backup coin cell is the first thing to check or replace. And since raw register reads come back in BCD, not plain binary, prefer a proven library's conversion over hand-rolling the bit-shifting math yourself, which is an easy place to introduce an off-by-one-digit error.