Example 6

Back to Arduino Interrupts

#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).

Leave a Reply

Your email address will not be published. Required fields are marked *