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.
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 |
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.
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
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
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 );
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].
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
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/.
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.
1: As an Amazon Associate I earn from qualifying purchases.