Low-Power: sleep an AVR Arduino to save the battery
Low-Power, from Rocket Scream, wraps the AVR鈥檚 sleep modes in one call each. powerDown(SLEEP_8S, ADC_OFF, BOD_OFF) switches almost everything off for about eight seconds and lets the watchdog timer wake the chip, which is how a battery sensor node reads once a minute and sleeps the rest of the time. SLEEP_FOREVER sleeps until an interrupt, such as a button on pin 2, wakes it.
Built in on Mokxi: #include <LowPower.h> and it builds, with nothing to install. Free, and no account needed.
What Low-Power does
The watchdog periods are fixed: 15 ms, 30 ms, 60 ms, 120 ms, 250 ms, 500 ms, 1, 2, 4 or 8 seconds. For longer gaps a sketch sleeps 8 seconds in a loop and counts. In power-down the timers stop, so millis() does not advance while the chip sleeps, and code that measures time with millis() needs to add the slept periods itself.
The library only puts the chip to sleep. On an Uno or Nano the USB chip, the power LED and the regulator keep drawing several milliamps, so the real savings come on a bare ATmega328P or a Pro Mini with its LED and regulator removed.
| Library Manager name | Low-Power |
|---|---|
| Author | Rocket Scream Electronics |
| Include | #include <LowPower.h> |
| Boards | Arduino Uno, Arduino Nano, Arduino Mega 2560, Arduino Leonardo, SparkFun Pro Micro, Arduino Micro, Arduino Pro Mini 3.3 V |
| In the simulator | Runs, with a gap the note below names. |
Install it
It builds on Arduino Uno, Arduino Nano, Arduino Mega 2560, Arduino Leonardo, SparkFun Pro Micro, Arduino Micro, Arduino Pro Mini 3.3 V.
In Mokxi it is built in: #include <LowPower.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Low-Power" by Rocket Scream Electronics from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add Low-Power to lib_deps in PlatformIO. Mokxi follows the calls of release 1.81, so a sketch written here builds there too.
What to know in the simulator: The sleep and the stopped millis() are simulated; the current the chip draws is not, so the battery savings cannot be seen.
Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 Arduino Pro Mini 3.3 V
The calls you will use
In the order a sketch meets them.
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF)
The deepest sleep, for about 8 seconds, with the ADC and brown-out detector off. Execution carries on after the call when it wakes.
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF)
Sleeps until an interrupt wakes the chip. Attach the wake-up interrupt first.
void wake() {}
attachInterrupt(digitalPinToInterrupt(2), wake, LOW);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
detachInterrupt(digitalPinToInterrupt(2));LowPower.idle(SLEEP_1S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF)
The lightest sleep: the CPU stops but chosen peripherals keep running. Each _OFF argument switches one off for the sleep.
LowPower.powerSave(SLEEP_4S, ADC_OFF, BOD_OFF, TIMER2_OFF)
Like power-down, but Timer2 can keep running from an external crystal, as a real-time clock.
LowPower.powerStandby(SLEEP_2S, ADC_OFF, BOD_OFF)
Power-down with the main oscillator left running, so it wakes faster.
LowPower.adcNoiseReduction(SLEEP_15MS, ADC_OFF, TIMER2_OFF)
A sleep made for taking a quieter analog reading, with the CPU and its noise stopped.
Example: Sleep for a second
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include "LowPower.h"
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long before = millis();
Serial.println("going to sleep");
Serial.flush();
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
// In power-down timer 0 stops, so millis() does not count the sleep.
unsigned long slept = millis() - before;
Serial.print("awake; millis() moved ");
Serial.println(slept < 20 ? "hardly at all" : "a lot");
delay(100);
}Common errors and how to fix them
LowPower.h is for the ATmega boards (Uno, Nano, Pro Mini, Mega, Leonardo) in Mokxi.
Mokxi stops the build with this on other boards, since the library drives AVR sleep registers. An ESP32 has its own esp_deep_sleep_start() and timer wake-ups; on the other boards, delay() waits the same time here.
The board never wakes from SLEEP_FOREVER
Nothing is attached to wake it. Attach an interrupt on pin 2 or 3 (LOW level works from power-down) before sleeping, and detach it after waking so it does not fire over and over.
Timing with millis() is wrong after sleeping
Timer0 stops in power-down, so millis() does not count the time asleep. Add 8000 to your own counter for every SLEEP_8S, or keep time with an RTC module.
The battery still drains in a day on an Uno
The chip sleeps, but the Uno鈥檚 USB chip, regulator and power LED do not. Use a Pro Mini or a bare ATmega328P, remove the power LED, and power it straight from the battery to reach microamps.
Keep going
Learn
Try Low-Power without installing anything
Open the example, change the sketch, and keep your version in a free account.