See section 9 & 28 of the data sheet.
Here's some bits that I found were needed. In my case, a keypress causes a hardware interrupt on pin 2.
I think hardware interrupt will let you put more stuff to sleep for lower current draw.
pre-setup
#include <VirtualWire.h> // Wireless transmitter/receiver library
#include <Keypad.h> // Matrix Keypad library
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library
functions
// * Name: pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
/* This brings us back from sleep. */
}
// * Name: enterSleep
void enterSleep()
{
/* Setup pin2 as an interrupt and attach handler. */
attachInterrupt(0, pin2Interrupt, LOW);
delay(50); // need this?
/* the sleep modes
SLEEP_MODE_IDLE - the least power savings
SLEEP_MODE_ADC
SLEEP_MODE_PWR_SAVE
SLEEP_MODE_STANDBY
SLEEP_MODE_PWR_DOWN - the most power savings
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // setting up for sleep ...
sleep_enable(); // setting up for sleep ...
// Disable ADC
ADCSRA &= ~(1 << ADEN);
// Power down functions
PRR = 0xFF;
sleep_mode(); // now goes to Sleep and waits for the interrupt
/* The program will continue from here after the interrupt. */
detachInterrupt(0); //disable interrupts while we get ready to read the keypad
// Power up functions
PRR = 0x00;
/* First thing to do is disable sleep. */
sleep_disable();
// then go to the void Loop()
}
and finally, calling sleep from within void loop()
void loop(){
if (sleep_count>1000){ // check if we should go to sleep because of "time" i.e. 1000 times thru loop with no action
sleep_count=0; // turn it off for when we wake up
delay(100); // need this?
enterSleep(); // call Sleep function to put us out
// THE PROGRAM CONTINUEs FROM HERE after waking up in enterSleep()
} // end of checking to go to sleep
// code here that does other stuff ...
sleep_count = sleep_count+1; // start counting to go to sleep
}