Posted on 5 Comments

Max deep sleep for ESP8266

max deep sleep for ESP8266

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.

Hardware

The 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 D0.

Some impressions, note the resistor in the 2nd image.

ESP8266 deep sleep impressions
Connecting GPIO16/D0 with RST on an ESP8266

Software/API

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 system_deep_sleep_set_option internally.

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 ESP.deepSleepMax().

Note that in order to test this you need ESP8266 Arduino core 2.4.1 or higher!

Max deep sleep for ESP8266

Theory

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 ESP.deepSleepMax()!

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.

Practice

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

Conclusion

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 ESP.deepSleep(ESP.deepSleepMax()).

5 thoughts on “Max deep sleep for ESP8266

  1. So does this extended sleep time also apply if you are using the Arduino IDE as compiling tool?

    1. Chris, would you care to elaborate? I’m not sure I understand what you mean by “Arduino IDE as compiling tool”.

      1. If I understand you correctly the deep sleep duration is now a 64 bit variable rather than 32 bit. I use the arduino IDE to program my ESP devices so my question is simply can I use the extended variable already within the Arduino IDE Environment or do I need to wait for an update to the compiler

        1. As I mentioned you need the ESP8266 Arduino core 2.4.1 (currently the latest). We documented at https://docs.thingpulse.com/how-tos/Arduino-IDE-for-ESP8266/ how to install & update it via the Boards Manager but I’m sure you already know how that works.

          1. Thanks. Embarrassingly overlooked and that certainly answers my query

Leave a Reply

Your email address will not be published. Required fields are marked *