HomeArduino TutorialsArduino SensorsDS1307 Arduino Tutorial: Interfacing RTC Module with LCD1602 I2C Display

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.

DS1307 Real-Time Clock (RTC) Interfacing with Arduino and LCD1602 I2C

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.

DS1307 TinyRTC module breakout board.

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.

Image showing pinout of DS1307 RTC module.

The tables below explain the function of each pin.

Pin NameFunctionDetails
SDAI2C Data LineTransfers data between Arduino and DS1307
SCLI2C Clock LineProvides clock signal for I2C communication
VCCPower InputConnect to 5V supply
GNDGroundCommon ground for the module
SQSquare Wave OutputOutputs 1Hz, 4kHz, 8kHz, 32kHz signal
DSData Pin for DS18B20Can be used to communicate with DS18B20, if connected
BATBackup BatteryHolds 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:

Image showing DS1307 RTC module, LCD1602 I2C module are connected to Arduino via the same I2C.

Here is the final wiring in tabular form for better clarity:

Arduino UNODS1307 RTCLCD1602 I2CPurpose
5VVCCVCCPower for both modules
GNDGNDGNDCommon ground
A4 (SDA)SDASDAShared I2C Data line
A5 (SCL)SCLSCLShared I2C Clock line

Summary of the Circuit

PointExplanation
Same I2C busBoth modules share SDA and SCL pins
No address conflictEach device has a unique I2C address
Backup BatteryDS1307 keeps time running even without Arduino power
Clean wiringOnly 4 wires per module needed
LCD DisplayShows 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:

  1. Open Arduino IDE
  2. Go to Sketch → Include Library → Manage Libraries
  3. In the search bar, type RTClib
  4. Install the library published by Adafruit
Install RTClib by Adafruit for the DS1307.

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:

  1. Open Arduino IDE.
  2. Go to Sketch → Include Library → Manage Libraries.
  3. Search for “LiquidCrystal_I2C”.
  4. Install the version by Frank de Brabander or Marco Schwartz.
Add the I2C LCD1602 liquidcrystal_I2C library to Arduino IDE.

Testing the Library Examples

After installing both libraries, it is a good idea to test the example codes.

  1. Open Arduino IDE
  2. Go to File → Examples → RTClib
  3. Run the ds1307 example
  4. Check the serial monitor to confirm the date and time readings

Next, test the LCD:

  1. Go to File → Examples → LiquidCrystal_I2C
  2. Upload the HelloWorld example
  3. 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:

FunctionDescription
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:

FunctionReturns
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:

  • % 12 converts 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 address 0x27, with a 16×2 display size.

3. Settings Section
#define AUTO_TIME_SET     1
#define MANUAL_TIME_SET   0

Only one method can be active:

  • AUTO_TIME_SET = 1 sets the RTC time from the computer’s compile time.
  • MANUAL_TIME_SET = 1 sets 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__)));
#endif

Sets RTC using the system’s compile date/time.

#if MANUAL_TIME_SET
  rtc.adjust(DateTime(manualYear, manualMonth, manualDate,
                      manualHour, manualMinute, manualSecond));
#endif

Sets 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.

gif showing the current time and date, fetched from the DS3231, are  printed on the LCD1602 I2C.

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.

Image showing the square wave output from DS1307, measured on the logic analyzer.

I have connected an LED to SQW pin, it will blink once every second. The gif below shows the LED blinking every second.

gif showing the current time on the LCD. The LED connected to SQW pin of DS1307 is blinking every 1 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 using readnvram().
  • 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.

Image showing the data read from the NVRam of the DS1307 is printed on the LCD display. Both DS1307 and LCD are connected using same I2C to the Arduino.

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

1 2

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

Subscribe
Notify of

0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments