Ds3231 rtc event at specific time

Im not understanding what i need to do in order to but a 24hr timer.

I was thinking how to turn on the output at the turn on time but i dont think this is going to give me the results i expect.

 if (now.hour() == 21 && now.minute() ==30) {
    GPIO.write( 7, 0);
  }

the above would set the output LOW "ON" at 21:30 but what happens if the device arduino is powered on at 21:31.

I would only like the output to stay LOW for a couple hours and need it to turn off at lets say 05:45

I'm afraid im stuck at this point. I most concerned that the device may not be powered on exactly when the "on point" happens and miss the turn on/turn off.

Not clear to me if by "device" you mean the Arduino or the thing the Arduino is controlling.

I mean arduino sorry. if the arduino is not powered on until 21:31.

How can i check after power on if the output should be "on/off "

How is 05:45 "a couple of hours" after 21:30?

Maybe someone can help me understand this

unsigned long  currentHour =1;
unsigned long currentMinute = 20;
unsigned long nowInSeconds = 0;
unsigned long  onInSeconds = 0;
unsigned long  offInSeconds = 0;
int onHour = 1;
int offHour = 1;
int onMinute = 21;
int offMinute = 22;

  currentHour = now.hour();
  currentMinute = now.minute();
  nowInSeconds = ((currentHour * 60) + currentMinute) * 60;
  onInSeconds = ((onHour * 60) + onMinute) * 60;
  offInSeconds = ((offHour * 60) + offMinute) * 60;

  if ((nowInSeconds >= onInSeconds) && (nowInSeconds < offInSeconds))
  {
    isTime = true;
    Serial.println("true");
  }
  else if ((nowInSeconds <= onInSeconds) && (nowInSeconds < offInSeconds))
  {
    isTime = true;
       Serial.println("true2");
  } else {
    isTime = false;
       Serial.println("false");
  }
}

with the above configuration i get "true2" in the serial console

I think im not understanding how it works. What is the point of this part of this code,

 else if ((nowInSeconds <= onInSeconds) && (nowInSeconds < offInSeconds))
  {
    isTime = true;
       Serial.println("true2");

It is just converting your time into seconds... then comparing the total seconds against the boundary times (also in seconds) for off and on.

So lets say you want it on at 21:30:00, and off at 05:45:00. The other way to looks at that is you want it off between 05:45:00 (time 1) and 21:30:00 (time 2).

So convert everything to seconds

unsigned long time1 = (unsigned long )(5UL * 60 * 60) + (45 * 60) + 0;
unsigned long time2 = (unsigned long )(21UL * 60 * 60) + (30 * 60) + 0;

Then in your code calculate current time (say 10:25:15) also into seconds:
unsigned long current = (unsigned long )(10UL * 60 * 60) + (25 * 60) + 15;

Then

if (current > time1 && current < time 2)
  // turn off
else
  // turn on

EDIT: Post updated as per Oops noted in post #8 (thanks @odometer ).. just in case someone stumbles across this in future.

1 Like

that helps me understand a little better. the math is more clear now. thanks

Oops!
That should be

unsigned long time2 = (unsigned long )(21L * 60 * 60) + (30 * 60) + 0;

because otherwise the 21 * 60 * 60 will be evaluated as an int, and it will overflow an int.

1 Like

yep

I still am really confused with this.

In this configuration im getting "on" in the serial console.

If the currentTime is > the onTime but < offTime, it should be on no?

  unsigned long offTime = (unsigned long )(12L * 60 * 60) + (23 * 60) + 0;
  unsigned long onTime = (unsigned long )(12L * 60 * 60) + (20 * 60) + 0;
  unsigned long current = ((12 * 60) + 24) * 60;

  if ((current > onTime) && (current < offTime)) {
    Serial.println("off");
    Serial.print("offTime:");
    Serial.println(offTime);
    Serial.print("onTime:");
    Serial.println(onTime);
    Serial.print("current:");
    Serial.println(current);
  } else {
    Serial.println("on");
    Serial.print("offTime:");
    Serial.println(offTime);
    Serial.print("onTime:");
    Serial.println(onTime);
    Serial.print("current:");
    Serial.println(current);

    // turn on
  }
12:24:02.564 -> on
12:24:02.564 -> offTime:44580
12:24:02.564 -> onTime:44400
12:24:02.564 -> current:44640

when my the arduino is powered on it should know somehow if it missed the turn on point and is halfway through the " on period " so go ahead and activate the output.

I need timer to come on every day at on time and off at off time. and repeat. every day. but should check if missed turn on point and handle that.

I need this to repeat. please help me understand

One way i found is to set a specific on time hh:mm. then set specific amount of hh:mm to run for. convert the "run hour and minutes" to a totality of seconds. then check if that many seconds has elapsed, if not then ON else OFF.

  currentHour = now.hour();
  currentMinute = now.minute();
  unsigned long onTime = (unsigned long)(_EEPROM.onHour * 60 * 60) + (_EEPROM.onMinute * 60) + 0;
  unsigned long current = ((currentHour * 60) + currentMinute) * 60;
  if ((current >= onTime) && (current - onTime  <= _EEPROM.onLength)) {
    Serial.println("ON");
  } else {
    Serial.println("OFF");
  }

Because this statement is overflowing...

Use 12UL.

You seemed to have missed the relevance of post #12 and how the default type for arithmetic is Integer, unless you force it to be something else.

Also... your condition check needs to be aware of the fact that you are working on a 24 hour clock and therefore need to consider whether you are best to check the OFF time or the ON time, otherwise it gets complicated if you are trying to test across days.

Yes but i did in another unreported attempt to use UL for all. the conclusion was there is something wrong when we get to

(current < offTime))

this statement never changes. So i guess the program is broken. did you try it?

This should print off right?

 unsigned long offTime = (unsigned long )(12L * 60 * 60) + (26 * 60) + 0;
  unsigned long onTime = (unsigned long )(12L * 60 * 60) + (25 * 60) + 0;
  unsigned long current = ((12UL * 60) + 24) * 60;

  if ((current > onTime) && (current < offTime)) {
    Serial.println("off");
    Serial.print("offTime:");
    Serial.println(offTime);
    Serial.print("onTime:");
    Serial.println(onTime);
    Serial.print("current:");
    Serial.println(current);
  } else {
    Serial.println("on");
    Serial.print("offTime:");
    Serial.println(offTime);
    Serial.print("onTime:");
    Serial.println(onTime);
    Serial.print("current:");
    Serial.println(current);

    // turn on
  }
16:20:21.128 -> on
16:20:21.128 -> offTime:44760
16:20:21.128 -> onTime:44700
16:20:21.128 -> current:44640

ignore the serial timestamp. I would like to understand why it dont work though

Because 44640 is NOT greater than 44700 ?

You have OFF and ON back to front.

okay but it don't matter what time it is. will be or was. The program you shared dont work.

There's typos, its incomplete, some parts were invalid. then you modified it days later. This will not be good for the next reader.

Wow... your appreciation is awesome. Good luck finding people to help you with that attitude.

I think the most confusing part is current < time2.

unless im not understanding something the code just simply don't work as you have presented it. The way i created in #12 is the solution to this problem.

If you can provide me with working code id be willing to try it

Nonsense.. that solution does not work. What if it were supposed to be on for 4 hours from 22:00, and it's 01:00

is false... so OFF !

But hey... you don't want my help so good luck.

1 Like

Ive asked you several times to help me. What is your problem? I have told you several times your programs don't work, but i guess you don't care.

What do you want me to say? You just like watching me repeat myself?