Sunday, 25 April 2010

Sleeping Arduino - Part 2 Wake Up Via An External Interrupt

Overview
In the second entry of this "Sleeping Arduino" series, we will be covering how to wake the Arduino via an external interrupt. We will be using the external interrupt circuit that has been covered in a previous blog Arduino External Interrupts. Please be sure to get the basic external interrupt example working before attempting to follow this entry, this will prove that your hardware setup is correct.


Operation
Our code will operate as follows:
  1. Set up the serial port and set pin 2 (INT0) as an input;
  2. Run the loop function which will:
    1. Stay awake for 3 seconds;
    2. Once the 3 seconds have elapsed, SLEEP_MODE_PWR_DOWN will be entered;
    3. All code execution stops;
  3. The user then pushes the switch and pin 2 (INT0) will become low;
  4. The INT0 interrupt will fire and bring the Arduino out of sleep mode;
  5. Code execution continues where it had previously stopped.

Circuit
The circuit is set up as specified in the Arduino External Interrupts blog.


Source Code

#include <avr/sleep.h>
#include <avr/power.h>


int pin2 = 2;


/***************************************************
 *  Name:        pin2Interrupt
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Service routine for pin2 interrupt  
 *
 ***************************************************/
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);
}


/***************************************************
 *  Name:        enterSleep
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Enters the arduino into sleep mode.
 *
 ***************************************************/
void enterSleep(void)
{
  
  /* Setup pin2 as an interrupt and attach handler. */
  attachInterrupt(0, pin2Interrupt, LOW);
  delay(100);
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  
  sleep_enable();
  
  sleep_mode();
  
  /* The program will continue from here. */
  
  /* First thing to do is disable sleep. */
  sleep_disable(); 
}


/***************************************************
 *  Name:        setup
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Setup for the Arduino.           
 *
 ***************************************************/
void setup()
{
  Serial.begin(9600);
  
  /* Setup the pin direction. */
  pinMode(pin2, INPUT);
  
  Serial.println("Initialisation complete.");
}



/***************************************************
 *  Name:        loop
 *
 *  Returns:     Nothing.
 *
 *  Parameters:  None.
 *
 *  Description: Main application loop.
 *
 ***************************************************/
int seconds=0;
void loop()
{
  delay(1000);
  seconds++;
  
  Serial.print("Awake for ");
  Serial.print(seconds, DEC);
  Serial.println(" second");
  
  if(seconds == 3)
  {
    Serial.println("Entering sleep");
    delay(200);
    seconds = 0;
    enterSleep();
  }
  
}

The sketch for this program can be downloaded here.





All parts of this series:


4 comments:

  1. Hi Donal,

    I'm finding that if I continually press the button I have setup to trigger the interrupt with code as it is the program kind of locks up after it goes into sleep.

    BUT if I move the "detachInterrupt(0);" statement out of the call back function, and just put it at the bottom of the enterSleep() method than things seems to work robustly.

    Any ideas why?

    Cheers
    Greg

    ReplyDelete
  2. Hello, What is the best way to set to sleep arduino using a Xbee module?
    I need minimum consumption for my project. Thank you and great blog.

    ReplyDelete
  3. Hi Giannis,
    Apologies for the delay in replying to you. Probably your best bet is to follow the very helpful tutorial here:
    http://www.sensor-networks.org/index.php?page=0820520514
    Cheers,
    Donal

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete