blog.hirnschall.net
home

Contents

Subscribe for New Projects

Introduction

In recent years the ESP8266 has become one of my go-to choices for smart home/IoT devices or projects requiring WiFi. It is cheap (around $1.5 on Amazon)1, has WiFi, and can be programmed using the Arduino IDE, making it an easy replacement for Arduinos if we need WiFi connectivity.

This post conentrates on setting up the ESP8266 module to save power and thus work on battery for a very long time. It is part of a complete ESP8266 reference you can find here.

ESP8266 power saving

As mentioned in the esp8266 reference, the esp8266 uses an average of around 80mA under normal operation. Assuming we want to use AA batteries with, let's say 2500mAh, the esp could run about 32 hours. Such a short runtime is insufficient for most applications. Fortunately, we can disable several internal elements to save power. Table 4.1 below shows what current we can expect in the different power modes.

Power Mode CPU System Clock WiFi modem RTC Power consumption
Active (RF on) on on on on
Modem-sleep on on off on 15mA
Light-sleep paused off off on 0.9mA
Deep-sleep off off off on 20µA
Power-down off off off off 5µA
Table 4.1: ESP8266 power modes and their power consumption

A notable limitation of the ESP8266's design is that waking up from deep-sleep resets the microcontroller, and all data in RAM is lost. Waking from deep sleep can be done manually by pulling RST low or using a timer. If we want to use a timer to wake the ESP, we must connect GPIO 16 to RST. We can use the circuit described in [1] to delay and extend the pulse emitted by GPIO16, as shown in Fig. 4.1 below.

esp8266 esp-12 and esp-07 and esp-01 reset pin gpio 16 circuit diagram scetch for deep sleep
Figure 4.1: Waking the ESP from deep-sleep using a timer [1]

Using Arduino to program the ESP (see section 4), we enter the different sleep modes as follows.

#include <ESP8266WiFi.h>
WiFi.forceSleepBegin(2500000); //modem sleep for 2.5s
ESP.deepSleep(5000000); //deep-sleep for 5s
delay(100); //added after deepSleep to ensure the ESP goes to sleep properly
ESP.deepSleep(0); //deep-sleep until manual wakeup
delay(100); //added after deepSleep to ensure the ESP goes to sleep properly

Note that the maximum deep sleep duration is 71 minutes, and the actual sleep time can vary by 2%.

Entering light sleep is a bit more complicated, as shown in [3].

To optimize the power consumption further, we need to minimize the time spent being active. We will follow the steps described in [4,5,6,7]. The main points to optimize are

Static IP

We will configure a static IP to disable DHCP negotiation, which takes time. Furthermore, we will disable network persistence to stop the ESP reading previous WiFi settings from flash (this can take over 1s). The code is relatively short:

IPAddress ip( 192, 168, 0, 25 ); //choose a suitable IP
IPAddress gateway( 192, 168, 0, 1 );    //gateway/router ip
IPAddress subnet( 255, 255, 255, 0 );   //subnet for your network

WiFi.persistent( false );   //prevent the ESP from reading WiFi settings from memory
WiFi.mode( WIFI_STA );  //WiFi mode. STA to connect to existing network
WiFi.config( ip, gateway, subnet ); //configure WiFi
WiFi.begin( WLAN_SSID, WLAN_PASSWD );   //connect to WiFi with this SSID and password

Disabeling WiFi while reading sensor data

As the WiFi is disabled during deep sleep, we will use the "WAKE_RF_DISABLED" argument to keep the WiFi disabled when waking from deep sleep.

WiFi.disconnect( true ); //ensures the ESP enters deep sleep correctly
delay( 1 ); //ensures the ESP enters deep sleep correctly
ESP.deepSleep( SLEEPTIME, WAKE_RF_DISABLED );// use WAKE_RF_DISABLED to keep WiFi off when waking up

The next time the ESP wakes from deep sleep, it will restart with the WiFi disabled. We will turn it on manually once we want to transmit data. To turn on the WiFi, we can use the following code

WiFi.mode( WIFI_STA );
WiFi.begin( WLAN_SSID, WLAN_PASSWD );

Avoiding network scans using RTC memory

The third optimization step is a bit more advanced. When connecting to WiFi normally, the ESP scans the network to find the right channel and BSSID. Assuming the channel has not changed while the ESP module was in deep sleep, we do not have to wait for the AP to advertise the network. The only problem is that data in RAM is lost during deep sleep. However, as shown in Table 4.1 above, the RTC stays on during deep sleep. It has 768B of its own memory, of which only 256B are reserved. We can use the remaining RTC memory to store the necessary WiFi connection information such that it survives deep sleep. Once the ESP wakes up, we check whether the information is valid. If it is, we connect without a network scan. If it is not, we ignore it and connect as usual.

The code to do this is available here, [4].

Voltage regulator

The last thing to consider is our choice of a voltage regulator. Once the ESP goes into deep sleep, it only uses about 20µA. Therefore, we want to choose a voltage regulator that uses minimal power itself if we draw tiny currents.

Here are some examples of bad choices

We recommend the following voltage regulators instead:

More Info

This post is part of a complete ESP8266 reference/guide. You can find more information on how to use your ESP8266 module effectively at blog.hirnschall.net/esp8266/.

Sebastian Hirnschall
Article by: Sebastian Hirnschall
Updated: 25.06.2023

References

Visited on 26.06.2023:

License

The content published on this page (with exceptions) is published under the CC Attribution-NonCommercial 3.0 Unported License. You are free to share on commercial blogs/websites as long as you link to this page and do not sell material found on blog.hirnschall.net/* or products with said material.

Amazon Links

1: As an Amazon Associate I earn from qualifying purchases.