Adding delays to reduce ESP8266 power consumption
I’m currently working on a small ESP8266 gadget which runs UDP server and does some actions based on packets received.
Main loop goes a bit like this (note: I’m using Arduino core):
void loop() {
size_t size = udp.parsePacket();
if (size > 0) {
// handle the packet
}
}
Looks fine until you remember that ESP8266 is a 32bit micro running at pretty whopping (for $1 price) 80Mhz frequency. So what does it actually do when there’s no packets coming in?
To start with, let’s figure out how many loops it does per second. This can be done by adding a counter and getting frequency by dividing it from time spent once in a while. Or.. If you have a scope, by flicking GPIO pin and measuring it:
void loop() {
digitalWrite(5, HIGH);
size_t size = udp.parsePacket();
if (size > 0) {
// handle the packet
}
digitalWrite(5, LOW);
}
Result:
107 thousand times / second! When with my app I can barely expect tens of packets / second. Which pretty much means that we’re burning CPU cycles needlessly.
Let’s add some delays (4ms in total) then and see what happens:
void loop() {
digitalWrite(5, HIGH);
delay(2);
size_t size = udp.parsePacket();
if (size > 0) {
// handle the packet
}
digitalWrite(5, LOW);
delay(2);
}
Result:
Loop now runs at little more reasonable ~250 times / second. Should deal with tens of packets / second without human noticeable delay.
And the best part of that is power consumption change (logged by R&S HMC8043 power supply):
Without delays - constant almost 80mA current consumption. With delays - baseline 20mA current with spikes during modem wake ups.
Project details with Jupyter notebook to generate the plot here. And a very useful Espressif board post about esp8266 power modes.