Electronic – ESP32: how to keep a pin high during deep sleep (RTC GPIO pull-ups are too weak)


I'm using an ESP32 in a battery-powered device. The ESP spends most of the time in deep-sleep to save power. The device also has some 5V-powered sensors which I'm feeding from a MCP1640 step-up converter, which is on during the brief active part, and powered off via its "ENABLE" pin during deep sleep. The relevant part of the schematic is:


simulate this circuit – Schematic created using CircuitLab

So, I need to hold pin #4 high during sleep.
Due to sloppy testing of this part, I didn't know that the ESP32 shuts down its GPIOs during deep sleep, so pin #4 isn't kept high, and the sensors remain active. This drains the battery at a much faster-than-expected rate.

I'm wondering whether it's possible to workaround this blunder by a software patch (of course, it's easy to just add an external pull-up resistor to pin 4 – but I have a few devices on the field, which I would hate to have to travel a few hundred kilometres just to solder a resistor to! And the people around aren't tech-savvy to do this themselves; on the contrary, remote software patching is easy and well-tested).

For example, I tried the RTC's pull-up resistors:

gpio_num_t pin = (gpio_num_t) PIN_DISABLE_5V;
rtc_gpio_set_direction(pin, RTC_GPIO_MODE_INPUT_OUTUT);
rtc_gpio_pullup_en(pin);                     // set the pin as pull-up
                    ESP_PD_OPTION_ON);       // keep the RTC IO domain powered

Executing this just before entering deep sleep almost worked, but it turns out the weak pull-up is too weak: probably ~38k if it is a resistance, or 90µA if it's a current source. This is insufficient to drive the ULN2003's pin. I also tried RTC_GPIO_MODE_OUTPUT_ONLY + rtc_gpio_set_level() too, but this didn't seem to increase the drive capability. Another possibility is light-sleep, which I'd avoid as it was buggy some time ago and I don't want to get my devices bricked.

So my question really is: have I exhausted all software options (since the hardware ones also require burning a tankful of gasoline)?

Best Answer

It's not clear that making the resistor change you propose will be effective at solving your problem.

The MCP160 requires that the enable input is taken below 20% of Vin to effectively switch the device off. If Vin is (say) 5 volts then 20% is 1.0 volts and, because the ULN2003 is a darlington, it may not reliably switch this low. However assuming it does switch lower than 1 volt then there is still the possibility that my guess about the value of Vbatt of 5 volts doesn't cover the low end of the range.

For instance if Vbatt is expected to work down to say 2 volts then you can only switch the MCP160 off if the enable pin is taken to less than 0.4 volts. This sounds all to close for my liking and I would recommend you think about the problem a bit more.