About a year and a half ago I posted about the power consumption observed running Toit on the ESP32 Huzzah. Since then, there have been a couple of developments that significantly reduce power consumption.
Deep sleep
The first, was support for deep sleeping the ESP32 while not being used.
In a lot of typical programs, the code starts, runs some initialization, then enters a potentially indefinite while true:
loop where you do some task, then long sleep. The loop is explicit and all your program state is preserved during sleep.
Deep sleep is a special processor mode, that shuts down much of the processor, memory and peripherals, to drive current consumption from mA to uA. Various options are available for waking the processor, typically time and select peripheral activity.
When programming for deep sleep, you write your code to run until the deep sleep command. There is no initialization, then code run within an explicit loop. Rather all your code runs within an implicit loop, formed by the processor waking periodically and rerunning the code. (You can query for the reason the processor woke, but for this example, it is based on duration). To save the maximum power during deep sleep, no memory (and thus program state) is saved between executions. All initialization code, for say an i2c bus, must also be rerun. Development with JAG is also complicated because during deep sleep, the processor is non-responsive to the JAG console.
To enter deep sleep, you invoke:
deep_sleep duration/Duration -> none
Enters deep sleep for the specified duration (up to 24h) and does not return.
Exiting deep sleep causes the ESP32 to start over from main.
A short writeup on Reporting data from a ‘sleepy’ device outlined using the technique to report temperature/humidity/pressure data over MQTT-SN. The program main
is run until the deep_sleep command is encountered, the ESP32 enters deep sleep for the nominated period, and then the processor is rebooted. Since no data is retained between executions, it was necessary to power the radio on each cycle and transmit the data.
Testing with a 500mAh battery demonstrated the ESP32 + BME280 hardware could run for 26 days between the usable LiPo battery limit voltages of 4.2 - 3.4v.
Report periodically, using Buckets
A few weeks ago, support for Bucket storage in RTC RAM and Flash, was introduced allowing data to be saved across reboots and power cycles respectively. It is proposed to acquire and save the data to a persistent bucket on some period, say 10 minutes, and then on a longer period, say 8 hours, reporting the stored data in a burst. (Note, the MiniStore
class is rudimentary, only suitable for experiments.) The Toit library code keeps the radio off if there is no network usage. The overhead of establishing the WiFi connection to the router and sychronizing the clock with the NTP server, will be amortized across many measurements, which should measurably reduce total radio time (as noted below, the radio consumes considerable power).
To baseline power consumption, the EzSBC ESP32 Feather board was tested with the Power Profiler Kit II (PPK II). For this experiment, the BME280 was disconnected, measuring only board current consumptions and to make the experiment go quickly, data was reported after 4 short 15 second sleeps.
Using this setup, an overview of the power consumption is:
You can see the very low consumption during deep sleep, two peaks around 50mA consumption as the device wakes, reads and records the battery voltages in RAM, then a major section from 50-250mA as the device powers on the WiFi, connects to the router, transmits the data and re-sychronizes the clock.
In more detail:
Deep sleep power consumption was measured at 9uA, consistent with the vendor’s claim.
The sense battery voltage + store data action, was about 50mA for <0.5sec (this time includes a fixed delay to stabilize the battery voltage measurement).
The send data action, was between 50mA with the processor running and ~130mA during transmit, over a period of ~7 seconds. Since MQTT-SN QoS -1 was used, packets are sent without acknowledgement.
To determine the actual battery impact of reporting data on a different, longer period than acquisition, the sleepy_sensor.toit
code was modified for v2.0 and the long term test is now running. I will update this article when complete.