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.
The 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.
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:
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.
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).
As 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).
Once 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.
The 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.