Main Content

Saving Power On An ESP8266 Web Server Using Delays

ESP8266 core support on Arduino comes with a library that allows you to quickly setup and run a web server from your device. Commonly the code using the ESP8266WebServer library looks something like the following:

#include <ESP8266WebServer.h>

ESP8266WebServer server(80);

void setup(void)_
{
... various wi-fi and request handler setup calls here ...
}

void loop(void)
{
server.handleClient();
}

For a more concrete example, take a look at the “Hello World” example that is included with the library.

In the following we’ll focus on the loop() and ignore the rest. As the name implies, the Arduino framework calls the loop() function in an infinite loop. The handleClient() method checks if any client has connected over the Wi-Fi network and issued an HTTP request. If so, it handles the request and sends a response back to the client. If not, it exits immediately, doing nothing.

In other words, loop() implements a busy-wait for HTTP requests. Even when there is nothing to do, the CPU still runs the busy loop roughly 100000 times per second. In the common case where a page is only requested from the server every once in a while, the system will spend almost all of its time in this state.

Busy loops are common on microcontrollers. On an ATmega microcontroller, another popular target for Arduino code, this is hardly a problem. Unless you’re running your hardware off a battery and really counting every microwatt, a busy CPU uses negligible extra power over a CPU that’s sleeping. The ESP8266 is a bit more powerful than an 8-bit microcontroller though and correspondingly has a higher power consumption when not sleeping. Hence it makes sense to be a bit more sensible about when the CPU is running or not.

The best solution would be to not have a busy loop at all. Ideally we could use the underlying RTOS to only schedule a handleClient() task in response to network events. The RTOS is smart enough to put the CPU to sleep when no task needs to run. Unfortunately, the simple Arduino environment does not want us to mess with the RTOS. The ESP8266WebServer library certainly isn’t written with such use in mind. This approach would require a lot of refactoring of ESP8266WebServer and the code that uses it.

A simpler way is to slow the busy loop down. There is no need to check for client connections hundreds of thousand times per second. A more modest rate would be good enough and the CPU can sleep in between. This would decrease the power consumption at the cost of the response time for HTTP requests. Inserting the Arduino-provided delay() function into loop() does exactly what we want:

void loop(void)
{
server.handleClient();
delay(...);
}

The question that remains is what is a good value to choose for delay in this case. What value gives the best trade off between decreased power consumption and increased response time?”

Link to article