using rtc output to trip several relays

I have Arduino 1:8:3 with a DS3231 RTC and I am looking for help with how to use the output time from

the RTC to turn on & off a number of relays.

I can find many scripts outputting time to a LCD display but am unable, so far, to find a sketch which will

allow me to use the time to turn on and off the relays.

Appreciate any helpful comments or advice

Suppose that you wanted to do something at 18:32 each day

If the current hour is 18 and the current minute is 32 then do it.

Another, possibly better way is to do things based on the number of minutes since midnight. So if the number of minutes since midnight is (18 * 60) + 32 then do what you need to.

read through

https://forum.arduino.cc/index.php?topic=552537.0

for some ideas.

a7

"I can find many scripts outputting time to a LCD display but am unable, so far, to find a sketch which will allow me to use the time to turn on and off the relays."

I have read the suggested topic, but sorry, you are talking to an Arduino "idiot".

Been at it on and off for about 2 weeks so things like EPROM,Registers,interupts etc are way above my current pay grade.

What I am asking is for an "idiots" way of achieving:

If RTCtime = x then turn on "pin y". If RTCtime =x then turn off "pin y."

Is there some easy way to retrieve "current time" from the RTC and convert it to a variable which could be used in the above example.

Thanks

Sorry to overpost but found a sketch that is supposed to do what I want but accepts the compilation and upload but outputs "garbage" to screen.

Any thing in the sketch I have done wrong???

RTC__specific_time.ino (746 Bytes)

Maybe if you set the baudrate of the Arduino and the baudrate of the Serial Monitor to the same value, you might get something readable.

Next time, please post your code in the post instead of attaching it; it's small enough (limit is around 9000 characters):
Type
** **[code]** **

Paste your code after that
Type
** **[/code]** **
after that

If you

can find many scripts outputting time to a LCD display

Then you will see how they retrieve the time from the RTC. So use the same method to

retrieve "current time" from the RTC

and compare it to your target times

Farticus:
Is there some easy way to retrieve "current time" from the RTC and convert it to a variable which could be used in the above example.

I believe that this sketch demonstrates what you want.

Notice that it uses the Wire library to access the RTC. That's why you have the lines
#include <Wire.h> and   Wire.begin();

Also notice the global variables near the top of the sketch, as well as the grabTime function which "loads" the time into those variables.

Because you want one single variable for the time of day, I created the packedTime variable. See the arithmetic for how I created it out of the hour and minute.

Here is the sketch:

#include <Wire.h>

// variables for storing the time
//   second  minute  hour    weekday  date    month   year
byte ss=0,   mi=0,   hh=0,   wd=6,    dd=1,   mo=1,   yy=0;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
//  Wire.beginTransmission(0x68); // address DS3231
//  Wire.write(0x0E); // select register
//  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
//  Wire.endTransmission();
}
 
void loop()
{
  // read the time from the RTC, if we can
  boolean gotTheTime = grabTime();
 
  if (gotTheTime) {
    // if we are here, then the time has been successfully read
    // and stored in global variables (ss, mi, hh, wd, dd, mo, yy)
    Serial.print("Got the time: ");
    printTime(); 
  }
  else {
    // if we are here, then we tried to read the time but couldn't
    Serial.println("Unable to read time from RTC");
  }
  
  Serial.print("   Value of hours variable (hh) is: ");
  Serial.println(hh, DEC);
  Serial.print(" Value of minutes variable (mi) is: ");
  Serial.println(mi, DEC);
  
  int packedTime = (100 * ((int)hh)) + ((int)mi);
  Serial.print("            Value of packedTime is: ");
  Serial.println(packedTime, DEC);
  Serial.println("");
  
  delay(500);
}


boolean grabTime() {
  // get time from the RTC and put it in global variables

  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hh, wd, dd, mo, yy)
  // check for a reply from the RTC, and use it if we can
  if (Wire.available() >= 7) {
    // if we're here, we got a reply and it is long enough
    // so now we read the time
    ss = bcd2bin(Wire.read()); // get seconds
    mi = bcd2bin(Wire.read()); // get minutes
    hh = bcd2bin(Wire.read()); // get hours
    wd = bcd2bin(Wire.read()); // get day of week
    dd = bcd2bin(Wire.read()); // get day of month
    mo = bcd2bin(Wire.read()); // get month
    yy = bcd2bin(Wire.read()); // get year (two digits)
    // indicate that we successfully got the time
    return true;
  }
  else {
    // indicate that we were unable to read the time
    return false;
  }
}


byte bcd2bin(byte x) {
  // converts from binary-coded decimal to a "regular" binary number
  return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}


void printTime() {
  // just like it says on the tin
  Serial.print ("\'");
  if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
  if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
  if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print("  ");
  if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
  if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
  if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}

Thank you sterretje as a rookie that was something I never noticed.

Also thanks for the tip about scripts in text. Was unaware of that.

:slight_smile: :slight_smile: odometer :slight_smile: :slight_smile: many thanks. That is exactly what I was looking for.

I have been trying to tweak it to include day and month output.

The attached revisal of your code does work but gives 2 outputs which would have to be compared with the

"&&" (eg If (output A==???? ) && (output B==????) {Pin,??????? HIGH}

Is there a better way to integrate both outputs into one number?

#include <Wire.h>

// variables for storing the time
//   second  minute  hour    weekday  date    month   year
byte ss=0,   mi=0,   hh=0,   wd=6,    dd=1,   mo=1,   yy=0;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
//  Wire.beginTransmission(0x68); // address DS3231
//  Wire.write(0x0E); // select register
//  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
//  Wire.endTransmission();
}
 
void loop()
{
  // read the time from the RTC, if we can
  boolean gotTheTime = grabTime();
 
  if (gotTheTime) {
    // if we are here, then the time has been successfully read
    // and stored in global variables (ss, mi, hh, wd, dd, mo, yy)
    Serial.print("Got the time: ");
    printTime();
  }
  else {
    // if we are here, then we tried to read the time but couldn't
    Serial.println("Unable to read time from RTC");
  }
  Serial.print("   Value of month variable (mo) is: ");
  Serial.println(mo, DEC);
 Serial.print("   Value of days variable (dd) is: ");
  Serial.println(dd, DEC);
  Serial.print("   Value of hours variable (hh) is: ");
  Serial.println(hh, DEC);
  Serial.print(" Value of minutes variable (mi) is: ");
  Serial.println(mi, DEC);
 
  int packedTime = (100 * ((int)hh)) + ((int)mi);
  int packedTime2 = ( 100* (( int)dd) + ((int)mo));           // Pack day and month
  Serial.print("            Value of packedTime is: ");  
  Serial.println(packedTime, DEC);                        
  Serial.println("");

   Serial.print("            Value of packedTime2 is: ");
  Serial.println(packedTime2, DEC);                                // Print pack value of day and month
  Serial.println("");
 
  delay(1000);
}


boolean grabTime() {
  // get time from the RTC and put it in global variables

  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hh, wd, dd, mo, yy)
  // check for a reply from the RTC, and use it if we can
  if (Wire.available() >= 7) {
    // if we're here, we got a reply and it is long enough
    // so now we read the time
    ss = bcd2bin(Wire.read()); // get seconds
    mi = bcd2bin(Wire.read()); // get minutes
    hh = bcd2bin(Wire.read()); // get hours
    wd = bcd2bin(Wire.read()); // get day of week
    dd = bcd2bin(Wire.read()); // get day of month
    mo = bcd2bin(Wire.read()); // get month
    yy = bcd2bin(Wire.read()); // get year (two digits)
    // indicate that we successfully got the time
    return true;
  }
  else {
    // indicate that we were unable to read the time
    return false;
  }
}


byte bcd2bin(byte x) {
  // converts from binary-coded decimal to a "regular" binary number
  return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}


void printTime() {
  // just like it says on the tin
  Serial.print ("\'");
  if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
  if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
  if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print("  ");
  if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
  if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
  if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}
/[code]

Thank you for your help