IoT is more and more popular in all sectors of society. Smart home appliances, smart factories, and smart cities all rely on data gathered by thousands of tiny devices scattered around the sites. These devices need to work for long periods of time, maintenance-free, often in remote or inaccessible locations. It is difficult to provide power for a fleet of thousands of devices, this is why a lot of them rely only on battery power – without access to the electrical grid. This article aims to showcase how do IoT devices manage to stay powered for months or even years at a time. We have chosen an Espressif ESP32 MCU as our platform, as it is well suited for the job, and has WiFi radio build in.
Where is the power going?
An IoT device usually consists of a microprocessor, radio transceiver or some kind of wired communication interface, sensor suite and sometimes actuator assembly. For this article, we will assume, the device consists of the ESP32 MCU with a DHT22 temperature and humidity sensor, so no actuators are present. We are going to update our gathered data to the internet via a WiFi link, and the available Bluetooth interface is going to remain disabled..
The ESP32 MCU consists of several modules hidden inside the enclosure. The main components of the MCU are:
- WIFI radio,
- Bluetooth radio,
- Peripherals (GPIO, UART, I2C, etc.),
- Ultra Low power coProcessor (ULP),
- Real-Time Clock (RTC).
From the datasheet, we can extract some interesting information. First of all, the modules listed above can be switched on/off on the fly. This is very good news as we definitely don’t need all of them all the time.
Reading further through the datasheet we can see the average current consumption of the working modules, for example, a WiFi circuitry can consume up to 240 mA during transmission. Working in these conditions would kill any reasonably sized battery in a matter of hours, not very impressive for an IoT device.
The most common and efficient way to avoid the issue is to simply avoid using power-hungry parts of the device for as long as possible. That’s why a typical operating cycle of an IoT device looks something like this:
As you can see, not all this much time is spent using WiFi in the grand scheme of things. For the most time, the device just sits idle, waiting for time to pass. This is why it is important to make use of all available means to reduce power consumption while simply waiting. Power savings for other modes (booting, gathering, sending) are becoming less and less relevant, the longer we extend our scope of working time. This is why optimizing power usage while idle is the most important thing to do.
MCU Power Modes
All MCUs have some kind of power-saving features. In the case of ESP32 most notable things we can do is switch off the radio and make use of one of the sleep modes available. Using the sleep modes, however, reduces the MCU functionality quite a bit, so compromises must be made. Let’s make a quick rundown of what modes can we use, and what do they offer:
So let’s just always use Deep Sleep while idle and we’re done, right? Not quite – deep sleep is a very special mode, as power is being cut not only from the CPU but also from main RAM memory – all the data stored, all peripheral settings and configurations will be lost, with only a single interrupt flag indicating that the chip has awoken, indicating that this is not a normal power-up sequence. This requires us to reinitialize everything, GPIOs, communications interfaces like UART or I2C and WiFi radio. This can take a lot of time, especially when there is an Operating System wrapping everything together. Going into a deep sleep only makes sense when the expected sleep period is significantly longer than boot time and expected operation time. The boot time has not been officially stated in the datasheet, but from real-world measurements, we can estimate it to be around 250-350 ms for a small to a medium-sized application while running on FreeRTOS. In the scenario when we want to sample a sensor every two seconds, it clearly doesn’t make sense to go all the way into a deep sleep, as MCU during boot time would consume far more energy than just light sleeping through the whole period.
On the other hand, when we don’t want to sample data that frequently and 30s sampling period is fine for our application, stepping to deep sleep is an obvious choice.
Of course, there are more factors for optimizing IoT device battery lifetime like selecting power-efficient sensors and creating custom PCB with only necessary components. Nonetheless, most of the optimizations can be achieved within designing proper MCU workflow.