You might not think about it, but, on average, you utilise hundreds of microcontrollers (MCU) in a day. Everything from your toothbrush to your car has one or more MCUs inside them, and the number of MCUs you rely on is growing with the rapid adoption of the Internet of Things (IoT) movement.
Historically, users wanted MCUs because they could process data and solve problems faster than a human could. MCUs also help make products more convenient and consistent in behaviour. The microcontroller speed or frequency indicates how fast data is processed and problems are solved. Speed is generally not a big problem anymore. The challenge now is that the MCU needs to be able to solve more complex problems while it is being put on a power diet.
Let’s face it. We all get a little worried and start looking for power outlets when our computer or smartphone battery gets close to zero. Imagine if all your battery-powered products required daily charging. To prevent this, we need to put our devices on a budget. They need to become energy efficient.
What is inside embedded applications?
At a high level, all embedded applications are strikingly similar. Everything from industrial products, like water meters and security sensors, to personal items, including smart wearables, are built from a number of components. These components are connected to each other to solve specific tasks.
A typical application includes many building blocks. Here is a list of categories and some common components and functions:
• Power management: battery, regulators, energy harvesting, energy storage.
• Microcontroller: the brain.
• MCU support: extra MCUs/co-processors, memories, external RTCs.
• Sensors/input: PIR, light, HRM, IMU, GPS, rotation count, capacitive touch.
• Actuators/output: display, LED, audio, motor control.
• Wired connectivity: USB, UART, I2C, Ethernet, CAN, PLC.
• Wireless connectivity: radio/RF, Bluetooth Smart, ZigBee, Thread, proprietary, NFC.
All of these components consume energy from your power source. So, when building an energy-efficient system, logic dictates that you should choose components within your budget that are inherently energy efficient. This is sometimes difficult because many of the items listed above are highly integrated and combine functionalities. For example, in Silicon Labs’ Bluetooth Smart MCU, the Blue Gecko, both the Bluetooth radio device and the MCU are combined, so the user only needs one device.
A single application might use multiple power sources, but common across these energy sources, beyond the wired option, is that minimising current consumption is key. For example, if you’re building a wired home automation system, you may include a backup battery in case there is a power outage. This helps ensure that not all functionality is lost in an emergency.
The following are topics to think about when choosing an energy source for your application:
• Mobility – Can the device move? Does it need to be near a socket?
• Lifetime – For how long can the device live before it needs maintenance?
• Cost – How expensive is this energy source?
• Form factor – What size restrictions does my product have?
Designing with batteries
Let’s say you’re a designer and the specification states that the product or application needs to last for at least three years. You’ve decided to use batteries as the energy source. Now you need to make a trade-off between lifetime, form factor and cost.
Let’s consider these two coin cell options:
Option A: CR1616, which comes in a 16 mm (diameter) x 1,6 mm (height) package with 55 mAh capacity.
Option B: Common CR2032, which has 20 mm (diameter) x 3.2 mm (height) dimensions with 210 mAh capacity.
With the CR2032, the average current consumption of your application needs to stay below 8 µA in order to get the desired lifetime of three years, based on a very simple model of the battery. If you go with the CR1616, the application must consume less than 2 µA to achieve the same lifetime. By making your application consume less than 2 µA, you go for the smaller battery, and thus get to a smaller form factor for the product.
Surprisingly, the smaller battery in this case actually has a higher cost than the larger one, so the current consumption reduction does not give a cost improvement when switching from the larger battery to the smaller. However, imagine switching from two of the CR2032 batteries to a single CR2032. That gives both a form factor and a cost improvement. Whether a single smaller battery has lower cost than a bigger one can depend on multiple factors, including product demand and availability.
If your application is a wearable or other rechargeable accessory, you may want to bypass coin cells altogether and explore the lithium polymer batteries.
Designing with energy harvesting
In general, energy harvesting looks like a very attractive solution. You just use the surroundings to generate the energy you need. But, as with batteries, energy harvesting has trade-offs to consider. Is the power source reliable? Is your power converter efficient enough?
Let’s consider the sun, which is a pretty reliable and sustainable power source. Solar harvesting panels must be in a bright location, and they need to have a given surface area. They might be able to generate 10 mW/cm2 under direct sunlight, but can drop to 10 µW/cm2 when indoors. That is 1000 times less energy to play with. To support night-time operation, a rechargeable battery is needed as well, which increases cost and penalises form factor.
Designing with wireless power
Wireless power delivery, also known as remote power delivery, is similar to energy harvesting in that your application picks up energy from its surroundings. The difference is that in this case, energy is not assumed to be present, in the form of light, vibration, or other natural energy source. A power transmitter generates the energy the application is supposed to pick up.
The challenges with remote power delivery are somewhat similar to those of energy harvesting. For inductive power delivery, the transmitter is generating an alternating magnetic field, and the receiver uses a coil to capture the energy. In this scenario, the maximum distance between the transmitter and the receiver, and also the amount of power that can be delivered, is based on the size of the coil. This puts constraints on form factor and flexibility.
Qi and A4WP are two emerging standards for inductive wireless charging, which is currently being used in a number of smartphones and wearables. These require the receiver and transmitter to be in very close proximity, and allow very little mobility. They are thus really only suitable for applications such as wireless charging.
Another method of remote power delivery is based on radio frequencies. By outputting a strong radio signal and using beamforming techniques, a transmitter can send a signal carrying sufficient energy to a receiving antenna. Challenges with this technology currently include transmission efficiency.
Deciding which energy source to choose for an application depends on the properties of the application itself. The rest of this article will dig into applications that operate from constrained energy sources.
Energy efficiency – the big picture
Sensors are the eyes and ears of an application. When working with a sensor in an application, the straightforward approach is to leave the sensor on all the time, as shown in case A of Figure 1. With this approach, the MCU can read the voltage across the variable resistor at any time, and calculate the current temperature based on the voltage.
This option is the easiest way to control the sensor, but it’s also the method that consumes the most energy. Now, 33 µA might not seem like much, but when a solar cell that small only produces 10 µW of current, we quickly see the problem. A better setup is shown in case B of Figure 1, where the MCU is able to control the power of the sensor directly, turning it on only when needed.
For an application that only needs to measure temperature once per second, the current consumption of the thermistor is now reduced to 0,165 nA. Assuming that you keep it on for 5 µs in order to sample it once every second, this approach gives you a 200 000x improvement in current consumption.
When controlling the supply of external components through a pin on the MCU, you have to clearly define the default state of these circuits. On Silicon Labs’ EFM32 products, all pins are floating when the device comes out of reset, which, in this scenario, is not an issue.
For a device with default-low I/O, you want to connect the sensor as shown in case B of Figure 1. But if the I/O comes out as default-high, you should connect the other end of the resistor divider to VDD (supply) instead of ground. This will prevent current consumption through the sensor during MCU reset.
An application can consist of a number of components and you have to make a decision on how to control each component in the most efficient way. Note that designing for energy efficiency actually has a cost. In the thermistor example above, an extra MCU pin is required to control the power to the thermistor.
Additional attention to efficiency also has to be given during software development.
Designing for energy efficiency can in some ways be harder than designing a system that does not care about efficiency. But in energy-constrained systems, it is well worth the investment.
What about the MCU?
We discussed that the application components must be duty-cycled in order to maximise efficiency. The same is true for the MCU itself. Because they are more sophisticated components, MCUs almost always have more than just an on/off button. MCUs have multiple energy modes, where each mode allows a set of capabilities with an associated current consumption overhead.
Table 1 shows an overview of the energy modes of the EFM32 MCUs. The Run mode (EM0) has all functionality available. As the MCU goes to deeper energy modes, less functionality is available, but drastically lower current consumption can result. There are two key takeaways from this table:
1.The CPU is only available in the highest energy mode. In order to reap maximum benefits, the CPU must be turned off whenever it is not needed. The system must aim to sleep as much as possible.
2.The system should sleep as deeply as possible whenever it’s sleeping. With deeper sleep, less functionality is available. Thus, the right modes have to be chosen to allow the system to sleep as much and as deeply as possible.
By requiring the CPU to be off as much as possible in order to save energy, the CPU tasks must be offloaded to the hardware in the MCU. Instead of being in a paradigm where software running on the CPU does everything, software development should focus on setting up hardware to do the heavy lifting and only intervene when hardware needs assistance. In other words, hardware should be the main driver of the application.
This takes the system to an event-driven architecture, allowing massive energy savings. A system using the traditional approach running at 10 MHz would consume more than 1,1 mA, while a system using the event-driven approach would consume as little as ~0,9 – 1,3 µA, depending on the sensor and sample rate. This is almost a three-orders-of-magnitude difference. More importantly, it’s the difference between a day and multiple years of battery life.
With the traditional approach, the CPU does everything, and can only manage a limited number of functions. With the event-driven approach, the CPU is freed up because hardware does the bulk of the work. With this method, an MCU can drive sophisticated applications.
On an MCU with minimal Flash and RAM resources, this is how you should write code. With this kind of multi-tasking you can get the absolute most out of the hardware in the MCU, both in terms of performance and energy savings. We call this ‘coding down to the metal.’
Spending some of the MCU resources on an embedded operating system provides a level of abstraction that makes building sophisticated, event-driven applications easier, but potentially less efficient. For applications running on MCUs with 512 KB Flash or more, the memory overhead can be negligible, making this an easy choice.
On MCUs with 32 KB Flash or less, there are still operating systems that can do the job, but the percentage of the MCU resources used by the OS increases drastically. A minimal configuration of FreeRTOS requires between 5 KB and 10 KB Flash and a minimal amount of RAM.
For complex applications, an operating system might actually make the system more efficient than coding to the metal. This approach gives software developers a framework for how to write code to use energy modes in the most efficient way.
Some operating systems or ecosystems to check out include ARM mbed OS, FreeRTOS and RTX. They all provide tick-less sleep modes, meaning that unlike normal PC operating systems that always waste energy by waking up every 1 ms or 10 ms, these operating systems only wake up when they are needed.
Optimising the system
It is relatively simple to cater for a system dealing with a single function and a single source of wakeups, but imagine a system with 10 different components that need to be managed. Some can be controlled fully autonomously, while for others the CPU might have to wake up periodically in order to take control.
If care is not taken with such a system, it can end up in a situation like the one shown in case A of Figure 2, with many more wakeups than necessary, resulting in a less efficient system.
The figure shows two deterministic processes, which execute periodically, and one sensor event, firing non-deterministically. In case A, the processes arbitrarily wake up to perform their tasks, which results in a total of 11 wakeups, wasting a significant amount of energy due to the time it takes to transition between sleep modes.
To improve on case A, you can do sleep planning. For all deterministic processes, i.e., processes we know of beforehand that are going to require a wakeup, care should be taken to align the wakeups as much as the system allows, minimising the number of wakeups.
In case B, the wakeups by Process 2 have been aligned with the wakeups from Process 1, resulting in a total of six wakeups during the same period, a significant reduction from case A.
As we have discussed, minimising awake time is important. In many cases, software running on the CPU is waiting for something to happen. If the CPU is set to wait for a fixed time, the best approach is to use a hardware timer. Hardware timers come in a range of types with varying functionality, current consumption and accuracy.
On an EFM32 system, if the CPU needs to sleep for a short number of clock cycles while maintaining full MCU operation, the software should use the TIMER peripheral and place the system in EM1 while waiting. This method will significantly reduce current consumption, and wakeup is instantaneous.
If only EM2-EM4 level functionality is necessary while waiting and the wait-time is more than 31 µs, the period of a 32 768 Hz oscillator, the low-frequency timers LETIMER, RTC or RTCC can be used and the system can go to EM2 for maximum efficiency. If high accuracy is required, a TIMER can be synchronised to the low-frequency timer upon wakeup through PRS to time out the last clock cycles with the accurate high-frequency TIMER.
If wait time is relatively long, i.e., multiple milliseconds, and does not have to be accurate, and the system only needs EM4 functionality while sleeping, sleep can be done using the CRYOTIMER, running on the 1 kHz ULFRCO oscillator for extremely low sleep current in the 100 nA range.
Note that wakeup from EM4 costs more energy than wakeup from EM2, because the wakeup is through a reset, so even though EM4 could be used for sleeping for 5 ms, it might not be the most energy efficient. With sleep times of minutes or more, EM4 starts becoming extremely efficient.
No matter how much you try to optimise for sleep, the CPU needs to execute code now and then. This can include everything from regular application logic to network stacks and signal processing algorithms. The CPU is an important part of the MCU. Here are the top five items to ensure the CPU runs code efficiently:
1. Let the compiler optimise your code. This tip might seem obvious, but make sure the code is compiled with full optimisations enabled. If the compiler is able to do link-time optimisation, use this as well. Code compiled for debugging is inefficient on many compilers, one reason being that values are fetched from memory, calculated and then written back on every operation. Without optimisation, it is also not fully utilising the capabilities of the CPU, which also slows down execution.
2. Target the right architecture. Choose the right CPU for your application and ensure that the compiler creates code optimised for that correct device. For example, Cortex M4 is excellent for bigger applications that contain number crunching. Cortex M3 does not have all the DSP capabilities and no floating point, compared to the Cortex M4, but is still relatively high-performance. Cortex M0+ is the most efficient of the bunch as long as the amount of signal processing is at a minimum. It is excellent for stacks and control logic.
3. Operate at the right frequency. Even though lower frequencies give lower current consumption, it is generally better to finish the job quickly to be able to go to sleep; in other words, a higher frequency might give better energy efficiency. If the different parts of the system have different needs (i.e., USART needs 4 MHz, but the CPU needs 8 MHz), use pre-scalers for clock domains to make the frequency selection optimal.
4. Use available hardware accelerators. Some operations perform more efficiently in hardware than on a CPU. One example is cryptography. The CRYPTO peripheral available on the EFM32 Gemstone devices can complete operations more than 10 times faster and much more efficiently than running them on the CPU. Another example is the alpha blending hardware on some of the EFM32 products. This hardware makes graphics compositing for external displays more efficient.
5. And, of course, sleep whenever possible.