# Add I2C LCD Display to my Digital Clock Using a DS1302 Project

**URL:** <https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645>\
**Category:** General Guidance\
**Created:** [September 27, 2024, 9:13am UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645 "2024-09-27T09:13:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![farhanamiranda](https://avatars.discourse-cdn.com/v4/letter/f/8dc957/32.png) [@farhanamiranda](https://forum.arduino.cc/u/farhanamiranda)\
**Post date:** [September 27, 2024, 9:13am UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/1 "2024-09-27T09:13:10Z")

</div>

Hello everyone,  
I need help on adding a LCD I2C Display to my project and display only the Time. So here is **the coding without adding a LCD I2C code yet**.

Components that i'm using:-

- DS1302 Real Time Clock Module RTC.

- 2x16 LCD I2C

- Arduino UNO

```arduino
#include <ThreeWire.h>
#include <RtcDS1302.h>

const int IO = 4; // DAT
const int SCLK = 5; // CLK
const int CE = 2; // RST

ThreeWire myWire(4, 5, 2); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

void setup() {
  Serial.begin(9600);

  Serial.print("compiled: ");
  Serial.print( __DATE__ );
  Serial.println( __TIME__ );

  Rtc.Begin();

  RtcDateTime compiled = RtcDateTime( __DATE__ , __TIME__ );
  printDateTime(compiled);
  Serial.println();

  if (!Rtc.IsDateTimeValid()) {
    // Common Causes:
    // 1) first time you ran and the device wasn't running yet
    // 2) the battery on the device is low or even missing

    Serial.println("RTC lost confidence in the DateTime!");
    Rtc.SetDateTime(compiled);
  }

  if (Rtc.GetIsWriteProtected()) {
    Serial.println("RTC was write protected, enabling writing now");
    Rtc.SetIsWriteProtected(false);
  }

  if (!Rtc.GetIsRunning()) {
    Serial.println("RTC was not actively running, starting now");
    Rtc.SetIsRunning(true);
  }

  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled) {
    Serial.println("RTC is older than compile time! (Updating DateTime)");
    Rtc.SetDateTime(compiled);
  } else if (now > compiled) {
    Serial.println("RTC is newer than compile time. (this is expected)");
  } else if (now == compiled) {
    Serial.println("RTC is the same as compile time! (not expected but all is fine)");
  }
}

void loop() {
  RtcDateTime now = Rtc.GetDateTime();

  printDateTime(now);
  Serial.println();

  if (!now.IsValid()) {
    // Common Causes:
    // 1) the battery on the device is low or even missing and the power line was disconnected
    Serial.println("RTC lost confidence in the DateTime!");
  }

  delay(5000); // five seconds
}

#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime& dt) {
  char datestring[20];

  snprintf_P(datestring,
             countof(datestring),
             PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
             dt.Month(),
             dt.Day(),
             dt.Year(),
             dt.Hour(),
             dt.Minute(),
             dt.Second());
  Serial.print(datestring);
}

```

Here's the pic of the setup:-

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/e/8/3/e838daa8acc4cb355b32ec70db9f0a3bf7905d9f.jpeg)

---

<div class="post-metadata">

**Author:** ![kolaha](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/kolaha/32/966427_2.png) [@kolaha](https://forum.arduino.cc/u/kolaha)\
**Post date:** [September 27, 2024, 9:49am UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/2 "2024-09-27T09:49:22Z")

</div>

follow the forum rules: edit your post and put entire code between CODE tags.  
after that, place pictures of your setup, diagram, schematic. more info is better then less.  
say when done, i will take a look

---

<div class="post-metadata">

**Author:** ![gilshultz](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gilshultz](https://forum.arduino.cc/u/gilshultz)\
**Post date:** [September 27, 2024, 4:12pm UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/3 "2024-09-27T16:12:16Z")

</div>

> [@farhanamiranda](#):
>
> adding a LCD I2C Display to my project

1. **Provide Clear Documentation:** Since we can’t see your project, **share an annotated schematic** (best) or a clear drawing of your setup. Pictures are welcome, but avoid using Fritzing diagrams as they are wiring diagrams, not schematics, and are not ideal for troubleshooting.
2. **Include Technical Details:** If there is specific hardware involved, **include links to technical information**. There are often many versions of similar components, so precise details are essential.
3. **Reference Resources:** For additional help, check out useful links and tutorials: [Useful Links on Arduino Forum](https://forum.arduino.cc/t/useful-links-check-here-for-reference-posts-tutorials/370268).
4. **Read and follow the forum guidelines** When posting your code and schematic, please review the forum guidelines and use code tags to ensure clarity.

---

<div class="post-metadata">

**Author:** ![bluejets](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bluejets/32/1013044_2.png) [@bluejets](https://forum.arduino.cc/u/bluejets)\
**Post date:** [September 28, 2024, 3:08am UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/4 "2024-09-28T03:08:01Z")

</div>

Better to use DS3231........

---

<div class="post-metadata">

**Author:** ![farhanamiranda](https://avatars.discourse-cdn.com/v4/letter/f/8dc957/32.png) [@farhanamiranda](https://forum.arduino.cc/u/farhanamiranda)\
**Post date:** [September 28, 2024, 1:54pm UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/5 "2024-09-28T13:54:01Z")

</div>

TQ for your time sir. I already edit my post.

---

<div class="post-metadata">

**Author:** ![gilshultz](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gilshultz](https://forum.arduino.cc/u/gilshultz)\
**Post date:** [September 28, 2024, 3:11pm UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/6 "2024-09-28T15:11:29Z")

</div>

> [@farhanamiranda](#):
>
> I already edit my post.

I edited my answer, note the bold print. Your photo is not clear but it appears things are not connected correctly, you are using to many pins on the Arduino.

> [@farhanamiranda](#):
>
> - CLK/SCLK --\> 5
> - DAT/IO --\> 4
> - RST/CE --\> 2
> - VCC --\> 2.0v - 5.5v
> - GND --\> GND

Put it on a proper schematic No idea of which end is which.  
What did not work, the display is lit up. Post the links to the technical information on the hardware I do not have anything that looks like what I assume is the clock module.

Your screen shot is useless, best post it as requested by @kolaha

---

<div class="post-metadata">

**Author:** ![kolaha](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/kolaha/32/966427_2.png) [@kolaha](https://forum.arduino.cc/u/kolaha)\
**Post date:** [September 28, 2024, 3:29pm UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/7 "2024-09-28T15:29:58Z")

</div>

```arduino
#include <ThreeWire.h>
#include <RtcDS1302.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // address may be 0x3F

// determine the size of an array dynamically
#define countof(a) (sizeof(a) / sizeof(a[0]))

// RtcDateTime uses Y2K as OriginYear, while time_t uses Epoch 1970 as OriginYear.
// This is the difference between years 2000 and 1970 in seconds.
#define UNIX_OFFSET 946684800

const int RST_PIN = 2; // Chip Enable
const int IO_PIN = 4; // Input/Output
const int SCLK_PIN = 5; // Serial Clock

ThreeWire myWire(IO_PIN, SCLK_PIN, RST_PIN);
RtcDS1302<ThreeWire> Rtc(myWire);

// 30 chars is max, RAM is 31 Bytes, last char is null.
// Will be used to store the next alarm date+time.
const char data[] = "";

//Is Eastern Daylight Savings Time?
bool isEDT = false;

// Set the current date and time for RTC based on compile time.
// Calculate the next alarm date.
void setup ()
{
  Serial.begin(9600);
  lcd.init(); // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();

  // __DATE__ is a preprocessor macro that expands to current date (at compile time)
  // in the form mmm dd yyyy (e.g. "Jan 14 2012"), as a string.
  const char* nowDate = __DATE__ ;
  const char* nowTime = __TIME__ ;

  Rtc.Begin();
  runRtcChecks();

  // Set the date and time. This only needs to be done once if there is a battery backup
  //RtcDateTime compiled = RtcDateTime(nowDate, nowTime);
  //Rtc.SetDateTime(compiled);

  RtcDateTime now = Rtc.GetDateTime();

  // Eastern Time Zone (Toronto, New York, Detroit)
  // Daylight Saving Time is from Second Sunday in March after 2AM
  // until First Sunday in November until 2AM
  isEDT = isDaylightSavingTime(now);

  storeAlarmInMemory(now);
}

// Print current time every 5 seconds.
// If current time passed the alarm time, execute Alarm and set the next alarm's date+time.
void loop ()
{
  RtcDateTime now = Rtc.GetDateTime();
  RtcDateTime nextAlarm = readAlarmFromMemory();

  if (!now.IsValid())
  {
    // Common Causes:
    // 1) the battery on the device is low or even missing and the power line was disconnected
    Serial.println(F("RTC lost confidence in the DateTime!"));
  }
  else
  {
    // Adjust for DaylightSavingTime/Standard Time, Eastern Time Zone
    if (now.Month() == 3 && !isEDT && isDaylightSavingTime(now))
    {
      // from EST to EDT (+ 1 hour)
      now += 3600;
      Rtc.SetDateTime(now);

      nextAlarm += 3600;
      storeAlarmInMemory(nextAlarm);

      isEDT = true;
    }
    else if (now.Month() == 11 && isEDT && !isDaylightSavingTime(now))
    {
      // from EDT to EST (- 1 hour)
      now -= 3600;
      Rtc.SetDateTime(now);

      nextAlarm -= 3600;
      storeAlarmInMemory(nextAlarm);

      isEDT = false;
    }

    // debug

    lcd.setCursor(0, 1);
    // execute alarm
    if (now >= nextAlarm) {
      Serial.println("!!!! ALARM !!!");
      storeAlarmInMemory(nextAlarm);
      lcd.print("!!!! ALARM !!!");
    } else {
      Serial.print(F("Next Alarm: "));
      printDateTime(nextAlarm);
    }

    // debug
    Serial.print(F("Time now: "));
    lcd.setCursor(0, 0);
    printDateTime(now);
  }

  delay(5000);
}

// Print date+time in a 12-hour AM/PM format.
void printDateTime(const RtcDateTime& dt)
{
  char datestring[30];

  bool isPM = (dt.Hour() > 12);
  // read the format string from the Flash memory
  snprintf_P(datestring,
             countof(datestring),
             // PSTR macro = pointer to a string
             // creating a PROGMEM array and returning its address
             PSTR("%02u %s %04u %02u:%02u:%02u %s %s %s"),
             dt.Day(),
             monthShortString(dt.Month()),
             dt.Year(),
             //Sutract 12, Exception: 12 AM = 00 in 24 hrs
             isPM ? dt.Hour() - 12 : (dt.Hour() == 0 ? 12 : dt.Hour()),
             dt.Minute(),
             dt.Second(),
             isPM ? "PM" : "AM",
             "+",
             isEDT ? "EDT" : "EST"); // Eastern Daylight Time/Eastern Standard Time
  Serial.println(datestring);

  snprintf_P(datestring,
             countof(datestring),
             // PSTR macro = pointer to a string
             // creating a PROGMEM array and returning its address
             PSTR("%02u%s%02u%s%02u:%02u:%02u"),
             dt.Day(),
             monthShortString(dt.Month()),
             dt.Year() % 100,
             isPM ? "P" : "A",
             //Sutract 12, Exception: 12 AM = 00 in 24 hrs
             isPM ? dt.Hour() - 12 : (dt.Hour() == 0 ? 12 : dt.Hour()),
             dt.Minute(),
             dt.Second()
            ); // Eastern Daylight Time/Eastern Standard Time
  lcd.print(datestring);
}

// Initialize chip by turning off write protection and clearing the clock halt flag.
void runRtcChecks()
{
  if (Rtc.GetIsWriteProtected())
  {
    Serial.println("RTC was write protected, enabling writing now");
    Rtc.SetIsWriteProtected(false);
  }

  if (!Rtc.GetIsRunning())
  {
    Serial.println("RTC was not actively running, starting now");
    Rtc.SetIsRunning(true);
  }
}

// Calculate the next alarm's date and store in memory.
void storeAlarmInMemory(RtcDateTime lastAlarm)
{
  // Calculate next alarm date
  // by rounding off to the last minute
  RtcDateTime nextAlarm = RtcDateTime(lastAlarm.Year(), lastAlarm.Month(), lastAlarm.Day(), lastAlarm.Hour(), lastAlarm.Minute(), 0);
  // then adding +1 min
  nextAlarm = RtcDateTime(nextAlarm.Epoch64Time() - UNIX_OFFSET + 60);
  char datestring[28];

  // read the format string from the Flash memory
  snprintf_P(datestring,
             countof(datestring),
             // PSTR macro = pointer to a string
             // creating a PROGMEM array and returning its address
             PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
             nextAlarm.Day(),
             nextAlarm.Month(),
             nextAlarm.Year(),
             nextAlarm.Hour(),
             nextAlarm.Minute(),
             nextAlarm.Second());

  // Store next alarm in memory on the RTC
  uint8_t _count = sizeof(datestring);
  uint8_t written = Rtc.SetMemory((const uint8_t*)datestring, _count); // this includes a null terminator for the string
  if (written != _count)
  {
    Serial.print("something didn't match, count = ");
    Serial.print(_count, DEC);
    Serial.print(", written = ");
    Serial.print(written, DEC);
    Serial.println();
  }
}

RtcDateTime readAlarmFromMemory() {
  // read data
  uint8_t buff[31];
  char buffy[31];

  const uint8_t count = sizeof(buff);
  // get our data
  uint8_t gotten = Rtc.GetMemory(buff, count);

  if (gotten != count)
  {
    Serial.print("something didn't match, count = ");
    Serial.print(count, DEC);
    Serial.print(", gotten = ");
    Serial.print(gotten, DEC);
    Serial.println();
  }

  // print the string, but terminate if we get a null
  for (uint8_t ch = 0; ch < gotten && buff[ch]; ch++)
  {
    buffy[ch] = buff[ch];
  }

  uint16_t day, month, year, hour, minute, second;
  sscanf(buffy, "%02u/%02u/%04u %02u:%02u:%02u",
         &day,
         &month,
         &year,
         &hour,
         &minute,
         &second);

  RtcDateTime nextAlarm = RtcDateTime(year, month, day, hour, minute, second);
  return nextAlarm;
}

const char* monthShortString(uint8_t mth) {

  // Initialize array of pointer
  const char *months[13] = { "Nil", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  return months[mth];
}

// Adapted from https://github.com/SensorsIot/NTPtimeESP/blob/master/NTPtimeESP.cpp
boolean isDaylightSavingTime(RtcDateTime _tempDateTime) {
  // DST begins on second Sunday of March and ends on first Sunday of November.
  // Time change occurs at 2AM locally
  if (_tempDateTime.Month() < 3 || _tempDateTime.Month() > 11) return false; //January, february, and december are out.
  if (_tempDateTime.Month() > 3 && _tempDateTime.Month() < 11) return true; //April to October are in
  int previousSunday = _tempDateTime.Day() - (_tempDateTime.DayOfWeek());

  // -------------------- March ---------------------------------------
  //In march, we are DST if our previous Sunday was = to or after the 8th.
  if (_tempDateTime.Month() == 3 ) { // in march, if previous Sunday is after the 8th, is DST
    // unless Sunday and hour < 2am
    if ( previousSunday >= 8 ) {
      // return true if day > 14 or (dow == 0 and hour >= 2)
      return ((_tempDateTime.Day() > 14) ||
              ((_tempDateTime.DayOfWeek() == 0 && _tempDateTime.Hour() >= 2) || _tempDateTime.DayOfWeek() > 0));
    }
    else
    {
      // previousSunday has to be < 8 to get here
      return false;
    }
  }

  // ------------------------------- November -------------------------------
  // gets here only if month = November
  //In november we must be before the first Sunday to be dst.
  //That means the previous Sunday must be before the 2nd.
  if (previousSunday < 1)
  {
    // is not true for Sunday after 2am or any day after 1st Sunday any time
    return ((_tempDateTime.DayOfWeek() == 0 && _tempDateTime.Hour() < 2) || (_tempDateTime.DayOfWeek() > 0));
  }
  else
  {
    // return false unless after first wk and dow = Sunday and hour < 2
    return (_tempDateTime.Day() < 8 && _tempDateTime.DayOfWeek() == 0 && _tempDateTime.Hour() < 2);
  }
}

```

as you already know, DS3231 is better because it is a bit more precise and uses I2C, so you can connect an I2C LCD to the same pins, sometimes directly on the RTC module.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [March 27, 2025, 3:30pm UTC](https://forum.arduino.cc/t/add-i2c-lcd-display-to-my-digital-clock-using-a-ds1302-project/1305645/8 "2025-03-27T15:30:27Z")

</div>

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
