The microcontroller industry has been aggressively focused on ultra-low-power silicon, enabling applications that outlive the typical shelf life of many batteries. As vendors push technologies and skip process nodes, gone are the days of milliamps. Microcontrollers have entered a world of microamps and nanoamps thanks to innovative use of lower-power standby modes, intelligent analog peripherals, power gating, and other silicon advancements.
Without the use of efficient, well-written software, however, the capabilities of these ultra-low-power micrcontrollers cannot be fully realized. In some cases, batteries can drain 100 times faster if the application’s firmware is not written for ultra-low-power efficiency.
As the microcontroller industry provides customers with more ultra-low-power microcontroller options, the final frontier for true low-power dominance is ensuring developers are writing intelligent software that maximizes the unique features integrated into microcontroller hardware. Efficient code can be the difference between a typical battery-operated application and one that operates battery-free.
First, let’s think about a few typical microcontroller applications such as smoke detectors, TV remotes, or motion detectors controling the lights installed in many garages. Now, think about what these applications have in common. Most microcontroller applications sit in standby mode for 90 to 99.9% of the time. Smoke detectors, for example, are usually sleeping, waking up periodically to sense for the presence of smoke in a building. TV remote controls are only awake when needed to change channels, and the motion-activated light only turns on when a car enters the garage.
Many modern microcontrollers provide various modes of operation, often called “standby,” “sleep” or “low-power” modes. These modes are enabled by a flexible and orthogonal clocking system. This means the microcontroller device and its integrated peripherals such as analog-to-digital converters (ADCs), timers and serial communication modules can be sourced by various clock and timing sources. With this feature integrated into the hardware, peripherals are able to operate sans-CPU, allowing the CPU to be turned off reducing overall current consumption. This means ADCs can take samples, timers can keep count and serial communication modules can transfer data all in a low-power mode without any CPU intervention.
software (most microcontroller applications should be in a
low-power mode 90-99.9% of the time).
Another good exercise is to look at a microcontroller datasheet. Within the one-hundred-or-so pages, developers will typically find current consumption numbers for these various modes of operation. Active mode current consumption with the CPU turned on can operate between 100 to 500 uA/MHz, while the CPU-less low-power standby modes can operate well below 1uA. While the datasheet shows impressive numbers, developers should take a look at the code to ensure this level of low-power operation is seen with actual measurements. With this in mind, software rule number one is to leverage a microcontroller’s low-power standby modes and its interrupt-capable hardware within the microcontroller code.
Microcontroller applications should jump to low-power modes whenever the CPU is not required. This is more frequent when intelligent peripherals are available and integrated into the microcontroller device. An example is the 16-bit MSP430 microcontroller from Texas Instruments (TI). This device can take ADC samples, keep count with timers, generate PWM signals and more, all without the CPU. Developers should consider the use of a low-power mode if their software is doing things like waiting for time to elapse or polling a flag as discussed below…
Waiting for time to elapse
In the example applications discussed earlier, actual work was only required periodically. This is especially clear in the smoke detector example, where a sensor is only read for fractions of a second every few minutes. There are several ways to do this; the easiest being an empty for or while loop that will run its course until a condition is met. Once the empty loop is completed, the rest of the code can finally run. To bring this point across, let’s simplify the application to a blinking LED. The LED should toggle on or off after a period of time has elapsed, similar to the smoke detector that must sample the air periodically.
Additionally, many compilers provide intrinsic functions for time delay, which allow developers to quickly add empty instructions to consume time. An example is shown below:
While developers are successful in adding the appropriate delay to their application with the code snippets above, current consumption is unnecessarily high. The application is running in an active mode 100% of the time, burning unnecessary cycles with the CPU turned on and consuming power. Instead, developers should write code that leverages the flexible low-power modes and intelligent timer peripherals integrated into the ultra-low-power microcontroller device. Take a look at the pseudo-code below.
The code above fully leverages the ultra-low-power capability of the microcontroller’s hardware. The microcontroller is still able to blink the LED, or sample the smoke detector sensor, while consuming as little power as possible. Now, the CPU remains off and stays in low-power modes for as long as possible, resulting in best-case average current consumption.Polling a flag
Many times, microcontroller applications have to wait for a task to finish before moving on with an operation. The microcontroller could be waiting for a reference voltage to settle, waiting for a switch to debounce or waiting for ADC samples to complete their conversions. Another example of wasting CPU cycles is when an application is waiting for something to change states or status.
Using the TV remote control example or motion sensitive light setup, these applications are usually in a standby state until a change of status occurs – a button is pressed on the remote, or a car appears in front of the passive infrared sensor. One way of identifying a change of state is to continuously poll the variable that holds the status of the sensor. Let’s take a look at the example code below for the motion detection light application:
In this scenario, the low-power capabilities of the microcontroller are not leveraged. The device is in active mode, consuming power and using the CPU for a task in which it is not needed. Instead of continuously polling the flag, the microcontroller should again use its integrated peripherals that can operate without the CPU. In this case, the interruptible general purpose input/output ports can be used to wake up the microcontroller from a low-power mode. Now, let’s take a look at the pseduo-code below:
In the last implementation, the microcontroller is able to offload more work to its intelligent, integrated peripherals as opposed to using software to continuously check the status of various flags. Once again, the device is able to do more in hardware , staying in low-power modes for longer periods of time, and only waking up the CPU when it is truly needed.
What does this power-saving really mean?
To see the true benefit of power-optimized code, let’s compare two implementations for periodically blinking an LED. First, let’s assume a few things: The microcontroller in question consumes 300uA in active mode and 0.5uA in standby mode, and the application is using a typical CR2032 coin cell battery with 220mAh battery life.
Project A: Project A used a simple empty while loop to periodically blink an LED. This means the application is in active mode 100% of the time, while the application only truly needs to be active for 1% of the time. The non-optimized code is burning CPU cycles when it could actually be sleeping. In this case, our battery life looks like this:
Battery life in hours = 220mAh/300uA
= 733.33 hours
Project B: Project B used an interrupt-driven timer module to periodically wake up the microcontroller at a set duty cycle. This means the application is able to stay in standby mode 99% of the time, and active mode the remaining 1%. In turn, battery life is greatly improved.
Battery life in hours = 220mAh/ average_current_consumption
= 220mAh/ [(300uA * 1%) + (0.5uA * 99%)]
= 62,947.07 hours
In this simplified case, efficient software within Project B enabled huge power savings resulting in 85x longer battery life. 62,947.07 hours equates to more than seven years of battery life, and all of this is realized by a few extra lines of code.
Following the examples discussed in this article will enable developers to write more efficient software for ultra-low-power microcontrollers. Ensuring that microcontroller applications are leveraging the ultra-low-power operation modes of a microcontroller can realize substantial power savings. The examples above are the two most common areas of where a lower-power standby mode can be used, but there are many more. Be sure to review code and understand the device’slow-power capabilities. Some questions developers should ask when examining lines of code include:
- What can the microcontroller peripherals do without the CPU?
- Are there any areas of functions in the application that can can be offloaded to a peripheral
- Is the application waiting for time to elapse without the use of timer-based interrupt?
To help developers identify areas of improvement in power-conscious applications, TI’s ULP Advisor code analysis software tool for MSP430 microcontrollers can help many developers learn ultra-low-power coding best-practices. The tool looks through developers’ code line-by-line and provides tips on how to improve the efficiency of the microcontroller’s code.
By following these simple rules within future microcontroller projects means microcontrollers will spend more time in a sub-1uA sleep mode as opposed to a 100uA or more active mode. Happy coding! The only thing better than recycling used batteries, is not using them at all.
Adrian Fernandez is a product marketing engineer for Texas Instruments’ ultra-low power MSP430 microcontroller (MCU) product line. In this role, Adrian is responsible for development tool strategy and outbound marketing for MSP430 MCUs. Adrian holds a Bachelor of Science in electrical engineering from the University of Texas at Austin, concentrating on embedded systems and digital signal processing.
This article was previously published on MCU DesignLine