Debugging sleep_cpu and interrupt gremlins on 32U4

Hello all,

I’m running a 32U4 in the guise of a Sparkfun Pro Micro. I’m building an interrupt driven chicken hutch radio door sensor off a Normally Open Reed Sensor.

I have read through https://www.gammon.com.au/power and ascertained that noInterrupts() is an alias to cli() and interrupts() is an alias to sei().

I’ve been trying to understand every line of code in the examples above, but getting some inconsistencies with sleep_cpu and wake up:

  • The LED stays ON at the end of the loop in the sketch below, despite being set to LOW. Is digitalWrite() asynchronous or do I need to do something else to make sure it finishes before the device goes back into sleep mode?
  • Sometimes the code below freezes in that no interrupts work anymore
  • I’m not 100% sure that I need to run noInterrupts() AND detachInterrupt() AND sleep_disable() in the ISR - surely noInterrupts() alone would prevent interrupts firing while the loop is being executed?
#include <avr/sleep.h>

const byte LED = 17; // RX LED on Pro Micro board
int sensor = 3; // Reed switch attached to D3=PIN18=PD0=INT0
volatile int count = 0; // counter to track interrupts

void setup()
{
  pinMode(LED, OUTPUT);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  
  noInterrupts(); 
}  // end of setup

void loop() 
{

  // flash as many times as we've seen interrupts
  for (int i=0; i<count; i++) {
    digitalWrite (LED, HIGH);
    delay(200);
    digitalWrite (LED, LOW);
    delay(200);
  }  

  attachInterrupt(digitalPinToInterrupt(sensor), wake, CHANGE);
  interrupts ();  // re-enable interrupts
  sleep_enable(); // enable sleep
  sleep_cpu ();   // go to sleep

} // end of loop

void wake()
{
  noInterrupts(); // disable interrupts
  detachInterrupt(digitalPinToInterrupt(sensor));
  sleep_disable();
  count++; // increment led counter
} //end of wake

Do you have any ideas?

Thanks!

Amadeus