ESP8266 - Operating voltage range and sleep current

The English translation of the datasheet has no specification of minimum and maximum voltage. There are some pages around that talk about the VIO specification (3.6 to 1.75V) as being the input voltage range, however that’s only for the IO drivers.

So the question is, over what voltage range is this thing stable and how much current does it consume?

Test conditions were, an ESP-01 board with both LEDs removed and a 330uF cap directly across the board input power pins. Power was supplied by a Tek lab supply and current monitored with 5.5 digit bench DMM. A Lua script was run on power up that connected to the WiFi, connected to an MQTT broker, got the temp from a DS18B20 temp sensor, published the temp, then when into deep sleep for 10sec, & repeat.

Minimum Voltage: At the low end, the device did not reset correctly 100% of the time by about 2.2V, 2.3V seemed stable. Therefore 2.5V should be a pretty safe bet.

High Voltage: Noting that I’m taking the device beyond what is spec’ed as the maximum VIO. This is probably only doable at low temps, and only because it’s a cheap device (don’t care if I kill one.) I took the device up to 4.7V without any sign of problems, albeit slightly higher current consumption. Probably not safe to have it that high for extended periods… Still it’s well above the 4.2V of a LiPo…

Current Consumption: The ESP-01 board with no leds in deep sleep mode consumes about 30uA @ 3.3V. This sounds about right, with the datasheet stating 10uA for the ESP8266, however there is also a flash device on this board fully powered on all the time.

At lower voltages there was no significant reduction in sleep current.

As the voltage increased above about 3.8V there is exponential increase in sleep current. It is likely some junctions are starting to become forward biased within either the ESP or flash. At 4.5V, the sleep current increases to ~2.5mA, or around 100x what it is below 3.8V. Given PN silicon junctions have a temperature dependent breakdown voltage, it’s pretty likely that current consumption will increase with increased temperature.

As a follow up, I got a few AA Alkaline batteries, soldered them together (which by the way, is another no-no, the heat substantially reduces their capacity.) Whilst the ESP8266 can stand the 4.5V, the sleep current would be pretty high, so I stuck a regular 1n4001 diode in series with them and got about 4V. Not ideal, but not too bad, it will at least allow the batteries to discharge down to 1V each and still have a stable ESP.

Stuck it all in a box and now it’s publishing the outside temp to my MQTT broker every minute.

Very interesting Derryn. Can you show your code (maybe put it into our git ) and specify the firmware you use? I have exactly the same logic and I cannot get the system to reliably work.

[later] I uploaded my example to github as eyal/wifi-3.lua.

Yeah I’ve essentially got the same code as you, and I’m seeing the same problems either running on battery or not. The pre-build latest binary hasn’t changed in 11 days, so that still the same one as I’m using.

Last night it kept falling over between 0.5 to 3 hrs.

From what I can tell it’s failing to restart cleanly, and goes into a state where it sits drawing ~30mA doing nothing. As far as I can tell the lua interpreter never starts fully (i.e. it never starts running our code.)

Other than adding an external watchdog or switching over to coding in C, I’m not sure what we can do about it?

Does it do this running at the 3.3V ?

Yes, 3.3V off a 2A lab supply with 330uF cap across the input power pins.

Derryn, how about printing (heck, publishing!) the memory usage of the device to see if there is a memory leak in the fw?

   print (collectgarbage ("count"));

And maybe other stats.

I did some testing along this line.

So far I failed to get the program fail to make a connection after running all night. I will continue to test.

Testing the ds18b20 module in my mqtt program yields

NodeMCU 0.9.5 build 20150126  powered by Lua 5.1.4
lua: cannot open init.lua
> dofile ("t");
used memory before=12288
used memory after =18432
Found 1 ds18b20 devices
exit ds18b20_init

NodeMCU 0.9.5 build 20150126  powered by Lua 5.1.4
lua: cannot open init.lua

So I do not know why it dies (should have about 8K available heap) yet it fails to connect to the mqtt broker.

Moving on.

I want to find out the memory size. A simple function that recurses (but does nothing else) starts with

level 0 memory used 4096 heap 21904 all 26000

then dies around here

level 84 memory used 10240 heap 16040 all 26280

Following the log shows memory is used in 1KB blocks. It seems that whatever I do it never gets more than 85 levels deep despite having the memory to continue. There is some other limit at play (stack size probably).

If I allocate a 1KB object in the recursion then I get

> dofile ("memtest.lua");
level 0 memory used 5120 heap 21120 all 26240
level 0 memory used 6144 heap 19976 all 26120
level 1 memory used 7168 heap 18832 all 26000
level 2 memory used 9216 heap 17576 all 26792
level 3 memory used 10240 heap 16488 all 26728
level 4 memory used 11264 heap 15232 all 26496
level 5 memory used 12288 heap 14168 all 26456
level 6 memory used 13312 heap 13256 all 26568
level 7 memory used 14336 heap 12008 all 26344
level 8 memory used 15360 heap 10944 all 26304
level 9 memory used 16384 heap 9880 all 26264
level 10 memory used 17408 heap 8944 all 26352
level 11 memory used 18432 heap 7304 all 25736
level 12 memory used 19456 heap 6240 all 25696
level 13 memory used 20480 heap 5176 all 25656
level 14 memory used 22528 heap 4112 all 26640
level 15 memory used 23552 heap 3048 all 26600
not enough memory

Then, just require("ds18b20.lua") gives

memory used  6144 heap 20328 all 26472
memory used 10240 heap 13808 all 24048

Here the total lost over 2K too.

Summary: we have about 26KB to play with, but probably cannot use the whole lot, so the real limit is probably 22-23KB.

Eyal, when you say “running all night”, was that just running on an alarm/timer, or was it actually sleeping and rebooting each measurement?

I’ve tried a few more things and still can’t reliably get it to keep rebooting after sleep. Works for maybe 50-100x then locks up…

No reboot test yet. So far I have “not enough memory” issues that stop me from getting there.

It either fails this way when loading ds18b20.lua or just restarts when executing mqtt.Client(...).

I now use fw 20150126. I will try 20150127 again later - I know that it uses more memory…

Ok, I’m switching back to 20150126 now as well to see if there’s any difference in the boot lockup issue.

Below are two grabs of the output of the device on lockup. The first one at 74k baud to capture the pre-lua output, then the second at 9600. Clearly the device starts ok, then somewhere in the start up code prior to the lua interpreter kicking off it hangs. So nothing to do with my code there.

I’ve also extensively probed the device now capturing all the signals on a scope, there’s nothing untoward there. I really expect this to be something silly like a decoupling issue, but it doesn’t seem like it at this stage.


I wonder if we both see the same thing. Can you upload your program and I will compare?

I have this here (running "wifi-6.lua" as "t"):

NodeMCU 0.9.5 build 20150126  powered by Lua 5.1.4
lua: cannot open init.lua
enter main
main: memory used 14336 heap 7720 all 22056
enter setupConnection
enter haveConnection
Node MAC: 18-FE-34-9C-DA-B6
Node  IP: after 0us
enter ds18b20_init
faking a ds18b20
exit  ds18b20_init
enter publishData
before: memory used 14336 heap 7304 all 21640

NodeMCU 0.9.5 build 20150126  powered by Lua 5.1.4
lua: cannot open init.lua

It seems to reboot at about the same place as yours does. I noticed a few mqtt fixes going in recently, we need a fresher fw (are you set up to build one?).

I’ve put the code in github, under examples and my name.

I don’t think it is the same issue though. Sorry my screen grab is probably unclear.

The “offline” print is the last thing that happens before it goes to sleep. After that it should spit out the lua interpreter startup string but that never happens. When it reboots it hangs before the interpreter comes online.

I’ve now just wired up an ESP-07 to test another board. I’ve just started running the test on that, see how long it goes for.

No luck, ESP-07 behaved in the same way. After 120 updates it failed…


I have it running here too. Naturally, I changed it a bit. I added this at the start of the actual code

gpio.mode (gpio0, gpio.INPUT)
if 0 == (gpio0) then
    print ("aborting by gpio0 LOW")
    doit () -- your program...

This allows me to stop a reboot loop so that I do not need to reflash etc.

BTW, I now have the meter in the loop. I see the current varying wildly while the chip is idle (but running). It drops to 0.25mA when sleeping, nowhere near the 30uA you see. I also note that the blue led stays on.

[Adding a 470uF cap I had around did not stabilise it at all]

[later] It now failed to restart after about 25 loops, hanging there with about 48mA, and rather stable.
[even later] Failed to restart after about 30 loops,

BTW, a couple of hours ago I started a fw build. That will be interesting to try. [UPDATE] Done and uploaded.

Here is an idea. Looking at the pins used for programming as described here
If some of these are floating, or in our case actually attached to the ds18b20 which may be low/high, the module can enter a programming mode. I noticed that the funny current when it hungs is similar to what I see during programming.

Worth a look.

I now removed the wire that was hanging off gpio0. gpio2 is attached to the ds18b20 but I do not read it (I always publish ‘25’). It is so far rebooting OK, done about 50. Time to go to bed, but I will leave it running overnight.

Good thinking Eyal. Hopefully that’s our problem.

I’ve been downloading the espressif VM and SDK. Hopefully get that up and running, as the C API looks quite good, quite a lot of stuff in there. I’d rather be coding in C than dealing with the number of memory problems I’ve been having.

Not perfect yet, it managed over 500 records before hanging.
Next I will change the input to gpio4, magic pin is gpio5, and I set gpio0/2 to HIGH/LOW.

But let me finish this morning coffee first.


I have a question about your program. Am I correct to say that the line

print("Trying to connect to Broker")

should simply say "connected"? And if so, then why the following alarm? I removed it and it still works…

Something different: I tried to run with gpio0/2 tied to HIGH/LOW (reverse of programming mode) and got a fast stream of errors (from the core, at 74k) repeating

Fatal exception (0):
epc1=0x40100000, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

So I left the pins unconnected for now.

To be honest I’m not sure.

The callback function from m:connect doesn’t necessarily mean that a connection has been made as far as I know. The documentation is lacking here and I haven’t had the chance to dig through the nodeMCU code yet.

There is a call back that can be registered for “connect”. From the API example

This would ideally be the place to do the read and publish, however this callback never gets called. It’s broken.

So I used an alarm to give the connect function time to complete. I have no idea if the alarm is necessary. However the bigger issue from my perspective is there’s no API function exposed to check if you’ve got a successful connection!

I believe the only way to know if you’re not connected at the moment is to attempt to publish something, and wait for an “offline” callback. I had all this checking coded and working, however I got stuck with the dreaded “out of memory” issue when I tried to include the ds18b20 module, so I had to remove all the error handling from my code. Very frustrating!