Running NodeMCU on a battery: ESP8266 low power consumption revisited

Over the last year I have standardised on the ESP8266 for all my small IoT projects. Its low price, ease of use (now that the Arduino IDE is available), tiny size and built in Wi-Fi makes it a compelling option.

Using Wi-Fi is a convenient way to link your newly created IoT device into your existing IT infrastructure – including cloud services – but it also has a drawback. Wi-Fi’s demand for power usually makes battery operation impractical for any real deployment. I have been able to get around this issue for most of my projects (e.g. the train and the smart shelf described on this blog) because they are for demonstration purposes only, requiring the battery to last no longer than a few hours.

Nevertheless, it is possible to put the ESP8266 into deep sleep and wake up periodically to check and activate Wi-Fi only when required. This would suit a scenario in which an IoT sensor sends relatively infrequent one way traffic (i.e. where real time control of the device is not needed).  I wrote about the ESP8266 deep sleep option more than a year ago, but have not explored it any more until recently, when exactly such a project arose.

NodeMCUThe other thing that I have done over the last year is to standardise on using the NodeMCU (hardware, not the LUA software). Especially when rolling out multiple small projects, it is immensely convenient to be able to plug a device into a USB port and just program it (automatically without having to wire up serial pins and then get the correct pins tied high / low for flashing / running). With no need to worry about providing 3.3V power, adding capacitors to prevent the ESP8266 power spikes from causing instability, or adding a resistor + cap for a power-on reset. No need to scale down the ADC input to 1V or to add my own test led… and all of this in a breadboard friendly package.

Also, just to be clear for those who may wish to follow along, I always use the “second generation” NodeMCU known as v2. The different versions are described here and I agree with that poster – i.e. don’t buy the v3 variant because its larger size means that it leaves no free breadboard holes on either side.

Unfortunately, with all this added convenience comes the drawback of added power consumption, which continues even when the ESP8266 is in deep sleep.

I measured 18mA to the NodeMCU board while the ESP8266 was in deep sleep mode – orders of magnitude more power hungry than I was looking for.

So for my iot-container project, I sought to retain the convenience of using the NodeMCU, but to address its power consumption shortcomings to allow battery operation.

Read further to hear what I did.

The two immediate suspects are the power regulator, and the UART, as discussed in the forum here.

The first step is to target the power regulator. The AMS1117 LDO draws a quiescent current of “typically” 5mA. To prevent this, it may be sufficient to lift just pin 1. However, I chose to remove the whole chip to free up space for later.

You won’t need the LDO if you supply your own power directly to the 3.3V pin of the NodeMCU. I often use a single cell Li-Ion battery via a 1N4001 dropper diode. Note that from now on you will need to supply this power, even if a USB cable is connected for programming / monitoring.

Place a small amount of flux and solder on the pins, starting with the big tag, and it should lift easily.IMG_5285mThen remove the remaining 3 pins. Without the LDO, I measured a saving of 3mA.IMG_5287m

break_track_NodeMCU

 

Now for the biggest saving – to disable the USB UART. This can be done with reference to the NodeMCU schematic by cutting power to pins 6 and 7.

 

 

 

 

In practice this means cutting a track with an X-Acto knife under the best magnification you can find, and with steady hands. Also scrape away the protective coating to the right side of the cut:IMG_5289m

Congratulations! You will now have reduced power consumption by some 360x to around 50μA 20μA [Updated 28 Jan 2017 when I was powering only the NodeMCU, without additional circuitry].

Earlier I mentioned using OTA to program your device. If you have already installed the OTA code prior to cutting the track, in theory you could finish at this point, and permanently forego the use of the USB port. In real life, things go wrong, and it is useful to have the option of going back to having a serial port.

Option 1: Add Switch or Jumper

The first (and easier) option is to put a switch in the position formerly occupied by the regulator, attached to the two points shown below:

IMG_5291m

With this in place, you can re-enable the USB port for programming or debugging via the serial monitor.

A note to the unwary: The first time I tried this I glued down the switch with epoxy. The problem is that, unless you are more careful than I was,  a drop of epoxy becomes suddenly HUGE under these magnifications. The glue seeped into the switch, preventing it from working, and the NodeMCU ended up in the bin. Second time around I used super glue with more success.

[Update 4 Sep 2016]: I have replaced the switch with a simpler and more reliable solution: a jumper.

IMG_5396m  IMG_5397m

Option 2: Power UART from USB (no switching required)

[Update 28 Jan 2017]: Thanks to Willem Jansen for suggesting this approach in the comments below. It turns out that the cp2102 UART has its own internal 5V to 3.3V regulator, which is not by default used by the NodeMCU circuitry, probably because it would not reliably supply the peak currents required by the ESP8266 (plus any associated circuitry the user might add around the NodeMCU).

option2schematicAs explained in section 10 of the cp2102 datasheet, the cp2102 can be “configured as either a USB bus-powered device or a USB self-powered device”. To reconfigure the chip to use USB power requires isolating the VDD pin  (break at X1) in addition to the X2 break described earlier, followed by permanently wiring the Regin pin to USB 5V (Wire3).

option-2-pcbYou can see on the right what this looks like. The extra PCB break really adds to the difficulty, even under 10X magnification.

option2photoOnce complete, the UART will only draw power when the USB is connected for programming / debugging. Certainly this is a more elegant solution and convenient to use –  offset by the extra time and effort required to make the mod. Depending on how often you plan to update firmware or debug will determine which approach is optimal – you decide!

I need to warn you that after I implemented option 2, I found that intermittently the ESP8266 does not seem to boot up after applying power. Thanks to Mario Valentino – in the comments below – who found that a disconnected UART can pull the ESP8266 TX pin low, causing intermittent booting problems (as hinted  at under “Desired level during power on” in: http://microchip.ua/esp8266/ESP8266_Module%20Application%20Design%20Guide.pdf). What I find strange is that in theory this should also be the case for option 1, yet I did not experience that.

img_6321mThe solution is to place a resistor between TX and 3.3v, as shown on the right. Unfortunately this does waste some power. Choosing 1MΩ minimises this to an additional 3uA, bringing the total deep sleep current consumption of the NodeMCU to between 22-23μA.

Which option would I choose? I favour option 1. You save 5% power compared to option 2, and it is less tricky to make the mod. If you use OTA to update your firmware (or seldom update your firmware), you will not very often, if at all, need to replace the jumper to re-enable the serial port. Certainly, however, option 1 is not as “elegant”…

To be able to measure the small currents, I made use of the excellent μCurrent Gold.

You may correctly point out that 50μA is still several times higher than what should be achievable with just the ESP8266 alone. But for what I am doing it is good enough: (theoretically at least you could get towards 10 000 hours from a small 500mAh  Li-Ion cell, depending of course on what you do during the wake up periods, and preferably only infrequently using Wi-Fi.

[Update 28 Jan 2017]: While testing option 2 above, I was powering only the NodeMCU (i.e. without the additional HX711 circuitry used previously). I measured deep sleep current at 20μA!

In my next post, I’ll put this into practice, with full code.

Measuring current using uCurrent set to 1mV/1uA
Measuring 45uA current consumption using uCurrent Gold set to 1mV/1uA

spam blocker

32 thoughts on “Running NodeMCU on a battery: ESP8266 low power consumption revisited

  1. Interesting — it is a bit surprising that the CP2102 consumes so much power. The datasheet seems to indicate that it operates in a low power mode from reset until USB enumeration. Look for SUSPEND in the datasheet.

    I’ll run some experiments as well.

    Like

    1. Yes, I saw the SUSPEND lines mentioned in the datasheet, but they are outputs only. Suspend seems to triggered when “signaling is detected on the bus”. So I tried removing all “Serial” references in my Arduino code and also not plugging in a USB cable, but to no avail. Report back if you have any success!

      Like

      1. Thanks for the great post! I’ve been tearing my hair out today trying to figure out why I could get that reported 70uA! Did you ever get a chance to follow up on the question of the CP2109 power consumption in suspend mode?

        Like

  2. When the current gets really low, the diode will drop less voltage than you might expect and your module may get exposed to a voltage that is higher than its maximum spec. To avoid this problem, instead of a regular Li-Ion use a Lithium Iron Phosphate battery (LiFePO4), which has a nominal voltage of 3.2V and never goes higher than 3.6V. An easy way to experiment with them is to use the LiFePO4wered/USB module I sell on Tindie: https://www.tindie.com/products/xorbit/lifepo4weredusb/?pt=ac_prod_search

    Liked by 1 person

  3. This is why i wish someone would come up with a proto and go version of nodemcu. Socket the actual nodemcu board for the ESP8266-12E and then sell a second board with just the socket wired to pins. Build and debug your prototype in the nodemcu and when complete pop the 12E out and into the socket only version.

    I have seen several 3d printed sockets but think we are still a ways off. http://www.thingiverse.com/thing:1333056 for example but the pins used arent something standard off the shelf.

    Like

    1. Or (epiphany here) maybe I wam thinking about it backward. Take a modern nodemcu board design, and move all parts other than the ESP8266 to a daughtercard that plugs into/onto the top of the nodemcu board. Doh they already have that http://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module-MINI-nodemcu/32569199462.html

      Hmmm I wonder what one of these draws current wise without the serial board. Time to order one.

      Like

    1. I have ESP01 powered with 2000 mAh power bank and AMS1117. It lasts about 10-12 days waking up every 5 minutes for 10 seconds to connect to wifi, read DS18B20 and send data both to local MQTT and ThingSpeak.

      Like

  4. I was wondering if you could improve the running time by removing the LDO and also reduce time 10 seconds for just a few Milliseconds… I’m currently running an old version of the board I mentioned above for over 1.2 years on 2xAA. I know it’s not the same an it can’t send metrics directly to the Internet without a gateway but might be room for some improvement on the ESP8226. Other thing is the power bank, rechargeable batteries normally have a bigger self-discharge rate when compared with non-recharchable ones.

    Liked by 1 person

    1. I’m not sure if ESP8266 can survive direct connect to LiPo battery as it’s voltage can be up to 4.2 V. In my case the longest step is WiFi connection, it takes about 5-6 seconds. Reading sensor and sending data adds 1-2 seconds. And I forgot to mention I’m using NodeMCU firmware running my Lua scripts. Probably clean C code could do the job much faster.
      I’m pretty sure it is better to use simple broadcasting radio like 315/433 MHz or NRF24L01+ to save time on AP association, though I have not tried them yet.

      Liked by 1 person

  5. My proposal would be: Cut the UART power lines as indicated, scratch away the Vcc-pin and connect the REGIN pin (pin in the bottom left corner) to +5V from the USB directly. This way, the SILAB IC is only active when you attach a USB device – without necessitating any jumper at all.

    Liked by 1 person

    1. Yes! I like your thinking. As per the cp2102 datasheet (section 10), the chip can be “configured as either a
      USB bus-powered device or a USB self-powered device”. I will give your approach a try to confirm, and then update the post with this alternative.

      Like

      1. If you power the CP2102 from a usb power supply, then it *ought* to go into suspend mode and consume much less current (at least, this is how I read the specs)

        Like

  6. Great article. I want to reduce the power consumption of my ESP8266 NodeMCU as well and I am going to try Option 2: Power UART from USB (no switching required). I have one question though, do I need to still do the other adjustments as well, or does this suffice?

    Like

    1. Kevin, for option 2 you still have to first make the mods described before the “option 1” heading. Just be aware that “option 1” is definitely robust and proven – and has been running my IoT device (https://tinker.yeoman.com.au/2016/07/24/iot-container/) for almost 6 months on a single charge of a 14500 cell. However, I only tried option 2 last week and experienced some strange intermittent issues with the NodeMCU not booting – so cannot be as confident of its reliability.

      Like

  7. I observed the instability with option 2 as well, especially when using deep sleep. About 1 in 3 times the module does not reboot after deep sleep when the CP2102 is unpowered.

    Solution: Pull up the TX pin to 3.3v with a 10K resistor (higher may work as well). By disabling the CP2102 the internal pull up is gone as well and the ESP becomes unstable on boot.

    Like

    1. Thanks Mario – I believe you mave have solved this! I must say I did consider something similar, but was thinking of the RX pin (since I thought it more likely to be an input). I couldn’t find any evidence that the TX pin (GPIO1) mattered at boot time. But doing another search there is something – look under “Desired level
      during power on” for the TX pin at: http://microchip.ua/esp8266/ESP8266_Module%20Application%20Design%20Guide.pdf
      I’ll confirm and update the post.

      Like

  8. First of all, thank you Tinkermax for a brilliant tutorial.

    I have followed Option 1 except I did not remove the voltage regulator, so I can still use a 5V powerbank. Unfortunately, my NodeMCU v2 does not boot without the jumper connecting the track I’ve cut. The blue LED does not even blink and the device draws about 35mA forever. If I wait for the LED to blink before I remove the jumper, it boots normally and when it falls to deepsleep, the current is 2.3mA (rather than 10mA when UART chip is connected).

    I also tried to solder a 120kOhm resistor between TX and 3.3V but nothing has changed.

    Does anybody have any idea what prevents my NodeMCU from booting? Do you think removing the voltage regulator makes any difference? Thanks.

    Like

      1. One possibility: are you putting the NodeMCU into deep sleep in your test software? If so, I found that I had to short 3.3v to ground briefly (with the power off / disconnected!) to cycle the NodeMCU. This is because the current draw is now so low that the onboard caps hold the ESP8266 powered in deep sleep mode for some time… so it can appear not to boot when you reapply power.

        Like

        1. Thank you for your tip. I do put the NodeMCU into deep sleep. But it’s the same no matter if I put it into deep sleep or if I just disconnect the power supply. I tried to short 3.3V to GND before connecting the power supply briefly but it’s still the same. I also tried to measure resistance between 3.3V and GND with the NodeMCU off, and found quite surprising that the resistance was only around 1kOhm with the UART chip connected (jumper present), and around 2.5kOhm with the UART chip disconnected (jumper removed). Is this normal? Thanks. Unfortunately, I don’t have another v2 for reference.

          I am going to try if I can use a PNP transistor to connect the UART chip only when the NodeMCU is running, and to disconnect it to save power when it goes to sleep.

          Like

          1. My results with the CP2102 power trace cut at X2:
            Needed 10k between tx and 3.3v for reliable booting/wake from deep sleep , otherwise it shows ~30ma always.
            Tx pin voltage is 1.5 volts while sleeping , 2.44v while running . There
            100K ohm would not boot

            1) 2.3ma in deep sleep with CP2102 unpowered and AMS 1117 regulator still populated.

            2) ~ 0.200ma in deep sleep with CP2102 unpowered and AMS 1117 regulator removed from board (I supply 3.3v to 3.3v pin_
            …and experimenting with 10k,100k and no pullup resistors between 3.3v & Tx:
            ….10k works 0.200ma
            …..100k doesn’t boot/wake 0.043ma
            ……no pullup (infinite res) doesn’t boot/wake 0.020ma

            Like

  9. Dear all,
    I want to provide supply to NodeMCU ESP8266 (v0.9) from powerbank (5000mah,10000mah and 20000mah and each has 2 ports). How could i achieve this ?
    Purpose is to build robotic car so that using mentioned power bank ( one port goes to controller via to motors(Wheels) and other would be connected to ESP8266 ).
    I require support and assistance .

    Like

  10. Nice tutorial got my esp8266 node mcu running without the 1 M ohm resistor and it’s consuming a 13 micro amps in deep sleep SWEET!
    also i use a arduino uno without chip to program the sketch through rx and tx , so that could also be a solution number 4 for operation without uart.
    now i have a microcontroller that can have a semi always on state running on the power from bacteria in a plant based microbial fuel cell

    Like

  11. My adafruit Huzzah goes into a proper deep sleep power consumption level without requiring these hardware modifications. Would love it it someone knew of a similar board that is in the price range of the Amica style boards.

    Like

Leave a Reply to Joachim Bongers (@helothisisfresh) Cancel reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s