Reducing WiFi Power Consumption On ESP8266, Part 3 - OppoverBakke

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

3/14/22, 6:31 AM Reducing WiFi power consumption on ESP8266, part 3 – OppoverBakke

OppoverBakke
…that means "uphill" for the rest of us

Reducing WiFi power consumption on ESP8266, part 3

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.

Disabling network persistence

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:

WiFi.begin( WLAN_SSID, WLAN_PASSWD );

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 );

WiFi.begin( WLAN_SSID, WLAN_PASSWD );

Let’s see how this affects the power consumption:

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:

IPAddress ip( 192, 168, 0, 1 );

IPAddress gateway( 192, 168, 0, 254 );

IPAddress subnet( 255, 255, 255, 0 );

WiFi.forceSleepWake();

delay( 1 );

WiFi.persistent( false );

WiFi.mode( WIFI_STA );

WiFi.config( ip, gateway, subnet );

WiFi.begin( WLAN_SSID, WLAN_PASSWD );

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

7 thoughts on “ Reducing WiFi power consumption on ESP8266, part 3”

MiroS
10/06/2017 at 05:48

Thank You, man!

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!

Again thanks, many success in future projects!

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,

Thanks for these tutos … but unfortunately, I missed something

Here my code :

#include

#include /* https://pubsubclient.knolleary.net/api.html */

#include “Maison.h” /* WiFi settings */

#define LED_BUILTIN 2

#define MQTT_PUBTOPIC “TestPub”

#define MQTT_CLIENT “TestWiFiDS”

IPAddress adr_ip(192, 168, 0, 17);

IPAddress adr_gateway(192, 168, 0, 10);

IPAddress adr_dns(192, 168, 0, 3);

WiFiClient clientWiFi;

PubSubClient clientMQTT(clientWiFi);

void connexion_WiFi(){

WiFi.forceSleepWake(); // Réveil le 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.print(“ok : adresse “);

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());

delay(1000); // Test dans 1 seconde

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() {

long debut = millis(); // Calcul du temps de connexion

/*

* Init hardward

*/

Serial.begin(115200); // debug

pinMode(LED_BUILTIN, OUTPUT); // La LED est allumée pendant la recherche de WiFi

/*

* Init WiFi

*/

WiFi.config(adr_ip, adr_gateway, adr_dns); // Service de base du réseau

connexion_WiFi();

/*

* Envoi du message MQTT

*/

clientMQTT.setServer(BROKER_HOST, BROKER_PORT);

Connexion_MQTT();

long q=millis();

clientMQTT.publish(MQTT_PUBTOPIC, String( q-debut ).c_str());

Serial.println( String( q-debut ).c_str() );

WiFi.disconnect( true ); // Explicitement désactive le WiFi

delay( 1 );

ESP.deepSleep(10e6, WAKE_RF_DISABLED);

void loop() {

But at wakeup, my ESP-12 stays forever in loop

while(WiFi.status() != WL_CONNECTED){

delay(500);

Serial.print(“.”);

So it seems the WiFi is never connected.

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

Thanks for your informations!

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.

I’m posting it below, so you can see what I am talking about.

#include "test.h"

#include

#include

#include

const char* WLAN_SSID = "XXXXXXXX";

const char* WLAN_PASSWD = "????????";

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 );

Serial.println( "Booted, and have disabled WiFi radio" );

void loop() {

loops++;

Serial.println ( "Entering loop()" );

Serial.println ( "Enabling WiFi" );

WiFi.forceSleepWake();

delay( 1 );

WiFi.persistent( true );

WiFi.mode( WIFI_STA );

WiFi.begin( WLAN_SSID, WLAN_PASSWD );

int retries = 0;

int wifiStatus = WiFi.status();

while ( wifiStatus != WL_CONNECTED )

retries++;

if( retries == 300 )

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 );

WiFi.begin( WLAN_SSID, WLAN_PASSWD );

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();

ESP.deepSleep( 120000000, WAKE_RF_DISABLED );

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.print( "Connected to " );

Serial.println( WLAN_SSID );

Serial.print( "Assigned IP address: " );

Serial.println( WiFi.localIP() );

Serial.println( "WiFi connection successful, waiting for 10 seconds" );

delay( 10000 );

MQTT_uploadToServer();

WiFi.disconnect( true );

delay( 1 );

WiFi.mode( WIFI_OFF );

WiFi.forceSleepBegin();

delay( 5 );

if( loops == 3 )

Serial.println( "That was 3 loops, so let's go to deep sleep for 2 minutes" );

Serial.flush();

ESP.deepSleep( 120000000, WAKE_RF_DISABLED );

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;

Adafruit_MQTT_Client mqtt( &client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_PASSWD );

Adafruit_MQTT_Publish publish_temp = Adafruit_MQTT_Publish( &mqtt, MQTT_USERNAME "/feeds/" MQTT_NAME "/temp",


MQTT_QOS_0, 1 );

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

Serial.println("Connecting to MQTT... ");

uint8_t retries = 3;

while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected

Serial.println(mqtt.connectErrorString(ret));

Serial.println("Retrying MQTT connection in 5 seconds...");

mqtt.disconnect();

delay(5000); // wait 5 seconds

retries--;

if (retries == 0) {

// basically just hang around and wait for the watchdog to come and eat us.

while (1);

Serial.println( "MQTT Connected!" );

Serial.println( "Sending MQTT message" );

publish_temp.publish( temp );

delay( 50 );

mqtt.disconnect();

Serial.println("Disconnected from MQTT");

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

Comments are closed.

OppoverBakke /
Proudly powered by WordPress

https://www.bakke.online/index.php/2017/05/22/reducing-wifi-power-consumption-on-esp8266-part-3/ 10/10

You might also like