I revised my measurement setup:
- measuring the voltage drop over a 1 kOhm resistor put in series with the ESP32s GND connection using a oscilloscope
- the resistor is shorted during the ESP32's startup to allow it to draw enough current during startup
- the oscilloscope uses 10:1 probes. Hence, I set the oscilloscope to 1:0.01 probes and the channels unit to A(mpere). So it directly converts the units correctly and displays the current that flows through the resistor. Without the ESP32 (but still the voltage regulator connected) the oscilloscope shows near 0A (<200nA, so this should be close enough) and when the ESP is connected and in deep sleep it measured ~77 µA or ~84 µA on average - depending on the some settings in software.
I did several tests:
- adc_power_off() - no effect on current drawn (seems to be disabled by default)
- rtc_gpio_force_hold_dis_all() - no effect on current drawn
- rtc_gpio_isolate(GPIO_NUM_0 - …) - reduced current from ~84 µA to ~77 µA; however the current then has a periodic sine pattern (seems to be 50 Hz interference from the power grid).
- esp_sleep_enable_timer_wakeup() -
FINAL SOLUTION:
NOT WORKING: Calling rtc_gpio_isolate()
for GPIO12 and GPIO15 is the suggested in the internet (e.g. Espressif's docs or another Espressif example, also some non-Espressif code that I can't find right now).
Since this did not work, I was calling this function for -ALL- RTC GPIOs, which seems to cause different issues for other pins. I believe due to floating input connections of pins in input mode or something like this. BUT, Instead calling gpio_reset_pin()
on all RTC GPIO PINS did resolve it! According to the docs this will "Reset an gpio to default state (select gpio function, enable pullup and disable input and output)."
Further research showed that I needed only to call gpio_reset_pin() for gpio_reset_pin(GPIO_NUM_2);
(note not 12, but 2!) to achieve the same result. And finally also rtc_gpio_isolate(GPIO_NUM_2);
does achieve the same result - but not when calling rtc_gpio_isolate() for all the other GPIO pins too...
Result:
~7 µA current consumption (long term average)... that's even below 10 µA from the specs. Yeah!
This also works when the ULP is enabled. While the ULP is enabled the current consumption shoots up to ~230 µA and then decreases to 7 µA again when the ULP is in HALT-state (until its again woken up be the configured RTC period).
This is the code I used to reset all the pins:
gpio_reset_pin(GPIO_NUM_0);
gpio_reset_pin(GPIO_NUM_2);
gpio_reset_pin(GPIO_NUM_4);
gpio_reset_pin(GPIO_NUM_12);
gpio_reset_pin(GPIO_NUM_13);
gpio_reset_pin(GPIO_NUM_14);
gpio_reset_pin(GPIO_NUM_15);
gpio_reset_pin(GPIO_NUM_25);
gpio_reset_pin(GPIO_NUM_26);
gpio_reset_pin(GPIO_NUM_27);
gpio_reset_pin(GPIO_NUM_32);
gpio_reset_pin(GPIO_NUM_33);
gpio_reset_pin(GPIO_NUM_34);
gpio_reset_pin(GPIO_NUM_35);
gpio_reset_pin(GPIO_NUM_36);
gpio_reset_pin(GPIO_NUM_37);
gpio_reset_pin(GPIO_NUM_38);
gpio_reset_pin(GPIO_NUM_39);
My best guess is that the isolate call does completely disconnect the inputs while the reset call additionally activates the pullup, which prevents interferences to be captured by the 'isolated' inputs causing continuous flipping of the inputs between high and low, which consumes some energy in the pins input logic and also causes those 50 Hz sinusoidal fluctuations.
So far I've no idea what's up with the GPIO_NUM_2 pin. There is nothing connected to it, nor should there be any special usage of the pin per default.