How to engineer a power-loss safe RTC time switch?

276 views Asked by At

I'm using a ESP32 with a DS3231 real time clock. The system should automatically switch on and off an output based on a user-programmable time (HH:MM) on a daily basis. The on and off hours/minutes are stored in flash so they are non-volatile. Also, the duration the output stays on is hardcoded.

I'm trying to develop a function which is called each second to check wether the output should be turned on or off based on the current time provided by the DS3231 RTC. This should be safe against misbehaviour if the power fails. So if for example power is temporarily lost in between an on-interval, the output should be set again for the remaining time interval once power is reapplied.

How can I relatively calculate if the current time is in between the on-time interval?

const int8_t light_ontime_h = 2; // Hour interval for how long the output should stay on
const int8_t light_ontime_m = 42; // Minute interval for how long the output should stay on
struct tm currenttime; // Current time is stored in here, refreshed somewhere else in the program from RTC
struct tm ontime; // Hours and minutes to turn on are stored in here. Values are loaded from NVS on each reboot or on change. So struct only holds valid HH:MM info, date etc. is invalid

// This is called each second
void checkTime() {
  struct tm offtime;

  offtime.tm_hour = ontime.tm_hour + light_ontime_h;
  offtime.tm_min = ontime.tm_min + light_ontime_m;

  // Normalize time
  mktime(&offtime);

  // Does not work if power is lost and correct hour/min was missed
  if ((currenttime.tm_hour == ontime.tm_hour) && (currenttime.tm_min == ontime.tm_min)) {
    // Turn output on
  } 
  if ((currenttime.tm_hour == offtime.tm_hour) && (currenttime.tm_min == offtime.tm_min)) {
    // Turn output off
  }

}
0

There are 0 answers