gpio_hold_en not working as expected since 2.0.0
Board
ESP-WROOM-32
Device Description
I tested both with a 30 pin and 38 pin dev modules:

Hardware Configuration
There is absolutely nothing attached to the ESP, only an oscilloscope on GPIO 33 and GND.
Version
v2.0.3
IDE Name
PlateformIO
Operating System
macOS 10.15.7
Flash frequency
40Mhz
PSRAM enabled
no
Upload speed
460800
Description
Below's code sets GPIO 33 HIGH, instructs the ESP to hold it in its current state, and sleep for 2 seconds.
Upon wake-up I expect GPIO 33 to be held high, except if / until I call gpio_hold_dis.
When using Arduino-ESP32 version 1.0.6, it works as mentioned. Since 2.0.0, as soon as the ESP wakes up, GPIOs are reset to their default state.
Sketch
pinMode(GPIO_NUM_33, OUTPUT);
digitalWrite(GPIO_NUM_33, HIGH);
gpio_hold_en(GPIO_NUM_33);
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();
Debug Message
M/A
Other Steps to Reproduce
N/A
I have checked existing issues, online documentation and the Troubleshooting Guide
- [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.
I think you now need to call gpio_deep_sleep_hold_en?
Isn't this used to hold all rtc gpios in their current state? I want to to specify which ones, reason why I use gpio_hold_en.
@dynek - This is not an Arduino Issue... but I'm surprised it works with Arduino 1.0.6, because as @lbernstone said you must call gpio_deep_sleep_hold_en() as well, for any both Arduino Cores (1.0.6 and 2.0.0+).
Check the documentation:
Arduino 1.0.6 uses IDF 3.3: https://espressif-docs.readthedocs-hosted.com/projects/esp-idf/en/v3.3.4/api-reference/peripherals/gpio.html#_CPPv412gpio_hold_en10gpio_num_t
Arduino 2.0.0+ uses IDF 4.4: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#_CPPv412gpio_hold_en10gpio_num_t
@dynek - check out this link https://github.com/espressif/arduino-esp32/issues/2712
@dynek Do you still need help?
@VojtechBartoska I still need to give a try, I've been super busy lately.
I was under the impression (when I tried it some weeks ago) that gpio_deep_sleep_hold_en() would hold all RTC GPIO in their current state, not just the ones specified with gpio_hold_en().
Also what's weird in my case is that the GPIO is actually held in the right state, it's just switching back to its default state when the ESP comes back to life, after sleeping.
But I'll give it a try asap, thanks for the hints!
@dynek thanks! Looking forward for your results.
Just tried it and it doesn't work better. I tried with:
gpio_deep_sleep_hold_en();
gpio_hold_en(GPIO_NUM_33);
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();
And:
gpio_hold_en(GPIO_NUM_33);
gpio_deep_sleep_hold_en();
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();
Using gpio_deep_sleep_hold_en or not has the same effect.
GPIO is held in its current state, but as soon as the ESP restarts it goes LOW again.
The documentation is a bit confusing here, but when looking at the gpio_hold_dis function, it looks like what you're seeing is intended behavior.
Not sure when the gpio_hold_dis is called, but maybe you can set the pin to the desired state in the setup() function and call gpio_hold_dis yourself right after?
What does seem contradicting in the documentation is that the gpio_hold_en is apparently not active during deep sleep, but should be activated right after deep sleep.
However the documentation of gpio_deep_sleep_hold_en does contradict this.
So it seems as if gpio_hold_dis is somehow called anyway when waking from deep sleep.
I am having the same problem. I have tried for days to figure out why I my LED was flashing off when it was supposed to remain on after resume from deep sleep.
- LED is set to be on using toggle switch.
- ESP32 goes into Deep Sleep
- Button is pressed which wakes ESP32 to wake up
- When resuming from deep sleep, LED flashes off for a few milliseconds (noticeably blinks)
When sketch is compiled on a Mac 12.5, Arduino IDE 1.8.19, ESP32 Board 2.0.4, issue IS present. When sketch is compiled on a Windows 10 21H1, Arduino IDE 1.8.13, ESP32 Board 1.0.5, issue is NOT present.
#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int bootCountRefresh = 100;
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 60 /* Time ESP32 will go to sleep (in seconds) = Seconds per Cycles */
#define sleep_duration 5
uint64_t GPIO_reason;
uint64_t GPIO_wake_number;
#define pinButton1 33
#define pinButton2 14
char pinLED1 = 2;
char pinTEST = 35;
///////////////////////////////////////////////////////// Setup /////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
Serial.println("\n");
Serial.println("-- Starting Setup -- ");
pinMode(pinButton1, INPUT_PULLDOWN);
//pinMode(pinButton1, INPUT_PULLUP);
pinMode(pinLED1, OUTPUT);
pinMode(pinTEST, INPUT);
print_wakeup_reason();
print_GPIO_wake_up();
//esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, 0); //1 = High, 0 = Low
//esp_sleep_enable_ext0_wakeup(GPIO_NUM_39, 0); //1 = High, 0 = Low
//---esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); //1 = High, 0 = Low
esp_sleep_enable_ext1_wakeup(0x200004000, ESP_EXT1_WAKEUP_ANY_HIGH); //14 , 33
//esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
//esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
//Serial.println("Configured all RTC Peripherals to be powered down in sleep");
}
///////////////////////////////////////////////////////// LOOP /////////////////////////////////////////////////////////
void loop() {
// put your main code here, to run repeatedly:
gpio_hold_dis((gpio_num_t) pinLED1);
bool buttonstate = digitalRead(pinTEST);
digitalWrite(pinLED1, buttonstate);
esp_sleep_enable_timer_wakeup(sleep_duration * uS_TO_S_FACTOR);
goToSleep();
}
///////////////////////////////////////////////////////// print_GPIO_wake_up /////////////////////////////////////////////////////////
void print_GPIO_wake_up() {
GPIO_reason = esp_sleep_get_ext1_wakeup_status();
Serial.print("GPIO that triggered the wake up: GPIO ");
GPIO_wake_number = (log(GPIO_reason)) / log(2);
Serial.println(GPIO_reason);
Serial.print("GPIO that triggered the wake up: GPIO ");
Serial.println(GPIO_wake_number);
}
///////////////////////////////////////////////////////// print_wakeup_reason /////////////////////////////////////////////////////////
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL");
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
}
////////////////////////////////////////////////////// goToSleep ///////////////////////////////////////////////////////////////
void goToSleep() {
gpio_hold_en((gpio_num_t)pinLED1);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
//gpio_pullup_dis(gpio_num);
//rtc_gpio_pulldown_en(GPIO_NUM_39);
gpio_pulldown_en(GPIO_NUM_14);
Serial.println("Going to sleep now");
Serial.println("============================================================================");
Serial.flush();
delay(200);
gpio_deep_sleep_hold_en();
esp_deep_sleep_start();
}
@VojtechBartoska not sure if you are still following this, but curious on your thoughts of my testing.
Hi @EdHayes3, thanks for your feedback!
We will investigate this for next major release 2.1.0 :)
@EdHayes3 Hi and thanks for great test sketch. There is a bug in ESP-IDF for a long time. I have created MR in ESP-IDF with fix. Once its merged and the fix gets to Arduino-esp32 I will inform you and close the issue.
Hi @EdHayes3, @dynek the fix is already merged in ESP-IDF. It isn't in Arduino-core master branch merged yet, but if you wanna give it a try, you can checkout branch idf-release/v4.4 and test that.
@dynek Are you able to test this under 2.0.5 Arduino version please?
@VojtechBartoska Its not fixed in 2.0.5 yet. Will be in IDF 4.4.3. 2.0.5 is based on 4.4.2.
@P-R-O-C-H-Y Perfect, so it will be part of bugfixes release. Thanks for answer and please don't reply during driving. 😄
I'll try asap
Missed @P-R-O-C-H-Y's comment in between, so I just tested with Plateform IO Espressif 32 version 5.2.0:
- Added support for Arduino v2.0.5 (release notes)
- Added support for ESP-IDF v4.4.2 (release notes)
to find out that it still the same. Waiting next iteration :-)
@dynek if you manually check current master branch, it's already using ESP-IDF 4.4.3. Or just wait for 2.0.6 release.
@VojtechBartoska I just tested it on VSCode PlateformIO by adding the following to the project's plateformio.ini file:
platform_packages =
platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master
And I can confirm the problem is solved.
@dynek Great, thanks for testing, closing as solved.