DS1307 Real-Time Clock (RTC) Interfacing with Arduino and LCD1602 I2C
Real-time clocks are very important in Arduino projects where you must keep track of the exact time and date. The DS1307 RTC module is one of the most commonly used real-time clocks because it is inexpensive and easy to interface. It communicates using the I2C protocol and keeps time using a small backup battery, even when the main power is removed.
In this tutorial, you will learn how to interface the DS1307 RTC with Arduino and display the live clock on the LCD1602 I2C display. If you are new to I2C LCDs, you can follow my detailed guide here: I2C LCD1602 Arduino Tutorial. Each section in this post contains complete example codes, explanations, and simple steps designed to give you clear understanding.
We will cover setting the time, reading the time, displaying it on the LCD, and using all functions of the DS1307, including the square-wave output and internal RAM. By the end of this tutorial, you will be able to build your own clock, timer, or logging system with Arduino.

- What is DS1307 RTC Module?
- DS1307 Pinout and Arduino Connection
- Installing DS1307 Arduino Libraries
- Setting the Time and Date on DS1307
- Reading Time and Date From DS1307
- Displaying Real-Time Clock on LCD1602 I2C
- Using Square Wave Output (1Hz / 4kHz / 8kHz / 32kHz)
- Reading and Writing DS1307 RAM (56 Bytes Internal Memory)
- Conclusion
What is DS1307 RTC Module?
The DS1307 RTC module is a Real-Time Clock chip that keeps accurate time even when the Arduino is powered off. It uses a small coin-cell battery to maintain the time internally. This makes it very useful in projects where you need to track time, date, or schedule events.

The chip communicates over the I2C interface, which means it requires only two pins on the Arduino. It is commonly used with LCD displays, data loggers, timers, alarms, and automation projects. In this tutorial, we will use LCD1602 I2C display to show the real-time clock, and you can also read my LCD tutorial for reference.
Features of DS1307 RTC
- Works on the I2C bus (SDA and SCL pins).
- Tracks seconds, minutes, hours, day, date, month, and year.
- Keeps time running with a CR2032 backup battery.
- Supports 12-hour and 24-hour time format.
- Has 56 bytes of battery-backed RAM for small data storage.
- Affordable and widely available in most Arduino starter kits.
Limitations of DS1307 Compared to DS3231
- DS1307 is less accurate. It can drift a few minutes per month.
- It is affected by temperature changes, unlike the DS3231 which has a built-in temperature-compensated crystal.
- DS1307 does not support alarms, but DS3231 does.
- DS1307 requires an external crystal oscillator, which further reduces accuracy.
- DS3231 is a drop-in replacement with much higher precision.
Applications of DS1307 in Arduino Projects
- Digital clocks with LCD or OLED displays.
- Timers and reminders in automation systems.
- Data logging with SD card modules.
- Home automation that works on scheduled tasks.
- Attendance and access systems where time stamping is needed.
- Weather stations where you record sensor data with timestamps.
DS1307 Pinout and Arduino Connection
The DS1307 RTC module uses the I2C protocol, which makes wiring very easy. You only need two data lines, and these lines can also be shared with other I2C devices like the LCD1602 I2C display.
DS1307 Pin Description
The DS1307 module usually has 7 pins. The image below shows the pinout of the DS3231 module.
The tables below explain the function of each pin.
| Pin Name | Function | Details |
|---|---|---|
| SDA | I2C Data Line | Transfers data between Arduino and DS1307 |
| SCL | I2C Clock Line | Provides clock signal for I2C communication |
| VCC | Power Input | Connect to 5V supply |
| GND | Ground | Common ground for the module |
| SQ | Square Wave Output | Outputs 1Hz, 4kHz, 8kHz, 32kHz signal |
| DS | Data Pin for DS18B20 | Can be used to communicate with DS18B20, if connected |
| BAT | Backup Battery | Holds a CR2032 cell to keep time running without power |
Wiring DS1307 to Arduino UNO
Connecting the DS1307 to an Arduino UNO is very easy. The module uses the I2C pins of the Arduino.
Here is the wiring:
- DS1307 VCC → 5V
- DS1307 GND → GND
- DS1307 SDA → A4
- DS1307 SCL → A5
The pins A4 and A5 are default I2C pins on the UNO. Keep the wires short for stable I2C communication.
Adding LCD1602 I2C to the Same Bus
The LCD1602 I2C display also uses the I2C bus, so it connects to the same SDA and SCL pins.
Connection:
- LCD SDA → A4
- LCD SCL → A5
- LCD VCC → 5V
- LCD GND → GND
Both DS1307 and LCD1602 will share the same two lines (SDA and SCL). Since each device has its own I2C address, they work without conflict.
Complete Circuit Diagram
The complete wiring for DS1307 and LCD1602 I2C connected to Arduino UNO is shown below:
Here is the final wiring in tabular form for better clarity:
| Arduino UNO | DS1307 RTC | LCD1602 I2C | Purpose |
|---|---|---|---|
| 5V | VCC | VCC | Power for both modules |
| GND | GND | GND | Common ground |
| A4 (SDA) | SDA | SDA | Shared I2C Data line |
| A5 (SCL) | SCL | SCL | Shared I2C Clock line |
Summary of the Circuit
| Point | Explanation |
|---|---|
| Same I2C bus | Both modules share SDA and SCL pins |
| No address conflict | Each device has a unique I2C address |
| Backup Battery | DS1307 keeps time running even without Arduino power |
| Clean wiring | Only 4 wires per module needed |
| LCD Display | Shows real-time clock data from DS1307 |
Installing DS1307 Arduino Libraries
To work with the DS1307 RTC module, we need the right Arduino libraries. These libraries make it easy to set the time, read the time, and use all the functions of the RTC. We also need the LCD1602 I2C library because we will display the real-time clock on the LCD. Once both libraries are installed, we can start testing simple example codes to make sure everything works.
Installing “RTClib” Library
The RTClib library is one of the most popular libraries for DS1307. It provides simple functions to read and set the time.
Follow these steps:
- Open Arduino IDE
- Go to Sketch → Include Library → Manage Libraries
- In the search bar, type RTClib
- Install the library published by Adafruit
This library supports DS1307, DS3231, and other RTC modules, so it works perfectly for this tutorial.
Installing the LiquidCrystal_I2C Library
Before writing the code, install the LiquidCrystal_I2C library:
- Open Arduino IDE.
- Go to Sketch → Include Library → Manage Libraries.
- Search for “LiquidCrystal_I2C”.
- Install the version by Frank de Brabander or Marco Schwartz.
Testing the Library Examples
After installing both libraries, it is a good idea to test the example codes.
- Open Arduino IDE
- Go to File → Examples → RTClib
- Run the ds1307 example
- Check the serial monitor to confirm the date and time readings
Next, test the LCD:
- Go to File → Examples → LiquidCrystal_I2C
- Upload the HelloWorld example
- Make sure the LCD shows the text
Setting the Time and Date on DS1307
Before using the DS1307 RTC in your project, you must set the correct time and date. The DS1307 stores this information in its internal registers and keeps running even when the Arduino is powered off, thanks to its backup battery. You can set the time manually, or you can let the Arduino automatically set it using your computer’s compile time. Both methods are simple and supported by the RTClib library.
Code to Set Time Manually
You can set the time and date by entering the values directly in the code. This is useful when you want full control or when your project needs a specific starting time.
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// Manually set the date and time (Year, Month, Day, Hour, Minute, Second)
rtc.adjust(DateTime(2025, 1, 1, 12, 0, 0));
Serial.println("RTC time set manually!");
}
void loop() {
}Short explanation:
- We include Wire and RTClib.
- We start the RTC and check if it’s connected.
rtc.adjust()sets the time using the DateTime format.- This time stays stored in the DS3231 until you change it again.
Code to Set Time Automatically Using Compile Time
This method sets the RTC to the computer’s exact time at the moment the code is uploaded. It is quick and very convenient.
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("RTC not found");
while (1);
}
// Set RTC using the compile time
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("RTC updated using compile time!");
}
void loop() {
}Short explanation:
__DATE__and__TIME__are built-in macros.- They read your computer’s real time at compilation.
- Upload the code immediately after compiling for best accuracy.
Explanation of Time and Date Functions
The RTClib library provides simple functions to work with the DS1307 time and date.
Here are the most useful ones:
| Function | Description |
|---|---|
rtc.begin() | Starts communication with the DS1307 |
rtc.adjust(DateTime(...)) | Sets the time and date |
rtc.now() | Reads the current time from DS1307 |
now.year() / now.month() / now.day() | Extracts date values |
now.hour() / now.minute() / now.second() | Extracts time values |
now.dayOfTheWeek() | Returns day of the week (0–6) |
now.unixtime() | Returns Unix timestamp |
How it works:
rtc.now()returns a DateTime object.- You can break it into year, month, day, hour, minute, and second.
- These values can be printed on LCD or used in automation projects.
Reading Time and Date From DS1307
Once the time is set on the DS1307, you can read it anytime using simple functions from the RTClib library. The RTC keeps running even when the Arduino is off, so every time your project starts, you can instantly read accurate time and date. In this section, we will read the live clock values and later display them on the LCD1602 I2C.
Code to Read Time and Date
Below is the simplest code to read the current time and date from the DS3231 and print them on the Serial Monitor:
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("RTC not found!");
while (1);
}
Serial.println("Reading time from DS3231...");
}
void loop() {
DateTime now = rtc.now();
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.print(now.second());
Serial.print(" ");
Serial.print(now.day());
Serial.print("/");
Serial.print(now.month());
Serial.print("/");
Serial.print(now.year());
Serial.println();
delay(1000);
}Explanation:
rtc.now()reads the current time.- The values are printed as HH:MM:SS and DD/MM/YYYY.
delay(1000)updates the print every second.
Breaking Down RTC Read Function
The rtc.now() function returns a DateTime object. You can extract individual values easily:
| Function | Returns |
|---|---|
now.hour() | Current hour (0–23) |
now.minute() | Current minute |
now.second() | Current seconds |
now.day() | Day of the month |
now.month() | Month number |
now.year() | Full year |
now.dayOfTheWeek() | Day index (0 = Sunday) |
These functions make it simple to show the clock on LCD or use the time for automation tasks.
Example:
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
int second = now.second();Handling 12-Hour and 24-Hour Format
The DS1307 works internally in 24-hour format, but you can easily convert it to 12-hour AM/PM format in your code.
The code snippet below can be used to display 12-hour formatted time.
int hour24 = now.hour();
int hour12 = hour24 % 12;
if (hour12 == 0) hour12 = 12;
String period = (hour24 >= 12) ? "PM" : "AM";
Serial.print(hour12);
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.print(now.second());
Serial.print(" ");
Serial.println(period);How it works:
% 12converts 24-hour to 12-hour format.- If the result is 0, we set it to 12 (for midnight/noon).
- The AM/PM value is selected based on hour24.
When to use 24-hour format
Use 24-hour format when:
- Building clocks for automation
- Using alarms
- Logging data
24-hour time avoids confusion between AM and PM.
Displaying Real-Time Clock on LCD1602 I2C
When working with the DS1307 Real-Time Clock module, the final and most useful step is to show the live time and date on a display. In this tutorial, we will use the LCD1602 I2C display, which requires only two wires (SDA and SCL).
If you have followed my previous tutorial on LCD1602 I2C, the process will feel very familiar. Here, we will combine the DS1307 data with the LCD to create a simple real-time clock output.
Below is the complete example that reads both date and time from the DS1307 and prints them to the LCD1602 I2C in real time.
Complete Code: Display Date + Time on LCD1602 (I2C)
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// -------------------- SETTINGS --------------------
// Enable only ONE of the following:
#define AUTO_TIME_SET 1 // Set RTC from system compile time
#define MANUAL_TIME_SET 0 // Set RTC to manually defined values
// Manual time setup (works only when MANUAL_TIME_SET = 1)
int manualYear = 2025;
int manualMonth = 1;
int manualDate = 15;
int manualHour = 10;
int manualMinute = 45;
int manualSecond = 0;
// ---------------------------------------------------
void setup() {
Serial.begin(9600);
Wire.begin();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
#if AUTO_TIME_SET
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
#endif
#if MANUAL_TIME_SET
rtc.adjust(DateTime(manualYear, manualMonth, manualDate,
manualHour, manualMinute, manualSecond));
#endif
lcd.begin(16, 2);
lcd.backlight();
}
void loop() {
DateTime now = rtc.now();
// Format Date: DD/MM/YYYY
char dateBuffer[17];
snprintf(dateBuffer, sizeof(dateBuffer), "%02d/%02d/%04d",
now.day(), now.month(), now.year());
// Format Time: HH:MM:SS
char timeBuffer[17];
snprintf(timeBuffer, sizeof(timeBuffer), "%02d:%02d:%02d",
now.hour(), now.minute(), now.second());
// Display on LCD
lcd.setCursor(0, 0);
lcd.print(dateBuffer);
lcd.setCursor(0, 1);
lcd.print(timeBuffer);
delay(1000);
}Explanation:
1. Library Imports
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>These libraries handle I2C communication, the DS1307 RTC module, and the 16×2 I2C LCD.
2. Object Creation
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);rtc→ creates an RTC object for DS1307.lcd→ creates an LCD object at I2C address0x27, with a 16×2 display size.
3. Settings Section
#define AUTO_TIME_SET 1
#define MANUAL_TIME_SET 0Only one method can be active:
AUTO_TIME_SET = 1sets the RTC time from the computer’s compile time.MANUAL_TIME_SET = 1sets custom date/time from user-defined values.
Manual time values:
int manualYear = 2025;
...
...These are used only when manual mode is enabled.
4. Setup Function
A. Initialize Serial & I2C
Serial.begin(9600);
Wire.begin();Starts serial communication and enables I2C.
B. Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}Checks if the DS1307 is connected. If not, the code stops here.
C. Select Time Setting Mode
#if AUTO_TIME_SET
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
#endifSets RTC using the system’s compile date/time.
#if MANUAL_TIME_SET
rtc.adjust(DateTime(manualYear, manualMonth, manualDate,
manualHour, manualMinute, manualSecond));
#endifSets RTC using the manual values.
D. Initialize LCD
lcd.begin(16, 2);
lcd.backlight();Starts the 16×2 LCD and turns on its backlight.
5. Loop Function
A. Read Current Time
DateTime now = rtc.now();Fetches current date and time from the DS1307 module.
B. Format Date
char dateBuffer[17];
snprintf(dateBuffer, sizeof(dateBuffer), "%02d/%02d/%04d",
now.day(), now.month(), now.year());Creates a string like: 15/01/2025
C. Format Time
char timeBuffer[17];
snprintf(timeBuffer, sizeof(timeBuffer), "%02d:%02d:%02d",
now.hour(), now.minute(), now.second());Creates a string like: 10:45:00
D. Display on LCD
lcd.setCursor(0, 0);
lcd.print(dateBuffer);
lcd.setCursor(0, 1);
lcd.print(timeBuffer);Line 1 : Date
Line 2 : Time
E. Update Every Second
delay(1000);Refreshes the display once per second.
The gif below shows the current time and date printed on the LCD1602.
Using Square Wave Output (1Hz / 4kHz / 8kHz / 32kHz)
The DS1307 can generate a stable and accurate square-wave output on the SQW pin. This signal is very useful in many Arduino projects, especially where you need:
- A precise clock pulse
- Timer generation
- Power-saving wakeups
- External timing reference
- CPU tick replacement
The DS1307 supports multiple square-wave frequencies, and you can select any one depending on your project needs.
Below is a complete code that enables different SQW output frequencies using the DS1307.
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// -------------------- SETTINGS --------------------
#define AUTO_TIME_SET 1 // Set RTC from system compile time
#define MANUAL_TIME_SET 0 // Set RTC to manually defined values
// Manual time setup (only used when MANUAL_TIME_SET = 1)
int manualYear = 2025;
int manualMonth = 1;
int manualDate = 15;
int manualHour = 10;
int manualMinute = 45;
int manualSecond = 0;
// ---------------------------------------------------
void setup() {
Wire.begin();
lcd.init();
lcd.backlight();
if (!rtc.begin()) {
lcd.print("RTC ERROR");
while (1);
}
// ---------------- TIME SETTING -------------------
#if AUTO_TIME_SET
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
#endif
#if MANUAL_TIME_SET
rtc.adjust(DateTime(manualYear, manualMonth, manualDate,
manualHour, manualMinute, manualSecond));
#endif
// ---------------------------------------------------
// Choose one line based on required SQW frequency:
rtc.writeSqwPinMode(DS1307_SquareWave1HZ);
// rtc.writeSqwPinMode(DS1307_SquareWave4kHz);
// rtc.writeSqwPinMode(DS1307_SquareWave8kHz);
// rtc.writeSqwPinMode(DS1307_SquareWave32kHz);
lcd.setCursor(0, 0);
lcd.print("SQW Enabled");
lcd.setCursor(0, 1);
lcd.print("Freq: 1 Hz"); // Update text if you change the mode
}
void loop() {
// Nothing required in loop – SQW output works automatically
}Explanation
- This example shows how to enable the DS1307’s built-in square-wave output.
- The SQW pin can generate four fixed frequencies: 1Hz, 4kHz, 8kHz, and 32kHz.
- You simply select one of the modes using
writeSqwPinMode(). - The SQW output is hardware-based, so it continues running even if the Arduino resets.
Output
The image below shows the output measured from the SQW pin of the module.
I have connected an LED to SQW pin, it will blink once every second. The gif below shows the LED blinking every second.
Reading and Writing DS1307 RAM (56 Bytes Internal Memory)
The DS1307 includes 56 bytes of battery-backed RAM. You can store small values such as settings, counters, flags, or calibration data. This memory stays safe even when Arduino loses power, as long as the RTC battery is present.
Below is the full code to write data into DS1307 RAM and read it back.
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// -------------------- SETTINGS --------------------
#define AUTO_TIME_SET 1 // Auto set RTC from compile time
#define MANUAL_TIME_SET 0 // Manually set RTC time
// Manual time values
int manualYear = 2025;
int manualMonth = 1;
int manualDate = 15;
int manualHour = 10;
int manualMinute = 45;
int manualSecond = 0;
// ---------------------------------------------------
void setup() {
Wire.begin();
lcd.init();
lcd.backlight();
if (!rtc.begin()) {
lcd.print("RTC ERROR");
while (1);
}
// ---------------- TIME SETTING -------------------
#if AUTO_TIME_SET
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
#endif
#if MANUAL_TIME_SET
rtc.adjust(DateTime(manualYear, manualMonth, manualDate,
manualHour, manualMinute, manualSecond));
#endif
// ---------------------------------------------------
// Example: Write data to DS1307 RAM
rtc.writenvram(0, 123); // Store value 123 at RAM address 0
rtc.writenvram(1, 45); // Store value 45 at RAM address 1
// Read back values
uint8_t value1 = rtc.readnvram(0);
uint8_t value2 = rtc.readnvram(1);
lcd.setCursor(0, 0);
lcd.print("RAM0:");
lcd.print(value1);
lcd.setCursor(0, 1);
lcd.print("RAM1:");
lcd.print(value2);
}
void loop() {
// Nothing to do — values already printed
}Explanation
- This example uses the DS1307’s non-volatile RAM to store two user-defined values.
- We write values using
writenvram()and read them back usingreadnvram(). - Since the RAM is powered by the RTC’s coin battery, the saved data remains even if Arduino loses power.
- This feature is useful for storing small configuration data or counters that you want to keep permanently.
Output
The image below shows the output of the code on the LCD.
You can see the value 123 is read from the nvRam0 and 45 from the nvRam1. These are the same values that we stored in the memories.
Conclusion
In this tutorial, you learned how to interface the DS1307 RTC module with Arduino and use its powerful real-time features. We covered the complete setup process, including wiring, installing libraries, setting the date and time, and displaying live clock data on the LCD1602 I2C display. You also explored the other useful DS1307 functions such as writing and reading NVRam and using the SQW pin to trigger an LED or buzzer.
The DS1307 is a simple, beginner-friendly real-time clock that works well for basic timekeeping in Arduino projects. With its battery backup support, it can retain the time even when the main power is disconnected, making it suitable for clocks, reminders, counters, menu systems, and other projects that need stable time storage. The examples in this tutorial give you a clear starting point to set the time, read the clock, detect halted conditions, and build practical applications around this widely used RTC module.
Browse More Arduino Sensors Tutorials
Interface SHT21 Temperature and Humidity Sensor with Arduino | Display on Serial Monitor and I2C LCD
Arduino DS18B20 Temperature Sensor Tutorial: Single and Multiple Sensors with SSD1306 OLED
ADXL345 Arduino I2C Tutorial: Pinout, Wiring, Calibration, and Accelerometer Data Reading Explained
Interfacing BMP180 Sensor with Arduino: Measure Temperature, Pressure Altitude with LCD1602 I2C
Interface AHT20 Sensor with Arduino | Measure Temperature and Humidity with OLED Display
MPU6050 Arduino I2C Tutorial: Pinout, Wiring, Calibration, Raw Data, and Code Examples
Arduino BME280 Tutorial: Wiring, Pinout, Code and LCD1602 Display Output
Arduino DS1307 Project Download
Info
You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.
Arduino DS1307 FAQs
Yes, the DS3231 continues running using its onboard CR2032 battery, so the time remains accurate without external power.
The square-wave output must be disabled using rtc.writeSqwPinMode(DS3231_OFF); otherwise, the pin will not switch to alarm-interrupt mode.
Yes, I2C supports multiple devices. Just make sure each device has a unique I2C address, like the LCD1602 (0x27) and DS3231 (0x68).
This happens if you keep calling rtc.adjust() in your code. Set the time once, then comment out the line to prevent unwanted resets.
No, the alarm triggers once and the flag must be cleared with rtc.clearAlarm(1) or rtc.clearAlarm(2) before it can trigger again.








