Code:Real time clock - LED should light up at certain time

Hi!

So I'm having an Arduino mega2560, RTC DS3231, LCD (16X2) connected via I2C bus.
I want to do that the LED would light up, for example for 1 min at certain time each day.
However, I wrote the code but it is obvious that sth is wrong. The LED doesn't want to light up at the desired time. I'm asking for the advices. Thanks.

#include <DS3231.h> //RTC
#include <Wire.h> //OBA
#include <LCD.h> //LCD
#include <LiquidCrystal_I2C.h> //LCD

#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#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

int n = 1;

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//RTC

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;


  void setup() {

 // LED IS ON I/O 12
  pinMode (12, OUTPUT);

// Start the I2C interface
     Wire.begin();
     lcd.begin (16,2);
     // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();                   // go home



// Start the serial interface
Serial.begin(9600);
}
void ReadDS3231()
{
 int second,minute,hour,date,month,year,temperature;
 second=Clock.getSecond();
 minute=Clock.getMinute();
 hour=Clock.getHour(h12, PM);
 date=Clock.getDate();
 month=Clock.getMonth(Century);
 year=Clock.getYear();

 temperature=Clock.getTemperature();



 lcd.setCursor ( 0, 0 ); // kolona 0, linija 1
 lcd.print(date, DEC);
 
 lcd.setCursor ( 2, 0 ); 
 lcd.print('.'); 
 
 lcd.setCursor ( 3, 0 );
 lcd.print(month, DEC);
 
 lcd.setCursor ( 5, 0 ); 
 lcd.print('.');

 lcd.setCursor ( 6, 0 );
 lcd.print("20");
 
 lcd.setCursor ( 8, 0 );
 lcd.print(year, DEC);
 
 lcd.setCursor ( 0, 1 );
 lcd.print(second, DEC);
 
 lcd.setCursor ( 2, 1 );
 lcd.print(':');
 
 lcd.setCursor ( 3, 1 );
 lcd.print(minute, DEC);
 
 lcd.setCursor ( 5, 1 );
 lcd.print(':');
 
 lcd.setCursor ( 6, 1 );
 lcd.print(hour, DEC);

 lcd.setCursor ( 11, 1 );
 lcd.print("T=");

 lcd.setCursor ( 13, 1 );
 lcd.print(temperature);

  lcd.setCursor ( 15, 1 );
  lcd.print("C");   
}

// CODE TO LIGHT UP THE LED
    void loop() {
      ReadDS3231();delay(1000);
      if (hour==12){
        digitalWrite(12, HIGH);
       
      }
      }

Is the clock displaying the correct time on the LCD after each read?

Does the LEd light up if you put its digitalWrite in setup() after you set it as output?

First you have declared "hour" as a global variable, then you declare "hour" to be a local variable in void ReadDS3231(). Also both are 2 different data types. Which do you need?

Try this as your loop and look in the serial monitor to see what it prints:

void loop() {
      ReadDS3231();delay(1000);
      Serial.println(hour);
      if (hour==12){
        digitalWrite(12, HIGH);
       }
      }

It might help you see the problem.

JimboZA:
Is the clock displaying the correct time on the LCD after each read?

Does the LEd light up if you put its digitalWrite in setup() after you set it as output?

Yes, the LCD is displaying correct time.

elac:
First you have declared "hour" as a global variable, then you declare "hour" to be a local variable in void ReadDS3231(). Also both are 2 different data types. Which do you need?

Try this as your loop and look in the serial monitor to see what it prints:

void loop() {

ReadDS3231();delay(1000);
      Serial.println(hour);
      if (hour==12){
        digitalWrite(12, HIGH);
      }
      }



It might help you see the problem.

Ok, I found out that if the code:

Serial.println(second);
 if (second < 30) {
        digitalWrite (11, HIGH);
        }
      if (second  > 30) {
        digitalWrite(11, LOW);
        }

is in the void setup, it works. But if it is in the void loop, it doesn't work.
In the former case Serial monitor prints correct number, in the latter just #0.
The same is with the LED.
Any idea why?

You need to have your variables global if you want the ability to pass/change the variables from function to function.
Or use local variables if only that function needs them.
Also, have all the work done in your ReadDS3231 function. Just use loop to call functions and time events.
Like so for global variables:

#include <DS3231.h> //RTC
#include <Wire.h> //OBA
#include <LCD.h> //LCD
#include <LiquidCrystal_I2C.h> //LCD

#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#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

int n = 1;

LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

//RTC
DS3231 Clock;
bool Century = false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
////////////////////////////////////////////////////////////
//These are now global and can be seen/used/changed by any function you want
int second, minute, hour, date, month, year, temperature;
///////////////////////////////////////////////////////////

void setup() {
  // LED IS ON I/O 12
  pinMode (12, OUTPUT);
  digitalWrite(12, LOW);;
  // Start the I2C interface
  Wire.begin();
  lcd.begin (16, 2);
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();                   // go home

  // Start the serial interface
  Serial.begin(9600);
}
// CODE TO CHECK TIME AND LIGHT UP THE LED
void ReadDS3231()
{

  second = Clock.getSecond();
  minute = Clock.getMinute();
  hour = Clock.getHour(h12, PM);
  date = Clock.getDate();
  month = Clock.getMonth(Century);
  year = Clock.getYear();

  temperature = Clock.getTemperature();
  /////////////////////////////////////////////
  // Code from loop moved here
  Serial.println(hour);
  if (hour == 12) {
    digitalWrite(12, HIGH);
  }
  else
  {
    digitalWrite(12, LOW);
  }
  ///////////////////////////////////////
  lcd.setCursor ( 0, 0 ); // kolona 0, linija 1
  lcd.print(date, DEC);

  lcd.setCursor ( 2, 0 );
  lcd.print('.');

  lcd.setCursor ( 3, 0 );
  lcd.print(month, DEC);

  lcd.setCursor ( 5, 0 );
  lcd.print('.');

  lcd.setCursor ( 6, 0 );
  lcd.print("20");

  lcd.setCursor ( 8, 0 );
  lcd.print(year, DEC);

  lcd.setCursor ( 0, 1 );
  lcd.print(second, DEC);

  lcd.setCursor ( 2, 1 );
  lcd.print(':');

  lcd.setCursor ( 3, 1 );
  lcd.print(minute, DEC);

  lcd.setCursor ( 5, 1 );
  lcd.print(':');

  lcd.setCursor ( 6, 1 );
  lcd.print(hour, DEC);

  lcd.setCursor ( 11, 1 );
  lcd.print("T=");

  lcd.setCursor ( 13, 1 );
  lcd.print(temperature);

  lcd.setCursor ( 15, 1 );
  lcd.print("C");
}

void loop() {
  ReadDS3231();
  delay(1000);
}

And for local variables:

#include <DS3231.h> //RTC
#include <Wire.h> //OBA
#include <LCD.h> //LCD
#include <LiquidCrystal_I2C.h> //LCD

#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#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

int n = 1;

LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

//RTC
DS3231 Clock;
bool Century = false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;

void setup() {
  // LED IS ON I/O 12
  pinMode (12, OUTPUT);
  digitalWrite(12, LOW);
  // Start the I2C interface
  Wire.begin();
  lcd.begin (16, 2);
  // Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();                   // go home

  // Start the serial interface
  Serial.begin(9600);
}
// CODE TO CHECK TIME AND LIGHT UP THE LED
void ReadDS3231()
{
  ///////////////////////////////////////////////////////////
  //These are now local and can only be seen/used/changed by this function
  int second, minute, hour, date, month, year, temperature;
  ///////////////////////////////////////////////////////////
  second = Clock.getSecond();
  minute = Clock.getMinute();
  hour = Clock.getHour(h12, PM);
  date = Clock.getDate();
  month = Clock.getMonth(Century);
  year = Clock.getYear();

  temperature = Clock.getTemperature();
  /////////////////////////////////////////////
  // Code from loop moved here
  Serial.println(hour);
  if (hour == 12) {
    digitalWrite(12, HIGH);
  }
  else
  {
    digitalWrite(12, LOW);
  }
  ///////////////////////////////////////
  lcd.setCursor ( 0, 0 ); // kolona 0, linija 1
  lcd.print(date, DEC);

  lcd.setCursor ( 2, 0 );
  lcd.print('.');

  lcd.setCursor ( 3, 0 );
  lcd.print(month, DEC);

  lcd.setCursor ( 5, 0 );
  lcd.print('.');

  lcd.setCursor ( 6, 0 );
  lcd.print("20");

  lcd.setCursor ( 8, 0 );
  lcd.print(year, DEC);

  lcd.setCursor ( 0, 1 );
  lcd.print(second, DEC);

  lcd.setCursor ( 2, 1 );
  lcd.print(':');

  lcd.setCursor ( 3, 1 );
  lcd.print(minute, DEC);

  lcd.setCursor ( 5, 1 );
  lcd.print(':');

  lcd.setCursor ( 6, 1 );
  lcd.print(hour, DEC);

  lcd.setCursor ( 11, 1 );
  lcd.print("T=");

  lcd.setCursor ( 13, 1 );
  lcd.print(temperature);

  lcd.setCursor ( 15, 1 );
  lcd.print("C");
}

void loop() {
  ReadDS3231();
  delay(1000);
}

This is the simple explanation for using global or local.

Ok, I understand now. Thanks for the explanation!