The interrupts() v. <avr/sleep.h> case

@simontpellier!

The tool I use for testing does not support sleep. So I placed a small sketch on a real UNO.

I had no trouble doubling up on the attached/detached interrupts or the nearly identical ISRs that support them.

Therefore I recommend that you create a small sketch that does that. I took an example from Nick Gammon, but before I learned why it was failing (!), I switched to some old code of mine that was 100 percent based on Nick Gammon.

Excuse the hacking. Buttons wired to switch to ground on pins 2 and 3 here.

# include <avr/sleep.h>

# define buttonINT 3
# define extraINT 2

byte cause;
unsigned int counter;

void setup()
{
  Serial.begin(115200);
  Serial.println(115200);
  
  pinMode(buttonINT, INPUT_PULLUP);
  pinMode(extraINT, INPUT_PULLUP);
}

void loop()
{
  Serial.println("going to sleep now.");

  sleepUntil();   // this goes us to sleep, we awake at the next line of code

  Serial.println("somehow I woke up.");

  delay(777);
}
  
void buttonISR()
{
  sleep_disable();
  detachInterrupt(digitalPinToInterrupt(extraINT));
  detachInterrupt(digitalPinToInterrupt(buttonINT));

  cause = buttonINT;
}

void extraISR()
{
  sleep_disable();
  detachInterrupt(digitalPinToInterrupt(extraINT));
  detachInterrupt(digitalPinToInterrupt(buttonINT));

  cause = extraINT;
}

void sleepUntil()
{
	Serial.println("to sleep 'K?");

	while (!digitalRead(buttonINT))
		delay(50);
	
	delay(50);

	goToSleep();

	delay(500);

	Serial.begin(115200);
	Serial.print("     woked up... ");
	Serial.print(counter);
	Serial.print("   interrupt ");
	Serial.println(cause);

	counter++;
}

void goToSleep()
{
    byte oldADCSRA = ADCSRA;
    ADCSRA = 0;  // turn off the A/D stuff verify 6 mA if ON

  
	set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
	sleep_enable();

	noInterrupts ();
	attachInterrupt (digitalPinToInterrupt(extraINT), extraISR, FALLING);
	attachInterrupt (digitalPinToInterrupt(buttonINT), buttonISR, FALLING);
	EIFR = bit(INTF0) || bit(INTF1);  // clear interupt flags
 
	MCUCR = bit (BODS) | bit (BODSE); // turn off brown-out stuff
	MCUCR = bit (BODS); 

	interrupts ();  // one cycle
	sleep_cpu ();   // one cycle

	ADCSRA = oldADCSRA;
}

HTH

a7

1 Like