Arduino Uno + RTC + HD44780 IIC/I2C problem with delay clock

Hello,

first i won’t to apologize for bad English grammar !

I made a simple controller based on the Arduino Uno through my modest knowledge of programming.

I include the following components:

  1. Arduino Uno R3;
  2. BH175OFVI;
  3. DS18B20;
  4. 8 Relay Board 220V/10A per channel;
  5. DS3231;
  6. 16x2 HD44780 Character LCD /w IIC/I2C Serial Interface Adapter Module;

I connected components by the attached scheme: diagram.jpg
I modify code of one popular controller for my needs: Aquatica.ino

I turn on the controller display to the correct time, but after the run for some time, the clock is delayed by a few minutes. When power is disconnected and reconnected, the clock is again correct.

Please direct me where to look for the problem and what is wrong.

Thank you in advanced for your HELP !

#include "RTClib.h"
#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <FastIO.h>
#include <I2CIO.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <DS1307RTC.h>
#include <OneWire.h>

#define BL 2
#define LL 3
#define RL 4
#define SK 5
#define AR 6
#define CD 7
#define FN 8
#define HT 9

// Liqiud Crystal LCD I2C
#define I2C_ADDR 0x3F
#define BACKLIGHT_PIN 3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

//Real Time Clock
RTC_DS1307 rtc;  //clock

// Dallas Temperature Sensors
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup() {
  lcd.begin (19, 2);
  sensors.begin();
  Wire.begin();
  rtc.begin();
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home (); // go home
  //  if (! rtc.isrunning()) {
  //    Serial.println("RTC is NOT running!");
  //    rtc.adjust(DateTime(__DATE__, __TIME__));  // Sets the RTC to the date & time this sketch was compiled
  //  }
  DateTime now = rtc.now();
  setTime(hour(), minute(), second(), day(), month(), year());
  setTime(now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());

  Alarm.alarmRepeat(19, 20, 0, BL_ON);
  Alarm.alarmRepeat(19, 21, 30, BL_OFF);

  Alarm.alarmRepeat(19, 22, 0, LL_ON);
  Alarm.alarmRepeat(19, 23, 0, LL_OFF);

  Alarm.alarmRepeat(19, 24, 0, RL_ON);
  Alarm.alarmRepeat(19, 25, 0, RL_OFF);

  Alarm.alarmRepeat(19, 26, 0, SK_ON);
  Alarm.alarmRepeat(19, 27, 0, SK_OFF);

  Alarm.alarmRepeat(19, 28, 0, AR_ON);
  Alarm.alarmRepeat(19, 29, 0, AR_OFF);

  Alarm.alarmRepeat(19, 30, 0, HT_ON);
  Alarm.alarmRepeat(19, 31, 0, HT_OFF);

  pinMode(BL, OUTPUT);
  pinMode(LL, OUTPUT);
  pinMode(RL, OUTPUT);
  pinMode(SK, OUTPUT);
  pinMode(AR, OUTPUT);
  pinMode(CD, OUTPUT);
  pinMode(FN, OUTPUT);
  pinMode(HT, OUTPUT);

  digitalWrite(BL, 1);
  digitalWrite(LL, 1);
  digitalWrite(RL, 1);
  digitalWrite(SK, 1);
  digitalWrite(AR, 1);
  digitalWrite(CD, 1);
  digitalWrite(FN, 1);
  digitalWrite(HT, 1);
}

void loop() {
  lcd.setCursor(0, 0);
  digitalClockDisplay();
  lcd.setCursor(11, 0);
  sensors.requestTemperatures();
  lcd.print(sensors.getTempCByIndex(0));
  lcd.home();
  if (sensors.getTempCByIndex(0) > 34.00)
  {
    digitalWrite(CD, 0);
  }
  else
  {
    digitalWrite(CD, 1);
  }
  Alarm.delay(10);
  delay(1000);
}
void digitalClockDisplay()
{
  printDigits(hour());
  lcd.print(":");
  printDigits(minute());
  lcd.print(":");
  printDigits(second());
}
void printDigits(int digits)
{
  if (digits < 10)
    lcd.print('0');
  lcd.print(digits);
}
void BL_ON() {
  digitalWrite(BL, 0);
}

void BL_OFF() {
  digitalWrite(BL, 1);
}

void LL_ON() {
  digitalWrite(LL, 0);
}

void LL_OFF() {
  digitalWrite(LL, 1);
}

void RL_ON() {
  digitalWrite(RL, 0);
}

void RL_OFF() {
  digitalWrite(RL, 1);
}

void SK_ON() {
  digitalWrite(SK, 0);
}

void SK_OFF() {
  digitalWrite(SK, 1);
}

void AR_ON() {
  digitalWrite(AR, 0);
}

void AR_OFF() {
  digitalWrite(AR, 1);
}

void HT_ON() {
  digitalWrite(HT, 0);
}

void HT_OFF() {
  digitalWrite(HT, 1);
}

Aquatica.ino (3.26 KB)

  DateTime now = rtc.now();
  setTime(hour(), minute(), second(), day(), month(), year());
  setTime(now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());

Can't make up your mind what time you want now to be? Better make up your mind.

  Alarm.delay(10);
  delay(1000);

You obviously don't care if the alarms happen on time. If you did, you would NOT be using delay().

void digitalClockDisplay()
{
  printDigits(hour());
  lcd.print(":");
  printDigits(minute());
  lcd.print(":");
  printDigits(second());
}

Where are hour(), minute(), and second() defined?

Dear PaulS,

thank you for your guidelines.

Can't make up your mind what time you want now to be? Better make up your mind.
I made a mistake and removed the second row.

setTime(now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());

You obviously don't care if the alarms happen on time. If you did, you would NOT be using delay().

In this case, if I remove the lines TimeAlarms stops and haven't action on time.

Where are hour(), minute(), and second() defined?

I do not understand what you mean by your question? This is the definition of the clock, which later recalled in the loop section.

digitalClockDisplay();

In this case, if I remove the lines TimeAlarms stops and haven't action on time.

You have (or had) calls to Alarm.delay() and delay(). You should ONLY have calls to Alarm.delay().

This is the definition of the clock

No, it is not. That is a call to a function.

I do not understand what you mean by your question?

Is that a statement or a question? You are calling functions that are implemented in the code you posted. Therefore, they must be implemented in some library. If is your responsibility to know which one.

PaulS:
You have (or had) calls to Alarm.delay() and delay(). You should ONLY have calls to Alarm.delay().
No, it is not. That is a call to a function.
Is that a statement or a question? You are calling functions that are implemented in the code you posted. Therefore, they must be implemented in some library. If is your responsibility to know which one.

PaulS,

I apologize if I have offended, that was not the goal.

On your recommendation I changed the code:

void loop() {
  lcd.setCursor(0, 0);
  digitalClockDisplay();
  lcd.setCursor(11, 0);
  sensors.requestTemperatures();
  lcd.print(sensors.getTempCByIndex(0));
  lcd.home();
  if (sensors.getTempCByIndex(0) > 34.00)
  {
    digitalWrite(CD, 0);
  }
  else
  {
    digitalWrite(CD, 1);
  }
  Alarm.delay(10);
  //delay(1000);
}
DateTime now = rtc.now();
  setTime(hour(), minute(), second(), day(), month(), year());
  //setTime(now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());

Really I do not understand what you mean by the last two questions. I wanted to build a function that displays a clock. I do not understand what should define. Perhaps I am not aware of what you say and therefore assume I can not understand.

I write finction, for clock with specific characters ":"

void digitalClockDisplay()
{
  printDigits(hour());
  lcd.print(":");
  printDigits(minute());
  lcd.print(":");
  printDigits(second());
}

I write finction, for clock with specific characters ":"

So, what is the problem?

The problem is that the clock behind with minutes. After I reboot to fix. I’m talking about the clock is displayed.

So, I think to find decision about my question:

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <TimeAlarms.h>
#define I2C_ADDR    0x3F
#define Rs_pin  0
#define Rw_pin  1
#define En_pin  2
#define BACKLIGHT_PIN  3
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
#define LED_OFF  1
#define LED_ON  0
#define Lights 2
#define Moon_lights 3
#define Heater 4
#define Cooler 5
#define Air 6
#define CO2 7
#define Skimmer 8
#define Free 9
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
void setup() {
  lcd.begin (16, 2);
  sensors.begin();
  Wire.begin();
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(LED_ON);
  Alarm.alarmRepeat(14, 0, 0, Lights_ON);
  Alarm.alarmRepeat(22, 0, 0, Lights_OFF);
  Alarm.alarmRepeat(21, 59, 0, Moon_lights_ON);
  Alarm.alarmRepeat(13, 59, 0, Moon_lights_OFF);
  //Alarm.alarmRepeat(0, 0, 0, Heater_ON);
  //Alarm.alarmRepeat(0, 0, 0, Heater_OFF);
  Alarm.alarmRepeat(14, 0, 0, Cooler_ON);
  Alarm.alarmRepeat(23, 0, 0, Cooler_OFF);
  Alarm.alarmRepeat(22, 0, 0, Air_ON);
  Alarm.alarmRepeat(11, 0, 0, Air_OFF);
  //Alarm.alarmRepeat(22, 0, 0, CO2_ON);
  //Alarm.alarmRepeat(11, 0, 0, CO2_OFF);
  Alarm.alarmRepeat(22, 0, 0, Skimmer_ON);
  Alarm.alarmRepeat(11, 10, 0, Skimmer_OFF);
  Alarm.alarmRepeat(22, 0, 0, Free_ON);
  Alarm.alarmRepeat(11, 10, 0, Free_OFF);
  pinMode(Lights, OUTPUT);
  pinMode(Moon_lights, OUTPUT);
  pinMode(Heater, OUTPUT);
  pinMode(Cooler, OUTPUT);
  pinMode(Air, OUTPUT);
  pinMode(CO2, OUTPUT);
  pinMode(Skimmer, OUTPUT);
  pinMode(Free, OUTPUT);
  digitalWrite(Lights, 1);
  digitalWrite(Moon_lights, 1);
  digitalWrite(Heater, 1);
  digitalWrite(Cooler, 1);
  digitalWrite(Air, 1);
  digitalWrite(CO2, 1);
  digitalWrite(Skimmer, 1);
  digitalWrite(Free, 1);
}
void loop() {
  tmElements_t tm;
  lcd.backlight();
  if (RTC.read(tm)) {
    lcd.setCursor(0, 0);
    print2digits(tm.Hour);
    lcd.print(':');
    print2digits(tm.Minute);
    lcd.print(':');
    print2digits(tm.Second);
    lcd.setCursor(12, 0);
    lcd.print(sensors.getTempCByIndex(0));
    lcd.setCursor(0, 1);
    lcd.print("DATE :");
    lcd.print(tm.Day);
    lcd.print('/');
    lcd.print(tm.Month);
    lcd.print('/');
    lcd.print(tmYearToCalendar(tm.Year));
    if (sensors.getTempCByIndex(0) > 26.00)
    {
      digitalWrite(Heater, 0);
    }
    else
    {
      digitalWrite(Heater, 1);
    }
  }
  delay(990);
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    lcd.print('0');
  }
  lcd.print(number);
}
void Lights_ON() {
  digitalWrite(Lights, 0);
}

void Lights_OFF() {
  digitalWrite(Lights, 1);
}

void Moon_lights_ON() {
  digitalWrite(Moon_lights, 0);
}

void Moon_lights_OFF() {
  digitalWrite(Moon_lights, 1);
}

//void Heater_ON() {
//  digitalWrite(Heater, 0);
//}
//
//void Heater_OFF() {
//  digitalWrite(Heater, 1);
//}

void Cooler_ON() {
  digitalWrite(Cooler, 0);
}

void Cooler_OFF() {
  digitalWrite(Cooler, 1);
}

void Air_ON() {
  digitalWrite(Air, 0);
}

void Air_OFF() {
  digitalWrite(Air, 1);
}

//void CO2_ON() {
//  digitalWrite(Air, 0);
//}
//
//void CO2_OFF() {
//  digitalWrite(Air, 1);
//}

void Skimmer_ON() {
  digitalWrite(Free, 0);
}

void Skimmer_OFF() {
  digitalWrite(Free, 1);
}
void Free_ON() {
  digitalWrite(Free, 0);
}

void Free_OFF() {
  digitalWrite(Free, 1);
}

Now, timealarms, do not work. I can’t understand why ?

Add correct scheme

Arduino I2C bus for both RTC and 16x2 LCD display.png

Now, timealarms, do not work. I can't understand why ?

You never set the time from the RTC to the internal arduino clock which is controlling the time alarms.

Please look at the example in the Time library "TimeRTC" which shows how best to manage using an RTC with the time and time alarms libraries. You will use the setSyncProvider() function to keep the Arduino clock synchronized with the RTC, and within your program, all calls for time will use the time and time library syntax.

cattledog,

thank you for your help !
I looked at the code again and all libraries. I read again available topics and I came to the conclusion that my approach is totally wrong. I guess that I use the library “Timealarms” as an easier option, but I was wrong. Apply the new code if anyone faced with a similar problem, so if I can call it. Ignorance leads to wrong decisions :slight_smile:

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#define I2C_ADDR    0x3F
#define Rs_pin  0
#define Rw_pin  1
#define En_pin  2
#define BACKLIGHT_PIN  3
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
#define LED_OFF  1
#define LED_ON  0
#define Lights 2
#define Moon_lights 3
#define Heater 4
#define Cooler 5
#define Air 6
#define CO2 7
#define Skimmer 8
#define Free 9
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
void setup() {
  lcd.begin (16, 2);
  sensors.begin();
  Wire.begin();
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(LED_ON);
  pinMode(Lights, OUTPUT);
  pinMode(Moon_lights, OUTPUT);
  pinMode(Heater, OUTPUT);
  pinMode(Cooler, OUTPUT);
  pinMode(Air, OUTPUT);
  pinMode(CO2, OUTPUT);
  pinMode(Skimmer, OUTPUT);
  pinMode(Free, OUTPUT);
  digitalWrite(Lights, 1);
  digitalWrite(Moon_lights, 1);
  digitalWrite(Heater, 1);
  digitalWrite(Cooler, 1);
  digitalWrite(Air, 1);
  digitalWrite(CO2, 1);
  digitalWrite(Skimmer, 1);
  digitalWrite(Free, 1);
}
void loop() {
  tmElements_t tm;
  lcd.backlight();
  if (RTC.read(tm)) {
    lcd.setCursor(0, 0);
    print2digits(tm.Hour);
    lcd.print(':');
    print2digits(tm.Minute);
    lcd.print(':');
    print2digits(tm.Second);
    lcd.setCursor(12, 0);
    lcd.print(sensors.getTempCByIndex(0));
    lcd.setCursor(0, 1);
    lcd.print("DATE :");
    lcd.print(tm.Day);
    lcd.print('/');
    lcd.print(tm.Month);
    lcd.print('/');
    lcd.print(tmYearToCalendar(tm.Year));

    // Lights ON TIMER
    if ((tm.Hour == 18) && (tm.Minute == 35) && (tm.Second == 10))
    {
      digitalWrite(Lights, 0);
    }
    // Lights OFF TIMER
    if ((tm.Hour == 18) && (tm.Minute == 37) && (tm.Second == 0))
    {
      digitalWrite(Lights, 1);
    }

    // Moon lights ON TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Moon_lights, 0);
    }
    // Moon lights OFF TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Moon_lights, 1);
    }

    // Heater ON/OFF function by temperature sensor
    if (sensors.getTempCByIndex(0) < 26.00)
    {
      digitalWrite(Heater, 0);
    }
    else
    {
      digitalWrite(Heater, 1);
    }

    // Cooler ON/OFF function by temperature sensor
    if (sensors.getTempCByIndex(0) > 26.00)
    {
      digitalWrite(Cooler, 0);
    }
    else
    {
      digitalWrite(Cooler, 1);
    }

    // Air ON TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Air, 0);
    }
    // Air OFF TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Air, 1);
    }

    // CO2 ON TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(CO2, 0);
    }
    // CO2 OFF TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(CO2, 1);
    }

    // Skimmer ON TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Skimmer, 0);
    }
    // Skimmer OFF TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Skimmer, 1);
    }

    // Free ON TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Free, 0);
    }
    // Free OFF TIMER
    if ((tm.Hour == 10) && (tm.Minute == 0) && (tm.Second == 0))
    {
      digitalWrite(Free, 1);
    }

  }
  delay(990);
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    lcd.print('0');
  }
  lcd.print(number);
}

New changes in code.
So i think that is final version of timers.

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
#include <OneWire.h>

#define I2C_ADDR    0x3F
#define Rs_pin  0
#define Rw_pin  1
#define En_pin  2
#define BACKLIGHT_PIN  3
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
#define LED_OFF  1
#define LED_ON  0
#define Lights 2
#define Moon_lights 3
#define Heater 4
#define Cooler 5
#define Air 6
#define CO2 7
#define Skimmer 8
#define Free 9
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
void setup() {
  lcd.begin (16, 2);
  sensors.begin();
  Wire.begin();
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(LED_ON);
  pinMode(Lights, OUTPUT);
  pinMode(Moon_lights, OUTPUT);
  pinMode(Heater, OUTPUT);
  pinMode(Cooler, OUTPUT);
  pinMode(Air, OUTPUT);
  pinMode(CO2, OUTPUT);
  pinMode(Skimmer, OUTPUT);
  pinMode(Free, OUTPUT);
  digitalWrite(Lights, 1);
  digitalWrite(Moon_lights, 1);
  digitalWrite(Heater, 1);
  digitalWrite(Cooler, 1);
  digitalWrite(Air, 1);
  digitalWrite(CO2, 1);
  digitalWrite(Skimmer, 1);
  digitalWrite(Free, 1);
}
void loop() {
  tmElements_t tm;
  sensors.requestTemperatures();
  lcd.backlight();
  lcd.setCursor(9, 0);
  lcd.print(sensors.getTempCByIndex(0));
  lcd.print(" C");
  if (RTC.read(tm)) {
    lcd.setCursor(0, 0);
    print2digits(tm.Hour);
    lcd.print(':');
    print2digits(tm.Minute);
    lcd.print(':');
    print2digits(tm.Second);
    lcd.setCursor(0, 1);
    lcd.print("DATE:  ");
    lcd.print(tm.Day);
    lcd.print('/');
    lcd.print(tm.Month);
    lcd.print('/');
    lcd.print(tmYearToCalendar(tm.Year));

    // Lights ON/OFF TIMER
    if ((tm.Hour >= 15) && (tm.Hour <= 22))
    {
      digitalWrite(Lights, 0);
    }

    // Moon lights ON/OFF TIMER
    if (tm.Hour >= 23)
    {
      digitalWrite(Moon_lights, 0);
    }
    else if (tm.Hour < 15)
    {
      digitalWrite(Moon_lights, 0);
    }

    // Heater ON/OFF function by temperature sensor
    if (sensors.getTempCByIndex(0) < 26.01)
    {
      digitalWrite(Heater, 0);
    }

    // Cooler ON/OFF function by temperature sensor
    if (sensors.getTempCByIndex(0) > 25.99)
    {
      digitalWrite(Cooler, 0);
    }

    // Air ON/OFF TIMER
    if (tm.Hour >= 23)
    {
      digitalWrite(Moon_lights, 0);
    }
    else if (tm.Hour < 13)
    {
      digitalWrite(Moon_lights, 0);
    }

    // CO2 ON TIMER
    if (tm.Hour >= 23)
    {
      digitalWrite(Moon_lights, 0);
    }
    else if (tm.Hour < 13)
    {
      digitalWrite(Moon_lights, 0);
    }

    // Skimmer ON TIMER
    if (tm.Hour >= 23)
    {
      digitalWrite(Moon_lights, 0);
    }
    else if (tm.Hour < 15)
    {
      digitalWrite(Moon_lights, 0);
    }

    // Free ON TIMER
    if (tm.Hour >= 23)
    {
      digitalWrite(Moon_lights, 0);
    }
    else if (tm.Hour < 15)
    {
      digitalWrite(Moon_lights, 0);
    }

  }
  delay(990);
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    lcd.print('0');
  }
  lcd.print(number);
}