#include <avr/sleep.h>
#include <PinChangeInt.h>
const byte LED = 13, SW = 5;
volatile unsigned char count = 0;
unsigned char lastCount = 255;
void handleSW() { // ISR
count++;
}
void wake() { // ISR
sleep_disable(); // first thing after waking
PCintPort::detachInterrupt(SW);
}
void sleepNow()
{
PCintPort::detachInterrupt(SW);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
noInterrupts();
sleep_enable();
PCintPort::attachInterrupt(SW, wake, LOW);
interrupts(); // interrupts ok now, next instruction WILL be executed
sleep_cpu(); // here we go to sleep
}
byte led = LOW;
void handleOtherStuff() {
digitalWrite(LED, led);
led ^= (HIGH^LOW);
if (count != lastCount) {
Serial.print("Count ");
Serial.println(count);
lastCount = count;
}
delay(300);
if (count > 1) {
Serial.print(F("Going to sleep now ... "));
digitalWrite(LED, LOW);
Serial.flush();
sleepNow(); // this is where we sleep
Serial.println(F(" I'm awake!"));
PCintPort::attachInterrupt(SW, handleSW, CHANGE);
count = 0;
}
}
void setup() {
//Start up the serial port
Serial.begin(9600);
while (!Serial); // for Leonardo
Serial.println(F("Initialized example6"));
// configure the pins
pinMode(LED, OUTPUT);
pinMode(SW, INPUT_PULLUP);
PCintPort::attachInterrupt(SW, handleSW, CHANGE);
}
void loop() {
handleOtherStuff();
}
In this example, we use a pin change interrupt to awaken the processor from deep sleep. We have to use a level interrupt (i.e. HIGH or LOW).