Check if time is between two time inputs.

Hello.

I cant seem to wrap my heard around this.

I have RTC and two time inputs.

I want to be able to turn on the lights between timeOn and TimeOff. The issue is that I have is that it example have to work if timeOn is 1500 and timeOff is 1800. And if timeOn is 1500 and timeOff is 0700. ( The crossing of midnight make it harder for me to use if timeOn is less time && time is more than timeOff. )

Im using Timelib, and time input from Blynk. With Timelibs I have the opportunity to get time in various different ways, including the same way I get it from Blynk, which is seconds since 00:00

Any pointers ?

Convert all times to seconds past midnight and the comparisons become trivial.

   if (time_in_seconds >= on_time && time_in_seconds < off_time) lights_on();
   else lights_off();

Thanks, but doesn't that also have issues?

Example I want to have lights on between 1900->0200

So timeOn 1900 and timeOFF at 0200.
At 2000 then both timeOFF and timeOn is smaller than time.

oleost:
Thanks, but doesn't that also have issues?

Example I want to have lights on between 1900->0200

So timeOn 1900 and timeOFF at 0200.
At 2000 then both timeOFF and timeOn is smaller than time.

I wrote a library to do exactly what you are looking to do

Thanks, will try it out as soon as I get home. Already wrote the code. Hope ti will work.

BulldogLowell:
I wrote a library to do exactly what you are looking to do

Having some issues using it.

Not sure if its because I already have an RTC clock ?

Isolated what I use is:

void ledOn() {
 for(int i=0;i<NUM_LEDS;i++){
   leds[i] = CHSV( hueDay, satDay, briDay);
 }
 FastLED.show();
}

void ledOff() {
 for(int i=0;i<NUM_LEDS;i++){
 leds[i] = CHSV( hueNight, satNight, briNight);
 FastLED.show();
}
}

DailyTimer ledTimer1(
 true,                             // AutoSync true or false, will run the startTimeCallback() if restarts within the active range or after range changes and you are in the range
 inputStart,                               // Start Hour
 inputStartminutes,                               // Start Minute
 inputStop,                                // End Hour
 inputStopminutes,                                // End Minute
 EVERY_DAY,                         // SUNDAYS, MONDAYS, TUESDAYS, WEDNESDAYS, THURSDAYS, FRIDAYS, SATURDAYS, WEEKENDS, WEEKDAYS, or EVERY_DAY
 FIXED,                            // OPTIONAL - FIXED, RANDOM, RANDOM_START, or RANDOM_END
 ledOn,                            // pointer to function to execute at Start time, or a Lambda as in this example:
 ledOff                            // pointer to function to execute at End time
);

void setup()
{
 ledTimer1.begin();
}

void dailylibtimer() {
 static unsigned long lastTime = 0;
 DailyTimer::update();
 if(millis() - lastTime >= 1000)
 {
   char timeBuffer[32] = "";
   sprintf(timeBuffer, "Time:%2d:%02d:%02d\tDate:%02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
   Serial.println(timeBuffer);
   lastTime = millis();
 }
}

void loop()
{
 dailylibtimer();
}

oleost:
Not sure if its because I already have an RTC clock ?

I don't see you using a clock in your code....

BulldogLowell:
I don't see you using a clock in your code....

I'm using Blynk RTC clock and Timelib.

So I pull current time from that lib with example hour()

Unsure how to intregate this with your lib?

oleost:
I’m using Blynk RTC clock and Timelib.

So I pull current time from that lib with example hour()

Unsure how to intregate this with your lib?

you need to get the time from somewhere.

try putting in your library and let’s see…

BulldogLowell:
you need to get the time from somewhere.

try putting in your library and let's see...

The blynk has the RTC time. So I get the time with the RTC widget. And Timelib is used.

But I'm unsure of all this is necessary for your lib?

void dailylibtimer() {
 static unsigned long lastTime = 0;
 DailyTimer::update();
 if(millis() - lastTime >= 1000)
 {
   char timeBuffer[32] = "";
   sprintf(timeBuffer, "Time:%2d:%02d:%02d\tDate:%02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
   Serial.println(timeBuffer);
   lastTime = millis();
 }
}

oleost:
The blynk has the RTC time. So I get the time with the RTC widget. And Timelib is used.

But I'm unsure of all this is necessary for your lib?

again, the time has to come from somewhere!

how does your arduino sync the time using blynk?

My library uses TimeLib.h, so you should be able to get this working.

The time comes from NTP server, it's an ESP8266.

oleost:
The time comes from NTP server, it's an ESP8266.

your code buddy... how do you get the time synced in your code?

The Blynk library handles it.

This I can verify by doing serial print hour() and get the current time.

Thanks, but doesn't that also have issues?

No, that statement is fine, especially if you use unix time instead of day times.

YOU have to deal with the special cases, which would obviously require a different, but also simple comparison.

jremington:
No, that statement is fine, especially if you use unix time instead of day times.

YOU have to deal with the special cases, which would obviously require a different, but also simple comparison.

I understand that, I just can’t grasp the logic I should use.

Maybe I found out how.

If inputstop > inputstart ( // inputstart and inputstop doesn't cross midnight

If time > timestart && time < timestop (
Ledon
)
)
If input stop < inputstart ( // crosses midnight
If time > inputstart && time > inputstop (
Ledon
)
If time < inputstart && time < inputstop (
Ledon
)
)
Else (ledoff)

oleost:
The Blynk library handles it.

This I can verify by doing serial print hour() and get the current time.

this:

DailyTimer::update();

needs to be in loop() as in the example...

your blocking code is a liability...

BulldogLowell:
this:

DailyTimer::update();

needs to be in loop() as in the example…

your blocking code is a liability…

But if the “Partymode” button is pressed I want to ignore the time settings, and just do an flashing of leds regardless of time.

As long as “Partymode” button is not pressed it should work, as DailTimer::update(); is in “dailytimetimer”

void dailylibtimer() {
  static unsigned long lastTime = 0;
  DailyTimer::update();
  if(millis() - lastTime >= 1000)
  {
    char timeBuffer[32] = "";
    sprintf(timeBuffer, "Time:%2d:%02d:%02d\tDate:%02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
    Serial.println(timeBuffer);
    lastTime = millis();
  }
}

void loop()
{
  ArduinoOTA.handle();
  Blynk.run();
  timer.run();
  if (partymodeButton >= 3) {
    partyMode();
  }
  else {
  dailylibtimer();
}
}

I understand that, I just can't grasp the logic I should use.

Using Unix time (seconds since 00:00:00 Jan 1, 1970 UTC), the single statement I posted works for every possible case, spanning any number of seconds, minutes, hours, days, weeks, months or years between 1970 and 2038.

jremington:
Using Unix time (seconds since 00:00:00 Jan 1, 1970 UTC), the single statement I posted works for every possible case, spanning any number of seconds, minutes, hours, days, weeks, months or years between 1970 and 2038.

Hmm, only if you enter and spesific time and date ? Example Monday 1.1.2010 13:00 (1262350800) to Tuesday 2.1.2010 07:00 (1262415600) ?

In my case I only have two time inputs, which is just 13:00 and 07:00