Battery life is often overlooked when building projects, especially for beginners. This tutorial takes you through the setup of power saving modes for the Arduino. Utilizing the watchdog and sleep functions, they put the chip into a hibernation mode between cycles. An optimum configuration could take your battery life from 4 days to about 3 years. For a lot of you, this is old news. But for the rest, this is really good stuff. You can download a sample application from the site that mimics the singing of a nightingale when the sun goes down.
23 thoughts on “Sleepy Arduino Saves Batteries”
Is this just the atmega chip itself providing the watchdog and power saving functionalities, and therefor the energy saving potential?
So all you need is activate it by code when you have time/cycles to spare in your implementation?
And if yes, are there any drawbacks associated with going into power saving mode and handing execution over to the watchdog (except from not being able to execute code during power saving, obviously)?
How about switching to power saving/watchdog more often for shorter amounts of time? Will there still be a benefit?
Thanks for your input =)
P.S.: First \o/
a) Stop firsting- this is not some stupid discussion forum.
b) Take a look at atmel’s 168 manual which goes into detail about which modules can and can not be disabled during sleep. The only downside is the time it takes to wake the device (and all its modules) back up from sleep. Complete manual here: http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf
Why this guy, who know how to standby the Arduino, continues to use an external quartz while having plenty of internal clocks is difficult to understand !
he’s using the external clock so that he has good timing accuracy. the internal clock is off by as much as 10%.
AVRs and other microcontroller architectures have sleep modes for at least 10 years. the guys who made Arduino just decided to do a full-speed main loop; I guess they thought it was easier for non-tech people to deal with, and the board’s hardware isn’t exactly prepared for low power consumption either.
The serial port would not work at 38400bps without a crystal. There are “workarounds”, but work is needed.
hey guys, I’m seeing some more-hype-than-tech posts here lately; please leave those for Make: and let’s get back to more “real” stuff as before, please :)
OMG I ALREADY KNEW THIS THEREFORE ITS NOT A HACK!
The atmegaX8 series (like the atmega168) have a useful feature to get accurate periodic wake up and sleep operation.
You run the AVR on internal oscillator, I choose 1 MHz and change the clock divider to 4MHz so it will operate from 1.8V to 5.5V.
You connect a 32KHz watch crystal to the crystal connections of the AVR. Dont forget the load capacitors.
When you turn on timer 2 in asynchronous mode, and enable to use the crystal oscillator. You can go to power-save mode where most of the controller is powered down, but the timer 2 interrupt will periodically wake the AVR up.
Using the interrupt of timer 2, and the proper divisor you can wake up 1024 times per second. Useful for a small operating system scheduler.
I use this setup in a small wireless sensor network I am developing. I need a quite accurate timer to have reasonably accurate synchronisation between nodes. It is not really needed but improves power efficiency.
Well I feel like a noob here, but i’m learning a lot from hackaday. thanks
Think of the beginners :'(
yay, arduino-a-day is here again.
Phew! I was begining to get shakes from serious Arduino withdrawl .. thanks Arduino-a-Day!
Timed sleep states are a great power saver when you don’t need real-time availability. But what I’m interested in is how to permanently put it to sleep and wake it up on button press (ground int pin). I know it’s possible, but I haven’t found any good write ups on how to do this. I’ve read what’s out there, and nothing is really clear to me.
its implemented here http://www.righto.com/2010/11/improved-arduino-tv-b-gone.html
also here is the page: http://playground.arduino.cc/Learning/arduinoSleepCode
God are most of the commenters here annoying. You’re obviously too good for hackaday, so move on. This is a perfectly fine article. There’s no ‘hype’, there’s good, useful information for beginners on how to better use the ATmega in the Arduino.
Yaaa, I think experts should start reading IEEE journals and stuff …
I didn’t mean to imply the article wasn’t good. It’s a great introduction to sleep states and the watchdog timer. I’ve bookmarked it for future reference. I was just saying that I would *also* like a write up on the other method. I could use either/or depending on the application. It just so happens that my current application requires the other.
Mike: i dont think they were talking about you, you had a valid comment and i would also like to know how to wake on button.
The AVR used in the arduino can wake up from deep sleep if you make the interrupt pin low for at least X microseconds.
A much better solution would be to use the pin change interrupts. They can wake up the MCU from all sleep modes when a pin changes. Perfect from wake up on button press.
that’s what I want, but I’m still not clear on how to implement that in my code.
It is not that hard but I am not familiar with the arduino environment on how to implement it. I program the AVR series in C and/or assembler.
Basically you setup the registers to what pins the MCU will wake up, Create an ISR(Interrupt Service Routine) and enable interrupts. Then execute the sleep setup and sleep instruction.
When exiting you can read out the pin change interrupt registers to see what pin caused the interrupt.
Actually, my pin change setup story was not completely correct.
You just setup the pins, and there are 3 interrupts for each AVR port. If you wish to know what pin changed you need to keep a backup register so you can see what pin changed by XORing the backup register with the current port.
10x! this circuit will be very useful for a robot. Not only for robots, but it´s useful for a several circuits.
I hate geeks. I mean really hate them. Particularly the geekier-than-thou kind. “I mean arduino, is soooooooo mainstream dude, real men build their own microcontroller from two pins and a lemon.”
Thank you for walking through a very practical topic on power management. I have a question in the setup section of the code, i have included it below
cbi( SMCR,SE ); // sleep enable, power down mode
cbi( SMCR,SM0 ); // power down mode
sbi( SMCR,SM1 ); // power down mode
cbi( SMCR,SM2 ); // power down mode
My question is why is it necessary here, you are executing set_sleep_mode(SLEEP_MODE_PWR_DOWN);
and sleep_enable() in the system_sleep() function.
I did not follow the need for having it in the setup() as well. Would appreciate if you can shed some light on what i am missing?
Please be kind and respectful to help make the comments section excellent. (Comment Policy)