My latest project is to make something battery powered, based on an ESP32 processor. The ESP32 data sheet claims it can go down to under 1uA in a deep sleep mode. It also has an Ultra Low Power processor that can do things in deep sleep at only a few uA. It is not very clear in the datasheet for the ESP32-WROOM-32 module how low it can go - after all that has extra bits including an external flash. So it was a bit of an unknown. However, I have made something, and it works... (on GitHub)
The first board was a cock up - wrong footprint completely on a key device - kicking myself. The second version was more what I would expect - some minor errors I could work around, allowing me to prove it all works and confirm power usage. The 3rd version was great except one of the chips again had wrong footprint - but this time close enough for the device to fit without problem. I have managed to keep the device tiny - not much bigger than the ESP32-WROOM-32 itself.
The first application is actually to work with a VL53L0X ranger in the top of an oil tank, running on battery and reporting over WiFi. The next trick may be LoRa for such things.
Battery / power supply?
The first real question was whether to try and run directly from a battery, or to use a power supply?
Directly from a battery means finding a battery that is within spec to produce 3.3V. The voltage from a battery is often slightly more (when new) than stated, and depends on the battery technology. The processor will cope with voltages a bit out of range as well (3.0V to 3.6V). So a 3V battery should work. But the voltage drops as the battery runs down, and we are starting on the edge of acceptable voltages, so this could cause problems. The advantage of running directly from a battery, apart from fewer components, is the really low power modes of the ESP32 should allow a really long battery life.
With a power supply you have the advantage of using a wide range of battery, e.g. 4.5V, 9V, 12V, etc, but the big disadvantage of wasting power on the regulator itself.
I ended up using the LMR16006 from TI which is designed for battery devices, and has an idle current of 28uA when not driving much load (e.g. an ESP32 in deep sleep). It also has a shutdown mode drawing less than 1uA (see more on that later).
However, testing showed that it draws 34uA when not even connected to a load. This pretty much is explained by the 460kΩ potential divide built in to the fixed 3.3V module to drive its feedback pin. I could go for external potential divide but 460kΩ is on the top range recommended in the data sheet.
However, even 34uA is good, and can allow a battery to last years.
USB as well?
Do I need USB as well? Well, no, not really, I could have a generic programming header, but I like the USB-C connectors. They are good as a power supply when not running off battery, and make programming and debug easy. So yes, I'd like to keep the USB.
The issue is power. The USB chip (FT231X) can be powered from USB, and even work its own 3.3V I/O from that. So it can be totally off when no USB. Good.
But it is used to control EN/GPIO0 to reset and put the ESP32 in boot mode. If USB is off, the ESP32 stays in reset. Thankfully the USB chip can be configured to invert RTS and DTR if you want, so I put them through a simple transistor inverter so that when the USB is off the ESP32 is not in reset or boot mode. The result then works as expected with the debug and flashing tools in the ESP IDF.
The Tx pin to the USB when powered down was a concern, but it seems to cause no problem, and the code can turn it off immediately on start up, and in deep sleep it is not connected.
The USB chip can also feed in some useful GPIO pins, reporting when it is on (a fixed "1" on a CBUS pin), and even if it is connected to a charger not a USB device. This means the software can tell if running from battery or not, and stay awake when being used for USB debug.
How low does the ESP32-WROOM-32 go?
Well, the good news is that the ESP32-WROOM-32 does indeed use bugger all (aka 1uA) in deep sleep. This is impressive, so we are looking at under 35uA idle current for the whole board from a 9V supply when idle.
Obviously we need to wake up occasionally, but we can wake up, boot, connect to WiFi, connect to MQTT, report status, and shut down in under a second with fixed IP. Indeed, the WiFi can be in use for under half a second, which is impressive. We need to do some long term tests to confirm battery life.
Measuring the voltage?
Of course, one thing we want to measure is the battery voltage. That allows us to see if we have a low battery. It is essential for any battery based device to tell you the battery is low. The answer is a simple potential divide feeding an ADC input to the ESP32. Except that draws current! Even 1MΩ divide is 9uA at 9V, 100% of the time.The answer is a FET, well, two FETs. I am not an electrical engineer so this needed a bit of research. One FET or transistor would not work as it had to be at the "top" of the divider. If it was at the bottom of the divider it would mean 9V going in to the ADC pin when the FET was off. But when at the top of the divider you don't have GND as a reference to drive the FET.
The answer is an N-channel FET driving a P-channel FET, all in one package. Thanks to twitter for help on this. It works! I can turn on the divider, take a reading, and turn off again. I have some resistors to ensure than when GPIOs are isolated the FET stays off anyway. Sorted.
How low can you go?
Can I do better than 35uA? Well, yes, probably. The ESP32-WROOM-32 itself goes down to 1uA or so. The regulator in shutdown goes to 1uA but as that annoying potential divider still. If I was able to shutdown and disconnect the power from the ESP32-WROOM-32, it could run off a capacitor for many seconds at 1uA.
So basically I'd need a way for the processor to turn off its own power most of the time!
The trick is ensuring that if you sleep too long, the power will come back on anyway, and indeed when first powered up.
I think I can do this with another FET, pulling the shutdown pin to GND, driven from a GPIO pin. When no power the GPIO will go to ground, pulled by parasitic diodes if nothing else, and cause the FET to go off. Of course you still have the issue of making the shutdown pin then go high when the FET is off, with the only power being the battery, so you still need that one pull up resistor. I wonder how big we can make it? If we can make it 10MΩ we waste only 1uA on that.
The same signal driving the shutdown pin could also drive a FET switching the feedback potential divider, so we turn that off too. It may need some careful design, e.g. FET at bottom of that divide, to ensure we don't fool the regulator in to supplying too much power because its feedback is not get connected, but that should not be rocket science.
For now, I'll test using the current design, idling at 35uA, and see how it goes. But I may yet make a new version that tries to turn itself off most of the time :-)
P.S. I am such a fan of solder paste now, I can't see me ordering boards without getting a stencil as well. It is so quick and so reliable, it is quite amazing really...