Yes, Atmega328 can be put to sleep.
I don’t know about non-hardware wake ups, these bits will do a lot of the rest.
Make sure to set your unused inputs high or low, don’t leave them floating.
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library
Hardware interrupt to wake up
//***************************************************
// * 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
// Power up functions
PRR = 0x00;
/* First thing to do is disable sleep. */
sleep_disable();
// then go to the void Loop()
}
// set up the pins as Inputs, Outputs, etc.
void setup()
{
/* Setup the pin directions, write inputs High to turn on internal pullups */
pinMode(pin2, INPUT); // our sleep interrupt pin
digitalWrite(pin2, HIGH);
}
void loop()
{
if (sleep_count>1000){ // check if we should go to sleep because of “time” → Try shorter versions of this
sleep_count=0; // turn it off for when we wake up
// Serial.println(“Sleep”); // for debug only
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