Run code for specified number of hours from time on the clock

Hello, I feel like this is simple, but all my googling just leads me to very similar but not-useful solutions which depend on the start time of the Arduino (or in my case, NodeMCU).

I want to run "day" code and "night" code, and allow the user to set the parameters defining which code is run at which time of a 24 hour period, via a bluetooth companion app. So simply running the Arduino / Node for part of the day, and not running it for the rest of the day, would not work for me.

My issue is I can't just make a statement that says, say, "if TimeActual > TimeOn, run day code", because if the user defines "day" to begin at 11 PM for example, then "TimeActual" will become numerically smaller as soon as it loops past 23:59. But if they define "day" to begin at 1 AM and last 5 hours, "TimeActual" should be larger and the first example statement would be valid.

In the past, I created a similar controller, but I reprogrammed values myself manually, so I could just switch the "greater than" to "less than" as needed and plug in "and" statements where required. I can't figure out how to set up a similar framework when time values are being provided by an app, and the numerical relationship insofar as greater than/less than will be inconsistent.

Guidance on either issue is greatly appreciated

What you need is a real time clock board wth a battery backup and the ability to set alarms.

The Alarm is used to wake your Arduino from sleep. Your code should run between the required time and then sleep.

I feel like this is simple

It is once you get the right real time clock board.

Grumpy_Mike:
What you need is a real time clock board wth a battery backup and the ability to set alarms.

The Alarm is used to wake your Arduino from sleep. Your code should run between the required time and then sleep.
It is once you get the right real time clock board.

I think I explained poorly - apologies, it was late when I made this post.

I want to run "day" code and "night" code, and allow the user to set the parameters defining which code is run at which time of a 24 hour period, via a bluetooth companion app. So simply running the Arduino / Node for part of the day, and not running it for the rest of the day, would not work for me.

My issue is I can't just make a statement that says, say, "if TimeActual > TimeOn, run day code", because if the user defines "day" to begin at 11 PM, then "TimeActual" will become numerically smaller as soon as it loops past 23:59. In the past, I created a similar controller, but I reprogrammed values myself manually, so I could just switch the "greater than" to "less than" as needed and plug in "and" statements where required. I can't figure out how to set up a similar framework when time values are being provided by an app, and the numerical relationship insofar as greater than/less than will be inconsistent.

I've replaced the OP with this explanation as I feel it's more clear.

It is easy to configure on/off settings if you keep time in units of minutes past midnight or seconds past midnight.

If minutes past midnight is accurate enough for your purposes, the following test code contains the function within_interval(), which checks whether a given time is within a specified interval.

It uses the modulo operator to eliminate the problem of rollover at midnight, that is, you can set a program to run from 11 PM to 2 AM with no problems.

To keep time in seconds past midnight, change the constant 1440 to 86400 and use long integers for time.

void setup() {
  Serial.begin(9600);

  unsigned int start_minutes = 23 * 60 + 58;  //start at 23:58
  unsigned int duration = 4; //off after 4 minutes at 00:01

  Serial.print("start time in minutes past midnight ");
  Serial.print(start_minutes);
  Serial.print(", duration ");
  Serial.println(duration);

// loop index i replaces RTC time input
  for (int i = 0; i < 10; i++) { //count some minutes, beginning at 23:57, modulo 1440
    int now_minutes = (23 * 60 + 57 + i) % 1440;  //simulated current time, minutes past midnight
    Serial.print(now_minutes);
    Serial.print("\t");
    unsigned int t = (now_minutes - start_minutes + 1440) % 1440; //time on, modulu 1440
    Serial.print( t );
    Serial.print("\tfan state= ");

    if ( t < duration) fan(1);  //fan should be on
    else fan(0);  //fan should be off

    Serial.print (" interval check function returns ");
    Serial.println(within_interval(start_minutes, duration, now_minutes));
  }
}

// function to "turn on fan"
void fan(int on) {
  Serial.print(on);
}

// this function determines whether the current time in minutes past midnight 
// is within the timed interval start and start+duration, also in minutes past midnight
// ***range may span midnight***
#define MIN_PER_DAY 1440
byte within_interval(unsigned int start, unsigned int duration, unsigned int now) {
  unsigned int time_on = (now - start + 2*MIN_PER_DAY) % MIN_PER_DAY;  //multiply minutes per day by two for safety
  if (time_on < duration) return 1;  //within interval
  return 0;  //not within interval
}

void loop() {}

I've replaced the OP with this explanation as I feel it's more clear.

Fantastic, but you are in breach of the forum rules doing that.
Please read the how to use this forum sticky post.

It makes my comments look lame.