When I asked the potential users of the frequency counter I am working on their advice on the design, most of them wrote to me that they actually would...
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.
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” 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.
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.
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:
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.