Created
March 9, 2015 12:29
-
-
Save j0uni/7d3d2be9c2f335f96785 to your computer and use it in GitHub Desktop.
Atmega 328 sleep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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