1. Description
This tutorial presents some power-saving techniques available for ATmega328 based designs. They could help in lowering the overall power consumption and preserve battery life (in case of using batteries as a power supply). Even though the examples presented below are originating from a basic sketch (periodic LED blinking), they could easily be ported to various other applications. Each scenario indicates the current consumption measurement and an estimation of the battery lifetime – this could be useful in choosing the right and most effective power-saving technique(s) for your specific applications.
Difficulty level: intermediate.
2. Parts
– 1 x Arduino uno R3 board;
– 1 x Atmega328P-PU in standalone mode (see tutorial Standalone ATmega328P-PU w Reset Button and LED);
– 1 x 9V standard battery (i.e. 6LF22PA);
– 1 x 5V switching power regulator (i.e. S7V7FS) – optional;
– 1 x half-size breadboard & wires.
3. Power-saving techniques for ATmega328P-PU microcontroller
Several power-saving techniques are listed below:
1. Run the microcontroller in a standalone configuration rather than on a development board
The main advantages of using a microcontroller in a standalone configuration are cost, size and power consumption reduction. Details on using an ATmega328P-PU in a standalone mode are presented in Standalone ATmega328P-PU w Reset Button and LED tutorial.
2. Avoid using inefficient voltage regulators; if possible run directly from batteries
Linear regulators (as the one used on the Arduino Uno R3 board) are a great choice for low powered devices where the difference between the input and output is small. Even though they are easy to use, simple and cheap, they are usually energy-inefficient; the power dissipation takes place on the power regulator itself based on the following formula:
power dissipation = (input voltage – output voltage) x load current
Switching regulators are more complex but highly energy-efficient; they are available as modular, compact and reliable chips.
The use of an external battery in conjunction with an efficient switching power regulator is highly recommended.
3. Avoid using power consuming devices (i.e. LEDs, backlit LCDs)
4. Run the microcontroller at a lower frequency and/or voltage (bootloader replacement might be needed)
5. Turn off unneeded internal modules in software (i.e. SPI, I2C, Serial, ADC)
By turning off unused internal modules, some power could be saved as well. Various macros (part of the <avr/power.h> library) could be used to turn on or off individual modules:
Module | Enable | Disable |
ADC converter | power_adc_enable() | power_adc_disable() |
SPI | power_spi_enable() | power_spi_disable() |
USART | power_usart0_enable() | power_usart0_disable() |
Timer 1 | power_timer0_enable() | power_timer0_disable() |
Timer 2 | power_timer1_enable() | power_timer1_disable() |
Timer 3 | power_timer2_enable() | power_timer2_disable() |
I2C | power_twi_enable() | power_twi_disable() |
6. Turn off brown-out detection
Brown-out detection is a mechanism used by the microcontroller in order to detect low voltages; when a brown-out occurs, the microcontroller resets. Disabling the brown-out detection could save some power, especially if using batteries as a power supply. It can be done permanently (by using bootloader fuses) or temporary (through software, as illustrated in some of the examples below).
7. Turn off the watchdog timer if not needed
8. Put the processor to sleep when unused
Various sleep modes are available with different impact on power consumption. Some examples below are using the power-down-mode that offers the maximum power saving.
9. Wake the microcontroller from sleep only when needed
To wake up the microcontroller from the sleep mode, the internal watchdog timer could be used: each time its (pre-programmed) prescaller value is reached, an interrupt is used for waking up the microcontroller; the watchdog’s timeout can be set from 15 ms up to 8 s. Some examples below are using an 8 s timeout.
10. Turn off (with a MOSFET) external devices (i.e. SD cards, temperature sensors) until needed.
4. Test scenarios, results and formulas
Test scenarios in the table below are using either a standard Arduino Uno R3 development board or a standalone ATmega328P-PU microcontroller (for schematics and details see tutorial Standalone ATmega328P-PU w Reset Button and LED). Assemblies are shown in the photos below.
Each test scenario’s details and results are presented in the table below.
Notes.
1. Vin connects directly to the Arduino Uno’s regulator’s input and immediately after the barrel jack socket’s diode. Take note that the Vin input is not protected by polarity inversions.
2. External power regulator used: 5V switching step-up/step-down voltage regulator (S7V7FS).
3. The formulas used for computing iavg and battery life are presented below:
5.Code
s_123.ino – code for test scenarios A, B and D:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/*------------------------------------------------------------------------------ Program: s_123.ino Description: Basic blink LED sketch for testing scenarios A, B, D. Hardware: Arduino Uno R3 or standalone ATmega328P-PU setup Software: Developed using Arduino 1.8.2 IDE References: - Atmel ATmega328-328P_Datasheet: http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf Date: May 22, 2017 Author: G. Gainaru, https://www.arduinolab.net ------------------------------------------------------------------------------*/ void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { for (int i = 0; i < 4; i++) { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); delay(50); } delay(8000); } |
s_5689.ino – code for test scenarios C and E:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
/*------------------------------------------------------------------------------ Program: s_5689.ino Description: Basic blink LED sketch for testing scenarios C, E. Hardware: Arduino Uno R3 or standalone ATmega328P-PU setup Software: Developed using Arduino 1.8.2 IDE Libraries: - AVR/sleep.h (included w Arduino IDE); - AVR/wdt.h (included w Arduino IDE); References: - Atmel ATmega328-328P_Datasheet: http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf Date: May 22, 2017 Author: G. Gainaru, https://www.arduinolab.net ------------------------------------------------------------------------------*/ #include <avr/sleep.h> #include <avr/wdt.h> void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() { for (int i = 0; i < 4; i++) { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); delay(50); } goToSleep(); } // watchdog interrupt ISR (WDT_vect) { wdt_disable(); // disable watchdog } void goToSleep () { // disable ADC ADCSRA = 0; // clear various "reset" flags MCUSR = 0; // allow changes, disable reset WDTCSR = bit (WDCE) | bit (WDE); // set interrupt mode and an interval WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay wdt_reset(); // reset the watchdog set_sleep_mode (SLEEP_MODE_PWR_DOWN); noInterrupts (); // timed sequence follows sleep_enable(); // turn off brown‐out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); interrupts (); // guarantees next instruction executed sleep_cpu (); // cancel sleep as a precaution sleep_disable(); } |
6. Additional resources
References:
– From Arduino to a Microcontroller on a Breadboard: https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard
– Building an Arduino on a Breadboard: https://www.arduino.cc/en/main/standalone
– Pololu 5V Step-Up/Step-Down Voltage Regulator S7V7F5: https://www.pololu.com/product/2119
– Atmel ATmega328-328P_Datasheet:
http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf