How to save power on Arduino boards?

Saving power has become a main concern when designing electronic circuits and it is now mandatory to incorporate a power saving system to get the CE certification.

Hence microcontrollers like the Atmega328 incorporate a full set of energy economy functions. Section 10 of the Atmega8 to 328 datasheet explains the “Power Management and Sleep Modes”.

There are two possibilities to configure energy consumption on this chip.
1) Enabling or disabling individual functions
2) Enabling or disabling sets of functions by putting the microcontroller in a specific “sleep mode”

By programming its registers the user can precisely control which sub-systems are running and which are not. But Arduino does also provide high-level functions to configure the microcontroller.

Power

The power.h library includes tens of functions to save power on Arduino by enabling or disabling individual sub-systems of the microcontroller. For example the user may activate the ADC converter simply by invoking the power_adc_enable() function and de-activate it by using power_adc_disable().

Not only “saving power is good” Happy face but disabling unused sub-system is generally best for reducing noise.

Using this library only requires to add the #include <avr/power.h> directive at the top of the sketch.

Sleep

The sleep.h library allows to put the microcontroller in a “sleep mode”, i.e. a configuration with a preset of enabled/disabled functions. The Atmega8-328 datasheet defines these sleep modes in the table 10-1.

Active clock domains of the Atmega328

Active clock domains of the Atmega328

 

Some of these modes save only very little power, others are putting the microcontroller in nearly total standby. These current consumptions have been reported:

Full power Uno board (with voltage regulators, USB chip and leds…): 49 mA

Standalone Atmega328: 15.5 mA

Standalone Atmega 328 in sleep mode:
SLEEP_MODE_IDLE: 15 mA
SLEEP_MODE_ADC: 6.5 mA
SLEEP_MODE_PWR_SAVE: 1.62 mA
SLEEP_MODE_EXT_STANDBY: 1.62 mA
SLEEP_MODE_STANDBY : 0.84 mA
SLEEP_MODE_PWR_DOWN : 0.36 mA

Using these power saving modes is not totally trivial since they de-activate some parts of the microcontroller, hence it may be impossible to bring the microcontroller to the original mode if not well programmed. Anyway a RESET will always wake up the microcontroller.

If the microcontroller is placed in the SLEEP_MODE_PWR_DOWN basically it will wakeup only after an interrupt on INT0 or INT1 or on another pin. In this case the common technique of programming will include an interrupt based on INT0 or INT1. In theory other pins could wake up the microcontroller but the usual configuration of the pin must be changed by setting PCIE0 and PCMSK0 registers.

A typical implementation of sleep mode is given here:

 

void wakeUpInterrupt() {
// Interrupt handler
// place short specific code here
}

void enterSleepMode() {

//Defines sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);

// attaches an interrupt on pin 2 (INT0)
attachInterrupt(digitalPinToInterrupt(2), wakeUpInterrupt, LOW);

// put to sleep
sleep_mode();

// wake up here

// avoid continuous firing of the Interrupt
detachInterrupt(digitalPinToInterrupt(2));
}

 

wakeUpInterrupt(void) is a handler that will be invocated when the Interrupt happens. The code put here should be very short since the Interrupt is still active.

Putting the microcontroller in sleep mode is done by setting its sleep mode set_sleep_mode(SLEEP_MODE_PWR_DOWN) then running sleep_mode().

The Interrupt is attached by: attachInterrupt (digitalPinToInterrupt(2), wakeUpInterrupt, LOW);
· The pin that will trigger the interrupt is positioned by digitalPinToInterrupt(2)
· The interrupt handler is specified
· The level of the signal that triggers the interrupt is specified. One of these values are supported: LOW, CHANGE, FALLING, RISING and HIGH on the Arduino DUE

After the sleep_mode() function is invoked the board is effectively placed in the sleep mode chosen. When the signal reaches a low level on pin 2, the Interrupt handler runs and the program resumes. The Interrupt is detached.

This is a practical and straightforward implementation that is used in the program of the Arduino compatible frequency counter.

Using this library only requires to add the #include <avr/sleep.h> directive at the top of the sketch.

A complete discussion about how to save power on Arduino can be found here: Power saving techniques for microprocessors.

 

Enregistrer

Leave a Reply

Your email address will not be published. Required fields are marked *