Track Time with DS1307 RTC and Display on Arduino Uno with 16x2 LCD | Cirkit Designer Project

DS1307 RTC Digital Clock with Arduino UNO & 16x2 LCD | MakeMindz

DS1307 RTC Project

Track Time with DS1307 RTC & 16×2 LCD on Arduino UNO

Build a hardware real-time clock that keeps accurate time even through power failures — displaying live date and time on a 16×2 I2C LCD with manual Hour, Minute and Second adjustment buttons.

🔵 Beginner Friendly 🕐 DS1307 RTC / I2C 📟 16×2 LCD Display

01 — Bill of Materials

Components Required

All parts use the I2C bus (SDA/SCL), so the OLED and LCD share only two data wires with the Arduino.

🟦
Arduino UNO
ATmega328P
🕐
DS1307 RTC
I2C, CR2032 backup
📟
16×2 LCD (I2C)
PCF8574 backpack
🔘
Push Buttons ×3
Hour / Min / Sec
🪙
CR2032 Cell
RTC battery backup
🔌
Jumper Wires
Male-to-male

Here's what the output looks like on the 16×2 LCD:

2025/04/05      
14:32:07        

02 — Concept

How It Works

The DS1307 maintains time autonomously using a 32.768 kHz crystal and CR2032 battery backup. Every second, Arduino polls the RTC over I2C and updates the LCD display. Three buttons let you manually increment Hour, Minute and Second.

🔗 I2C Bus

Both DS1307 (address 0x68) and LCD backpack (0x27) share SDA/SCL on A4/A5.

⏱ Timing Loop

Uses millis() with a 1000 ms interval — no blocking delay() in the main loop.

🔘 Button Debounce

Each button read includes a 200 ms software debounce delay to prevent double-triggering on press.

🔋 Battery Backup

The CR2032 coin cell keeps the DS1307 running when Arduino has no power — time is preserved indefinitely.

03 — Visual Schematic

Circuit Diagram

Arduino UNO + DS1307 RTC + 16×2 I2C LCD + Push Buttons

ARDUINO UNO A4 SDA A5 SCL 5V GND D2 (HOUR) D3 (MIN) D4 (SEC) GND USB-B DS1307 RTC Real-Time Clock Module 32.768kHz CR2032 VCC GND SDA SCL 16×2 LCD (I2C) 2025/04/05 14:32:07 PCF8574 VCC GND SDA SCL HOUR H MINUTE M SECOND S Shared GND Wire Key SDA SCL 5V GND

 


04 — Pin Connections

Wiring Connections

DS1307 RTC Module → Arduino UNO

DS1307 PinArduino PinWireNote
VCC5VRedPower supply
GNDGNDBlackGround
SDAA4YellowI2C Data — address 0x68
SCLA5BlueI2C Clock

16×2 I2C LCD → Arduino UNO

LCD PinArduino PinWireNote
VCC5VRedShared 5V rail
GNDGNDBlackShared GND rail
SDAA4YellowShared I2C bus — address 0x27
SCLA5BlueShared I2C clock

Push Buttons → Arduino UNO

ButtonArduino PinWireNote
HOUR (one leg)D2PurpleINPUT_PULLUP, reads LOW on press
MINUTE (one leg)D3TealINPUT_PULLUP
SECOND (one leg)D4YellowINPUT_PULLUP
All buttons (other leg)GNDBlackNo external resistors needed

05 — Sketch

Full Arduino Code

Install RTClib (by Adafruit) and LiquidCrystal_I2C (by Frank de Brabander) via the Arduino IDE Library Manager before uploading.

Arduino C++ — DS1307 RTC Clock with LCD
/*
  DS1307 RTC Digital Clock — Arduino UNO + 16x2 I2C LCD
  MakeMindz.com | makemindz.com/2026/02/track-time-with-ds1307-rtc-and-display.html

  Libraries required:
    - RTClib by Adafruit
    - LiquidCrystal_I2C by Frank de Brabander
*/

#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>

// I2C devices: DS1307 @ 0x68, LCD @ 0x27
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Button pins (INPUT_PULLUP — LOW = pressed)
const int buttonHourPin   = 2;
const int buttonMinutePin = 3;
const int buttonSecondPin = 4;

unsigned long previousMillis = 0;
const long    interval       = 1000;  // 1 second display refresh

void setup() {
    // Optional: power the LCD via GPIO (used in Cirkit simulation)
    pinMode(12, OUTPUT); digitalWrite(12, LOW);
    pinMode(11, OUTPUT); digitalWrite(11, HIGH);

    Serial.begin(9600);

    // Init DS1307
    if (!rtc.begin()) {
        Serial.println("Couldn't find RTC");
        while (1);
    }
    if (!rtc.isrunning()) {
        Serial.println("RTC is NOT running!");
        // Set RTC to compile time — uncomment once, then re-comment:
        // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }

    // Init LCD
    lcd.init();
    lcd.backlight();
    lcd.clear();

    // Init buttons with internal pull-up
    pinMode(buttonHourPin,   INPUT_PULLUP);
    pinMode(buttonMinutePin, INPUT_PULLUP);
    pinMode(buttonSecondPin, INPUT_PULLUP);
}

void loop() {
    unsigned long currentMillis = millis();

    // ── HOUR button ──
    if (digitalRead(buttonHourPin) == LOW) {
        DateTime now = rtc.now();
        rtc.adjust(DateTime(now.year(), now.month(), now.day(),
                            now.hour() + 1, now.minute(), now.second()));
        updateDisplay(rtc.now());
        delay(200);  // debounce
    }

    // ── MINUTE button ──
    if (digitalRead(buttonMinutePin) == LOW) {
        DateTime now = rtc.now();
        rtc.adjust(DateTime(now.year(), now.month(), now.day(),
                            now.hour(), now.minute() + 1, now.second()));
        updateDisplay(rtc.now());
        delay(200);
    }

    // ── SECOND button ──
    if (digitalRead(buttonSecondPin) == LOW) {
        DateTime now = rtc.now();
        rtc.adjust(DateTime(now.year(), now.month(), now.day(),
                            now.hour(), now.minute(), now.second() + 1));
        updateDisplay(rtc.now());
        delay(200);
    }

    // ── Auto-refresh every 1 second ──
    if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        updateDisplay(rtc.now());
    }
}

// Display date (row 0) and time (row 1) on LCD
void updateDisplay(DateTime now) {
    // Row 0: YYYY/MM/DD
    lcd.setCursor(0, 0);
    lcd.print(now.year(),  DEC); lcd.print('/');
    lcd.print(now.month(), DEC); lcd.print('/');
    lcd.print(now.day(),   DEC);

    // Row 1: HH:MM:SS — clear first to avoid stale digits
    lcd.setCursor(0, 1);
    lcd.print("                ");  // 16 spaces
    lcd.setCursor(0, 1);
    lcd.print(now.hour(),   DEC); lcd.print(':');
    lcd.print(now.minute(), DEC); lcd.print(':');
    lcd.print(now.second(), DEC);
}

06 — Build Guide

Step-by-Step Instructions

1

Install the Libraries

Open Arduino IDE → Sketch → Include Library → Manage Libraries. Search and install RTClib (by Adafruit) and LiquidCrystal I2C (by Frank de Brabander). Wire.h comes built-in.

2

Wire the DS1307 RTC Module

Connect RTC VCC → 5V, GND → GND, SDA → A4, SCL → A5. Insert the CR2032 coin cell into the RTC module — this is what preserves time when power is off.

💡 DS1307 default I2C address is 0x68 — no configuration needed.
3

Wire the 16×2 I2C LCD

Connect LCD VCC → 5V, GND → GND, SDA → A4, SCL → A5 — the same two wires as the RTC. Both devices coexist on the I2C bus with different addresses.

⚠️ If your LCD shows nothing or garbled text, adjust the small blue contrast potentiometer on the PCF8574 backpack. Also try address 0x3F instead of 0x27.
4

Connect the Three Adjustment Buttons

Wire one leg of the Hour button to D2, Minute to D3, Second to D4. Connect all other legs to GND. No resistors needed thanks to INPUT_PULLUP.

5

Set the Initial Time

In the code, find the commented line // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); — uncomment it, upload, then immediately re-comment it and upload again. This sets the RTC to your PC's compile time without resetting on every reboot.

🕐 Once set, the CR2032 battery keeps time accurate for years — even without Arduino power.
6

Upload and Test

Select Board: Arduino UNO and the correct COM port. Upload the final sketch. The LCD shows today's date on row 1 and the live time on row 2 — updating every second. Press buttons to adjust.

🔍 Open Serial Monitor at 9600 baud to see RTC error messages if the display stays blank.

08 — Try It Online

Simulation Links

Cirkit Designer Simulation

Import the diagram.json above into Cirkit Designer to view the full schematic, paste the sketch, and run the simulation — no hardware needed.

▶ Open Cirkit Designer 📄 Original Post
🔌

Wokwi Online Simulator

Wokwi supports DS1307 RTC, 16×2 I2C LCD and push buttons. Paste the sketch directly into the editor and run it in your browser.

▶ Open Wokwi

10 — Keep Building

More MakeMindz Projects

Comments

try for free