Arduino Sleep Interrupt not working.

Hi there!

So I am trying to make my arduino sleep, and wake up on Serial msgs using the examples provided from : Arduino, Zigbee and Embedded Development: Sleeping Arduino - Part 2 Wake Up Via An External Interrupt

But what I have done differently is placed the sleep_mode() call inside of a infinite loop.(See code below). The idea with this is just to make arduino go back to sleep immediately after it wakes up after the 8s watchdog timer event.

So the example code worked without my adding the loop but with it, the interrupt never fires/wakes up arduino.

 // This variable is made volatile because it is changed inside an interrupt function
volatile int sleep_count = 0; // Keep track of how many sleep cycles have been completed.

int sleepInterval = 5; // Interval in minutes between waking and doing tasks.
int sleep_total = (sleepInterval*60)/8; // Approximate number of sleep cycles needed before the interval defined above elapses. Not that this does integer math.
// NOTE WHEN sleepInterval gets eventually changed later also have to recalc sleep total  
  
  int pin2 = 2;
  void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    
    //WatchDog Timer Initialization
     MCUSR &= ~(1<<WDRF); // clear reset flag
     WDTCSR |= (1<<WDCE) | (1<<WDE); // set WDCE to allow updates to prescaler and WDE for 4 clock cycles  
     WDTCSR = 1<<WDP0 | 1<<WDP3; // set watchdog timer prescale values for max timeout (8 seconds)
     WDTCSR |= _BV(WDIE); // enable watchdog interrupts
   
   /* Setup the pin direction. */
  pinMode(pin2, INPUT);
   
  }
  
  void loop() {
    
    
    // put your main code here, to run repeatedly:
      if (sleep_count >= sleep_total) {
      
        // CODE TO BE EXECUTED PERIODICALLY
        Serial.println("Im awake!");
        delay(100);
        sleep_count = 0;
      }
      enableSleepMode();   
  }
  
  
  
  
  /**
  Watchdog Interrupt Service. This is executed when watchdog timed out.
  */
  
  ISR(WDT_vect){
    sleep_count++; // keep track of how many sleep cycles have been completed.
  }
  
  
  void pin2Interrupt(void)
{
  /* This will bring us back from sleep. */
  
  /* We detach the interrupt to stop it from 
   * continuously firing while the interrupt pin
   * is low.
   */
  detachInterrupt(0);
  
  Serial.println("WHAT? YOU WOKE ME UP!");
  
}
  
  /**
  * Enables sleep mode by powering down peripherals, etc. Minimizes current draw and power consumption.
  */
  
  void enableSleepMode(void){  
    
     set_sleep_mode(SLEEP_MODE_PWR_DOWN);
     
     sleep_enable();
     /* Setup pin2 as an interrupt and attach handler. */
    attachInterrupt(0, pin2Interrupt, LOW);

    while(true){
      sleep_mode();
      // program wakes up here from sleep here
    }
     sleep_disable();
  
  }

Perhaps the problem is that Serial.println("WHAT? YOU WOKE ME UP!"); can't complete its task between the time the interrupt returns and the time the processor is put back to sleep.

"Power-down mode. In this mode, the external Oscillator is stopped, while the external interrupts, the 2- wire Serial Interface address watch, and the Watchdog continue operating (if enabled). Only an External Reset, a Watchdog System Reset, a Watchdog Interrupt, a Brown-out Reset, a 2-wire Serial Interface address match, an external level interrupt on INT0 or INT1, or a pin change interrupt can wake up the MCU. This sleep mode basically halts all generated clocks, allowing operation of asynchronous modules only."

Sounds like the UART Send Completed interrupt is disabled so Serial.print() can't send while sleeping.

  void loop() {
    
    
    // put your main code here, to run repeatedly:
      if (sleep_count >= sleep_total) {
      
        // CODE TO BE EXECUTED PERIODICALLY
        Serial.println("Im awake!");
        delay(100);
        sleep_count = 0;
      }
      enableSleepMode();   
  }

Since enableSleepMode() never returns the loop() will not repeat. It will check the sleep_count only once.

You can use Serial.flush() to assure that all the serial data has been sent before going to sleep. It is the only time that this function is needed.