Professional Documents
Culture Documents
Reducing WiFi Power Consumption On ESP8266, Part 3 - OppoverBakke
Reducing WiFi Power Consumption On ESP8266, Part 3 - OppoverBakke
Reducing WiFi Power Consumption On ESP8266, Part 3 - OppoverBakke
OppoverBakke
…that means "uphill" for the rest of us
Welcome to part 3 of this series on reducing WiFi power consumption on ESP8266 chips.
Earlier, I have established the baseline power consumption and shown how to reduce this a bit by disabling the radio when it is
not needed.
This time, I’ll take it a step further by showing how to make sure the radio is needed for a shorter period of time.
In the first part I showed that in my case, where the ESP8266 wakes up every 5 minutes to read some sensors and transmit the
results to the server. This whole process takes 8.3 seconds, and a whole 6.45 seconds of this is taken up by the ESP8266
establishing a connection to the WiFi network and configuring itself by DHCP.
I mentioned before that the ESP8266 will persist the network connection information to flash, and then read this back when it
next starts the WiFi function. It does this every time, and in my experiments I have found that this takes at least 1.2 seconds.
There are cases where the WiFi function would crash the chip, and the WiFi would never connect.
The chip also does this even when you pass connection information to WiFi.begin(), i.e. even in the case below:
This will actually load the connection information from flash, promptly ignore it and use the values you specify instead,
connect to the WiFi and then finally write your values back to flash.
This starts wearing out the flash memory after a while. Exactly how quickly or slowly will depend on the quality of the flash
memory connected to your ESP8266 chip.
The good news is that we can disable or enable this persistence by calling WiFi.persistent(). Our code to enable the WiFi
network will then look like this:
WiFi.forceSleepWake();
delay( 1 );
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 1/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
// Disable the WiFi persistence. The ESP8266 will not load and save WiFi settings in the flash memory.
WiFi.persistent( false );
WiFi.mode( WIFI_STA );
The cycle has become longer, but on closer inspection of the graph and network packets the main reason for that is that DHCP
took longer this time. Unfortunately, the DHCP time is quite variable on my network, probably something I need to look into at
some stage but not today. (Ah, the noble art of procrastination…)
What is missing this time, though, is the 1.2 seconds between AP association and the start of DHCP negotiation. That’s 1200
ms at 71 mA, or 0.023 mAh saved. Combined with the 0.024 mAh saved so far, we’ve saved 0.047 mAh in total. And we’ve most
likely increased the life time of the flash chip as well.
Configuring static IP
As the DHCP negotiation is taking quite a while, the next step will be to disable DHCP and configure the WiFi connection
statically instead.
Of course, depending on your network setup this may not be a practical solution, but if your goal is to reduce the power
consumption as far as we can go, it’s worth looking at this as well.
Assuming that the sensor network operates with an IP range of 192.168.0.1 – 192.168.0.255, network mask 255.255.255.0 and
192.168.0.254 as a gateway, we can configure it as follows:
WiFi.forceSleepWake();
delay( 1 );
WiFi.persistent( false );
WiFi.mode( WIFI_STA );
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 2/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
The time taken to negotiate a DHCP lease is now completely gone, and along with it the variability in the wake/sleep cycle.
The total power consumption is now down to 0.07 mAh per cycle, less than half of the 0.164 mAh we started with before
optimising.
There may be other areas to target, so I will continue researching the impact different access points and interleaving
operations.
ebakke / 22/05/2017 / Arduino, The Notwork, Uncategorized / Arduino, Energy efficience, ESP8266, Internet of things, Notwork
MiroS
10/06/2017 at 05:48
Your article was very helpfull for me. I wanted use for powered ESP from garden solar light. I had problem with using only one
solar cell. When I applicated your solution, rasantelly fall consumed current, and now enough for powering!
ebakke
10/06/2017 at 11:11
Happy to help. I’m just about to start a solar powered project on one of these chips myself. The idea is to let the solar cell
charge my batteries enough while the ESP sleeps to both power the device when it wakes up as well as through the night.
Hopefully I will have enough sun during the day to get results as good as yours
destroyedlolo
18/10/2017 at 10:06
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 3/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
Hello,
Here my code :
#include
#include /* https://pubsubclient.knolleary.net/api.html */
#define LED_BUILTIN 2
WiFiClient clientWiFi;
PubSubClient clientMQTT(clientWiFi);
void connexion_WiFi(){
delay(10);
Serial.println(“Connexion WiFi”);
WiFi.persistent( false );
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(“.”);
Serial.println(WiFi.localIP());
void Connexion_MQTT(){
digitalWrite(LED_BUILTIN, LOW);
Serial.println(“Connexion MQTT”);
while(!clientMQTT.connected()){
if(clientMQTT.connect(MQTT_CLIENT)){
Serial.println(“connecté”);
break;
} else {
Serial.print(“Echec, rc:”);
Serial.println(clientMQTT.state());
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 4/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
digitalWrite(LED_BUILTIN, HIGH);
void setup() {
/*
* Init hardward
*/
Serial.begin(115200); // debug
/*
* Init WiFi
*/
connexion_WiFi();
/*
*/
clientMQTT.setServer(BROKER_HOST, BROKER_PORT);
Connexion_MQTT();
long q=millis();
delay( 1 );
ESP.deepSleep(10e6, WAKE_RF_DISABLED);
void loop() {
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(“.”);
I think it’s a stupid mistake … but it drives me nuts and I can’t where I’m wrong.
Any idea ?
Thanks
ebakke
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 5/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
19/10/2017 at 22:16
Bonjour.
I’ve compiled your program for one of my own modules here and was able to reproduce exactly the same problem here.
It is easily fixed, though, by adding the following lines to the beginning of your setup() function:
WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 1 );
It looks like my code does not initialise the WiFi radio properly, otherwise. My process was quite iterative, so each
optimisation step was building on what came before, and it looks like the WiFi.forceSleepWake() and WiFi.mode() calls
depend on this initialisation to happen first.
One other thing that I usually do is to place a timeout on the WiFi connection, so that if a connection has not been established
by a certain number of loops, I will reset the module. (Or send it back to sleep, depending on what is most suitable for the
situation)
Rudy
24/10/2017 at 01:57
I will try it on my esp, but i don’t know if it’s possible to activate and deactivate the wifi in a loop like a timer during only a
period of time like…each 2 minutes between my first action and my last action, i want to use the wifi to retrieve data from a
mqtt only during a period of time
ebakke
24/10/2017 at 22:24
Hi Rudy.
THat should be possible. I have an example sketch here which keeps the WiFi disabled until I need it, then I enable the
WiFi, do what needs to be done and then disable it again, without going back to deep sleep. After a minute, the loop
repeats, the WiFi is enabled again, and so on.
#include "test.h"
#include
#include
#include
int loops = 0;
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 6/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
void setup() {
WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 1 );
Serial.begin( 115200 );
while ( !Serial );
void loop() {
loops++;
WiFi.forceSleepWake();
delay( 1 );
WiFi.persistent( true );
WiFi.mode( WIFI_STA );
int retries = 0;
retries++;
Serial.println( "No connection after 300 steps, powercycling the WiFi radio. I have seen this work when the connection
is unstable" );
WiFi.disconnect();
delay( 10 );
WiFi.forceSleepBegin();
delay( 10 );
WiFi.forceSleepWake();
delay( 10 );
if ( retries == 600 )
WiFi.disconnect( true );
delay( 1 );
WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 10 );
if( loops == 3 )
Serial.println( "That was 3 loops, still no connection so let's go to deep sleep for 2 minutes" );
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 7/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
Serial.flush();
else
Serial.println( "No connection after 600 steps. WiFi connection failed, disabled WiFi and waiting for a minute" );
delay( 60000 );
return;
delay( 50 );
wifiStatus = WiFi.status();
Serial.println( WLAN_SSID );
Serial.println( WiFi.localIP() );
delay( 10000 );
MQTT_uploadToServer();
WiFi.disconnect( true );
delay( 1 );
WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 5 );
if( loops == 3 )
Serial.flush();
else
Serial.println( "All done, disabled WiFi and will wait for a minute." );
delay( 60000 );
void MQTT_uploadToServer()
WiFiClient client;
float temp = -500; // Use this as a flag, as -500 degrees is physically impossible, it is below absolute zero
int8_t ret;
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 8/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
uint8_t retries = 3;
Serial.println(mqtt.connectErrorString(ret));
mqtt.disconnect();
retries--;
if (retries == 0) {
// basically just hang around and wait for the watchdog to come and eat us.
while (1);
publish_temp.publish( temp );
delay( 50 );
mqtt.disconnect();
Rainer Ochs
23/11/2017 at 09:55
Hi ebakke,
I am doing pretty the same, designing a WIFI temperature / humidity sensor to report to a server (another ESP system)
I followed basically your advice and get a wake time of unbelivable 200ms to connect to the server, read out the HTU21 and
send the data via UDP. Reading the sensor is done while connecting.
However, I go to deep sleep with WAKE_RFCAL and omit the forceSleep calls.
The 200ms are measured from the begin of setup to the point where I go back to sleep.
The ESP needs another 300ms or so from reset until it enters setup, so I have an overall on-time of about 500ms consuming an
average of 70mA -> tis makes 10µAh per measurement.
I also tried your version with going to sleept with WAKE_RF_DISABLED and enabling WIFI again in setup so the first 300ms
only consume about 13mA. Then however the connection takes 400ms, so there is no advantage in this.
I have no idea, why my connection is so much faster – probably my router is connecting faster (a AVM fritz!box) or the ESP I
am using has some newer firmware or what ever. When sleeping I measure about 18µA including the HTU21 – so I am sure the
device is really in deep sleep.
As a board I am using a modified Wemos D1 mini with a split up 3.3V power source so the USB system does not draw any power
when not active.
Rainer
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 9/10
3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke
OppoverBakke /
Proudly powered by WordPress
https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 10/10