In light of our recent power-consumption related posts 1 & 2 it seemed logical to ask ourselves about max deep sleep for ESP8266. Yet, it took a comment from a curious reader to set things in motion. I replied
…the maximum value for a 32-bit unsigned integer is 4294967295 or 0xffffffff. Hence, the max deep sleep interval appears to be ~71 minutes.
You can’t argue with that first statement but the second is a bit in the air without clear evidence. My co-founder Dani quite rightly then asked “are you sure, didn’t they change that recently?” (“they” being Espressif and/or the Arduino devs).
So then, what is the current max deep sleep for ESP8266 i.e. the maximum duration the ESP8266 can sleep deeply – and still wake up afterwards.
Deep sleep basics
The intention of this post is not primarily to talk about ESP8266 deep sleep in general but about max deep sleep for ESP8266. If you’re interested in the former there’s a very nice article from Losant with great explanations and sample code for Arduino. Below are just the absolutely essential corner stones.
RST pin is held HIGH while the ESP8266 is running. When it receives a LOW signal, it restarts the microcontroller. Once your device is in deep sleep, it will send a LOW signal to GPIO 16 when the sleep timer is up. Now, if you connect GPIO 16 to
RST the device will wake up (i.e. reset) when deep sleep is over. Ideally you put a low-valued resistor, like 330 – 1kΩ, in between.
Side note: on the NodeMCU modules, GPIO 16 is marked as
Some impressions, note the resistor in the 2nd image.
The Espressif NON-OS SDK, on which the ESP8266 Arduino integration is based, offers the
system_deep_sleep function (and the more adventurous
system_deep_sleep_instant) to send the MCU to sleep. It accepts a single parameter that denotes the sleep duration in μs. Why microseconds? Can you image a situation in which you’d want the MCU to sleep less than a second? If you consider that it might take up to 100ms until it actually sleeps after you issued the command this becomes even more absurd. But it is what it is.
In Arduino land that deep sleep function is made available as
ESP.deepSleep(duration, wakeMode) with the second parameter being effectively optional. It is used to set
Changes with Espressif SDK 2.1
Remember my initial “…32-bit unsigned integer is 4294967295 or 0xffffffff…” statement? It referred to the data type of the
system_deep_sleep parameter (that μs thing).
Well, it used to be a 32-bit unsigned integer; a
uint32_t in Arduino lingo. Hence, deep sleep could last at most 4294967295μs or ~71min. You simply can’t fit a larger number than that into a
uint32_t. If you tried, it would overflow and you’d possibly get a much lower value.
With SDK 2.1 Espressif changed the data type of that parameter to a 64-bit unsigned integer; a
uint64_t. So, in theory you could send the MCU to deep sleep for some 5’124’095’576 hours ((2^64-1)/(3600 * 10^6) i.e. (2^64-1)/μs-per-hour). As this is neither useful nor practical they also documented the realistic limit which Arduino calculates in
Note that in order to test this you need ESP8266 Arduino core 2.4.1 or higher!
Max deep sleep for ESP8266
So, if you wanted to find the effective max deep sleep for ESP8266 you would simply have to print
ESP.deepSleepMax() to console or make it otherwise visible, right?
Turns out Arduino
String/toInt/Serial.print() can’t handle printing 64 bit values.
So, let’s write a helper function first then:
If you test this with
Serial.println("max deep sleep: " + uint64ToString(ESP.deepSleepMax()))
you will get something like 13612089337μs ≙ 13612s ≙ 3.78h ≙ 3h 46min. This is less than what you might have hoped for but still 5x more than the 71min from pre-SDK-2.1 times.
Except that this is not a static value. Meaning it changes with every invocation of
A quick glance into the Arduino source code reveals why. The calculation, originally provided by Espressif, is based on the RTC clock period. Since the RTC clock tends to drift with changes in temperature results may vary over time. My tests yielded results in the range of 3:35 – 3:50h.
The big question of course is: is the ESP8266 able to deliver? When will it wake up if you send it to sleep for exactly
ESP.deepSleepMax() microseconds? What if you go beyond? Will there be dragons?
When I tried
ESP.deepSleep(ESP.deepSleepMax()) with the max deep sleep value being around 3:46h the ESP8266 woke up after 3:25h. That’s 20min early but hey, the early bird catches the worm they say.
How about setting the deep sleep interval to 4h? 6h?
Nothing failed, all looked good. Except that the ESP8266 never woke up; it literally slept forever. Kind of at least; I stopped the test after 24h.
How about NodeMCU?
As I have been a committer with the NodeMCU firmware project (Lua on ESP8266/ESP32) since summer 2015 one question seems inevitable: how about 64-bit support for deep sleep in NodeMCU?
Thanks to friendly nudge from yours truly 64-bit support was introduced shortly after this post was published. The documentation for node.dsleep() and node.dsleepMax() was updated accordingly (it links to this post).
In that brief ESP8266 deep sleep primer I called to mind that on the hardware side the precondition is to wire GPIO16 to
RST. Then we saw that the deep sleep interval in the SDK is now an 64-bit unsigned integer – a potentially really large number of microseconds.
I was able to demonstrate that the effective max deep sleep for ESP8266 is around 3.5h hours which is a significant improvement over the earlier 71 minutes. To send the ESP8266 to sleep for as long as possible use