Skip to content

Instantly share code, notes, and snippets.

@j0uni
Created March 9, 2015 12:29
Show Gist options
  • Save j0uni/7d3d2be9c2f335f96785 to your computer and use it in GitHub Desktop.
Save j0uni/7d3d2be9c2f335f96785 to your computer and use it in GitHub Desktop.
Atmega 328 sleep
// source: http://forum.arduino.cc/index.php?PHPSESSID=8lp97jhr4smvi9n29he0ii6eu2&topic=78430.msg2080222#msg2080222
//ATmega328P sleep demo
//
//Wire the usual Arduino LED from PB5 (DIP pin 19, Arduino pin 13) to ground, through
//an appropriate current-limiting resistor.
//Wire a tactile button switch from INT0/PD2 (DIP pin 4, Arduino pin 2) to ground.
//
//The sketch will blink the LED three times, then go to sleep.
//Press the button to generate an interrupt to wake the MCU.
//Best on a breadboard. Note that voltage regulators and other circuitry on a real Arduino
//will continue to draw current and so the current consumed by just the MCU will be
//difficult to measure.
//While sleeping, I measure < 0.5uA supply current.
//
//Jack Christensen 11Sep2011
//
//Scotchware License: If we meet some day, and you think this is worth it, you can buy me a scotch.
#include <avr/sleep.h>
byte intCounter, adcsra, mcucr1, mcucr2;
void setup(void)
{
for (byte i=0; i<20; i++) {
pinMode(i, INPUT); //make all pins input pins
digitalWrite(i, HIGH); //with pullup resistors to minimize power consumption
}
pinMode(13, OUTPUT); //except LED pin
Serial.begin(115200);
EICRA = 0x00; //configure INT0 to trigger on low level
}
void loop(void)
{
Serial.print("interrupts: ");
Serial.println(intCounter, DEC);
for (byte i=0; i<3; i++) {
digitalWrite(13, LOW);
delay(1000);
digitalWrite(13, HIGH);
delay(1000);
}
digitalWrite(13, LOW);
sleep_enable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
adcsra = ADCSRA; //save the ADC Control and Status Register A
ADCSRA = 0; //disable ADC
cli();
EIMSK |= _BV(INT0); //enable INT0
mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE); //turn off the brown-out detector
mcucr2 = mcucr1 & ~_BV(BODSE);
MCUCR = mcucr1;
MCUCR = mcucr2;
sei(); //ensure interrupts enabled so we can wake up again
sleep_cpu(); //go to sleep
sleep_disable(); //wake up here
ADCSRA = adcsra; //restore ADCSRA
digitalWrite(13, LOW);
pinMode(13, OUTPUT); //so we can blink the LED some more
}
ISR(INT0_vect)
{
intCounter++;
EIMSK &= ~_BV(INT0); //one interrupt to wake up only
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment