Delay/Sleep for 8 hours?

Hi,

I'd like to delay/sleep the execution of my code for about 9 hours. I've tried incrementing an integer in the loop() and resuming the execution once it has hit a threshold, but this only works for about an hour and then jumps back into the code (some sort of overflow?)...

I've also tried the MsTimer2-library, but if I increase the time-to-sleep past 40 seconds (40000ms), it seemingly "sleeps" forever and never wakes up (the callback never fires).

The relevant part of my code:

void loop() {  

 switch (mode) {
    case NORMAL:
      analogWrite(ULNOutputPin, 255);
      break;
    
    case SLEEP:
      analogWrite(ULNOutputPin,0);
     
      #ifdef DEBUG
          Serial.print("\nSleeping...");
      #endif
      break;
  }


  // Button "Sleep" pressed?
  if (sleepButton.pressed()) {

    if(mode == NORMAL) {
      mode = SLEEP;
      MsTimer2::set(32400000, wakeUp);  // 9 hours in ms
      MsTimer2::start();
    } else {
      mode = NORMAL;
      MsTimer2::stop();
    }
    
    #ifdef DEBUG
      Serial.print("\nSleep-Button pressed, mode is now ");
      Serial.print(mode);
    #endif   
    
  }


  delay(200);
}



void wakeUp() {
      mode = NORMAL;
      MsTimer2::stop();
      
      #ifdef DEBUG
        Serial.print("\nSleep time ended, time to get up!");
      #endif
}

Is what I'm trying to achieve possible without connecting an external quartz? I've searched the forums but haven't found a suitable answer (likely due to stupid search-terms :-)!)...

Thanks for your help,
Nick

    delay(32400000UL); // pause execution for 9 hours (32,400,000 milliseconds)

Thanks!

That works, but I'd like to retain responsiveness if possible, i.e. pressing the "Sleep" button again should return the mode back to NORMAL (and if I use delay(), the Arduino will not register button-presses any more).

Thanks,
Nick

In that case, you need to record millis() at the start of your sleep, then have a loop that checks the sleep button, then checks whether millis() has increased by 32,400,000 since the start.

unsigned long SleepStart = 0;
const unsigned long SleepInterval = 32400000UL;
void loop() {  

 switch (mode) {
    case NORMAL:
      analogWrite(ULNOutputPin, 255);
      break;
    
    case SLEEP:
      analogWrite(ULNOutputPin,0);
      if (millis() - SleepStart > SleepInterval)
          mode = NORMAL;  // Resume normal operation
     
      #ifdef DEBUG
          Serial.print("\nSleeping...");
      #endif
      break;
  }


  // Button "Sleep" pressed?
  if (sleepButton.pressed()) {

    if(mode == NORMAL) {
      mode = SLEEP;
      SleepStart = millis();
    } else {
      mode = NORMAL;
    }
    
    #ifdef DEBUG
      Serial.print("\nSleep-Button pressed, mode is now ");
      Serial.print(mode);
    #endif   
  }

}

Thanks, guys, you're awesome :-)!! Works perfectly!

Best regards,
Nick

A little less work to activate/deactivate debugging serial output to the monitor -

// --- UNCOMMENT FOLLOWING TO ACTIVATE DEBUGGING CODE

//#define DEBUG_PRINT

#ifndef DEBUG_PRINT
    #define DebugPrint(X)
    #define DebugPrintln(X)
#else
    #define DebugPrint(X)     Serial.print(X)
    #define DebugPrintln(X)   Serial.println(X)
#endif

unsigned long SleepStart = 0;
const unsigned long SleepInterval = 32400000UL;

void loop() {  

 switch (mode) {
    case NORMAL:
      analogWrite(ULNOutputPin, 255);
      break;
    
    case SLEEP:
      analogWrite(ULNOutputPin,0);
      if (millis() - SleepStart > SleepInterval)
          mode = NORMAL;  // Resume normal operation
     
      DebugPrint("\nSleeping...");
      break;
  }


  // Button "Sleep" pressed?
  if (sleepButton.pressed()) {

    if(mode == NORMAL) {
      mode = SLEEP;
      SleepStart = millis();
    } else {
      mode = NORMAL;
    }
    
    DebugPrint("\nSleep-Button pressed, mode is now ");
    DebugPrint(mode);
  }

}