Networking applications consume a lot of power. If such applications are battery-powered, there’s a risk the battery will exhaust because of the high power demands of networking functions.
Frequently, power is also wasted in non-essential microcontroller activities. For example, the power might remain on for various built-in peripherals irrespective of their use or relevance in the application. Fortunately, Wi-Fi development boards such as ESP8266 and ESP32 offer sleep modes to save net-power consumption, which are recommended in networked applications.
This saves the battery power for the application rather than wasting it on the controller peripherals. Here we’ll discuss the sleep modes in ESP8266 and ESP32 boards and explore how they can be used in MicroPython.
The sleep modes
In ESP8266, there are three sleep modes:
1. Modem sleep. The Wi-Fi is turned off in the modem sleep mode while the CPU, system clock, and RTC remain on. In this state, the substrate current drawn by SoC is 15 mA.
If every beacon broadcasts the delivery traffic indication message (DTIM) via the Wi-Fi module, the power consumption is approximately 16.2 mA. If every three beacons broadcast the DTIM, the power consumption is approximately 15.4 mA. And if the DTIM is broadcast every 10 beacons, the power consumption is approximately 15.2 mA.
Note that the DTIM message is broadcast by the Wi-Fi module every three beacons by default.
2. Light sleep
The CPU stays pending in light sleep mode when the Wi-Fi and the system clock are turned off. The RTC that’s responsible for maintaining the date-time remains on. In this state, the substrate current drawn by the SoC is 0.4 mA. If every beacon broadcasts the DTIM via the Wi-Fi module, the power consumption is approximately 1.8 mA. If every three beacons broadcast the DTIM, the power consumption is approximately 0.9 mA. And if the DTIM is broadcast every 10 beacons, the power consumption is about 0.55 mA.
Again, the default DTIM value in the networking configurations is three.
3. Deep sleep
In the deep sleep mode, the CPU, system clock, and Wi-Fi are turned off, and only the RTC remains on to maintain the date-time. The controller remains in an idle state, and no DTIM is broadcast. Normal controller operations are resumed only when the controller “wakes” from the deep sleep. In this mode, the current drawn by the ESP8266 SoC is reduced to 20 uA.
Only ESP8266 offers all of the sleep modes. By default, MicroPython only supports the light and deep sleep modes. Therefore, an ESP-specific module is required for the modem sleep mode.
If an SoC falls into deep sleep mode, the net power consumption by a breakout board might be in mA. The onboard components and peripherals — such as the LEDs, power regulator, USB serial chip, and other interfaces — might still consume significant power irrespective of the fact that the SoC itself is in an idle state, drawing only a few micro-ampere of current.
Waking up in ESP8266
Depending on the port, different wake-up sources are available. For example, in ESP8266, only two wake-up sources are available: the timer and external.
In the timer wake-up, the built-in RTC is used to wake up
the SoC from a deep sleep after a specified period.
In the external wake-up, the SoC is in deep sleep until the reset button is hit. In ESP8266, the reset button must be connected to the GPIO16 for the board to wake up. In a breakout board, the reset button might already be connected to the GPIO16 onboard or require an external connection.
The deep sleep cycle
The deep sleep mode is useful in battery-powered networking applications. The chip then remains in deep sleep or an idle state, only waking periodically to execute assigned tasks. Tasks might include taking readings from a sensor, sending the sensor data to a server via an IoT protocol (such as MQTT or CoAP), and executing an on-spot action based on sensor readings or insights received over the network.
After the task is executed per the user application, the chip goes back to sleep. This cycle of deep sleep, waking, performing embedded/IoT tasks, and going back to sleep continues endlessly.
MicroPython
The machine module of MicroPython provides these functions for the power management of supported boards.
machine.lightsleep([time_ms]): puts the port into a light sleep mode. If the time in milliseconds is specified as an argument, the light sleep mode lasts for the maximum time specified. The port may wake up before the timeout if a source triggers it. If no argument is passed, the light sleep mode lasts until interrupted by a wake-up source.
machine.deepsleep([time_ms]): puts the port into a deep sleep mode. If the time in milliseconds is specified as an argument, the deep sleep mode last for the maximum time specified. The port may wake up before the timeout if a source triggers it. If no argument is passed, the deep sleep mode continues until interrupted by a wake-up source. Waking up from the deep sleep mode is the same as a hardware reset.
machine.wake_reason(): this method returns the wake-up source. The return value can be machine.WLAN_WAKE, machine.PIN_WAKE, or machine.RTC_WAKE, depending on if the wake-up source is WLAN, pin change, or RTC. This method can be used to log the wake-up reason into a variable or print the wake-up reason to the console.
However, the wake-up source must be configured before calling for light or deep sleep. Also, the machine.wake_reason() can only be called after calling for the light or deep sleep.
The machine module provides one more function that’s useful for the power management of the port. This is the machine.idle(). Calling this method gates the clock to the CPU, causing the port to go into a sleep mode where the port wakes up when an interrupt is received.
MicroPython’s sleep modes in ESP8266
ESP8266’s sleep mode can be accessed using the power-related functions of the machine module or ESP8266’s functions, which are available through the esp module.
These functions only let a user put ESP8266 into the light or deep sleep modes (as discussed above). But the esp-specific module functions allow a user to place ESP8266 into a light, deep, or modem sleep.
The esp module can be imported into a MicroPython script using this statement: import esp
The esp module provides these functions to put ESP8266 into different sleep modes…
esp.sleep_type([sleep_type]): sets or gets the ESP8266 sleep mode. If the method is called with an argument, it sets the ESP8266 to the specified sleep mode. If the method is called without arguments, it returns the ESP8266 sleep mode.
The parameters can be set via these arguments: SLEEP_NONE, SLEEP_MODEM, and SLEEP_LIGHT. If set to the SLEEP_NONE, ESP8266 remains in active mode or resumes active mode from sleep. If set to the SLEEP_MODEM, ESP8266 is placed in the modem sleep mode. If set to the SLEEP_LIGHT, ESP8266 is placed in a light sleep mode.
esp.deepsleep(time_us=0, /): puts ESP8266 in a deep sleep for a specified time (in microseconds). If a sleep time is specified, the built-in RTC is used as the timer. If the time is not specified as an argument, ESP8266 falls into a deep sleep until there’s an external wake-up.
Whether ESP8266 is put into a deep or light sleep using the power-related functions of the machine module or functions of the esp module, the GPIO16 must be connected to the reset button for the timer wake-up to work. This is typically done by an external circuit connection in most ESP8266 breakout boards.
Working the timer wake-up
For timer wake-up, connect the GPIO16 with ESP8266’s reset button.
To detect the wake-up, an LED will blink after the ESP8266 wakes from any given sleep mode. For this to work, connect an LED to the GPIO2 as shown below.
To place ESP8266 into the modem sleep mode and later wake from a timer, use the esp module. This MicroPython script puts ESP8266 into the modem sleep mode and blinks an LED, which is connected to the GPIO2, every time ESP8266 wakes because of the timer.
import esp
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
def modem_sleep(msecs):
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
rtc.alarm(rtc.ALARM0, msecs)
esp.sleep_type(SLEEP_MODEM)
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to modem sleep’)
#sleep for 10 seconds (10000 milliseconds)
modem_sleep(10000)
To place ESP8266 into the light sleep mode and later wake from the timer, use the esp module or power-related functions of the machine module. This MicroPython script puts ESP8266 into a light sleep mode using the esp module and blinks an LED, which is connected to the GPIO2, every time ESP8266 wakes because of the timer.
import esp
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
def light_sleep(msecs):
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
rtc.alarm(rtc.ALARM0, msecs)
esp.sleep_type(SLEEP_LIGHT)
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to light sleep’)
#sleep for 10 seconds (10000 milliseconds)
light_sleep(10000)
This MicroPython script puts the ESP8266 into a light sleep mode using the machine module, blinking an LED connected to the GPIO2 every time ESP8266 wakes because of the timer.
import machine
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
def light_sleep(msecs):
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
rtc.alarm(rtc.ALARM0, msecs)
machine.lightsleep()
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to light sleep’)
#sleep for 10 seconds (10000 milliseconds)
light_sleep(10000)
To place ESP8266 into a deep sleep mode and later wake from the timer, use the esp module or power-related functions of the machine module. This MicroPython script puts ESP8266 into a deep sleep mode using the esp module and blinks an LED, which is connected to the GPIO2 every time ESP8266 wakes because of the timer.
import esp
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
def deep_sleep(msecs):
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
rtc.alarm(rtc.ALARM0, msecs)
esp.deepsleep()
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to deep sleep’)
#sleep for 10 seconds (10000 milliseconds)
deep_sleep(10000)
This MicroPython script puts ESP8266 into a deep sleep mode using the machine module and blinks an LED, connected to the GPIO2, every time ESP8266 wakes because of the timer.
import machine
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
def deep_sleep(msecs):
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
rtc.alarm(rtc.ALARM0, msecs)
machine.deepsleep()
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to deep sleep’)
#sleep for 10 seconds (10000 milliseconds)
deep_sleep(10000)
Working the external wake-up
In ESP8266, the external wake-up is triggered whenever the reset button is hit. This wake-up is only useful when ESP8266 is in deep sleep mode. The reset button on the breakout board can be pressed for the external wake-up or a push-button pulled high can be connected to the reset pin.
To place ESP8266 into the deep sleep mode and later wake up via the external, use the esp module or power-related functions of the machine module. This MicroPython script puts ESP8266 into a deep sleep mode using the esp module and blinks an LED, connected to GPIO2, every time ESP8266 wakes from an external reset.
import esp
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to deep sleep’)
sleep(1)
esp.deepsleep()
This MicroPython script puts the ESP8266 into deep sleep mode using the machine module and blinks an LED, connected to the GPIO2, every time ESP8266 wakes from an external reset.
import machine
from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
#blink LED
led.value(1)
sleep(1)
led.value(0)
sleep(1)
# wait 5 seconds so that you can catch the ESP awake to establish a serial communication later
# you should remove this sleep line in your final script
sleep(5)
print(‘Im awake, but Im going to deep sleep’)
sleep(1)
machine.deepsleep()
For an external reset, the esp.deepsleep() or machine.deepsleep() methods are called without arguments. These calls put ESP8266 in a deep sleep until an external wake-up is detected through the reset button. The push-button connected to the reset button for the external wake-up must be pulled high.
Learn how to use ESP32’s sleep and wake-up modes in MicroPython here.
You may also like:
Filed Under: Electronic Projects, ESP8266, Featured Contributions, Python, Tutorials
Questions related to this article?
👉Ask and discuss on Electro-Tech-Online.com and EDAboard.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.