arduino-esp32
arduino-esp32 copied to clipboard
ESP32-U4WDH rtc wakeup
Board
ESP32-U4WDH
Device Description
personal PCB
Hardware Configuration
no
Version
latest master (checkout manually)
IDE Name
arduino-1.8.13
Operating System
Windows
Flash frequency
40MHz
PSRAM enabled
yes
Upload speed
115200
Description
Hello everyone, I made a small software with Arduino for the ESP32-WROOM-32U. ESP reads sensor data and goes back to sleep. It is woken up again via GPIO32. With the WROOM module it worked without any problems. Now I have switched to the ESP32-U4WDH with the internal memory. Both processors have the same data sheet. But no wakeup works with the ESP32-U4WDH. If I read the status with the same port it works without problems but waking up doesn't work. Here is the command:
esp_sleep_enable_ext0_wakeup(GPIO_NUM_32,1); //1 = High, 0 = Low
Does somebody has any idea? Which board do I have to select in the Arduino?
Sketch
esp_sleep_enable_ext0_wakeup(GPIO_NUM_32,1); //1 = High, 0 = Low
Debug Message
no Errors
Other Steps to Reproduce
no Failure
I have checked existing issues, online documentation and the Troubleshooting Guide
- [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@esmersystems - The ESP32-U4WDH module is based on the ESP32-SOLO-1 chip variant, which is a single-core processor. However, it’s important to note that the Arduino IDE currently supports the dual-core version of the ESP32. This has some implications regarding how FreeRTOS and IDF works.
For single core ESP32, sdkconfig shall define CONFIG_FREERTOS_UNICORE, but it is not set for the ESP32 in Arduino. I'd suggest that you trying to set all RUNNING_CORE to Core0 (instead of Core1). Not sure if this would solve the issue.
If it doesn't work, you can try to change the project to build as Arduino as IDF Component and manually set your sdkconfig using Menuconfig option.
As reference you can also check this issue: https://github.com/espressif/arduino-esp32/issues/5183
One possible alternative would be using PlatformIO + Tasmota for the ESP32-Solo, as @Jason2866 suggested in https://github.com/espressif/arduino-esp32/issues/5183#issuecomment-1183099472 platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.4/platform-espressif32-solo1-2.0.4.zip
Another alternative is using this libraries as in @lbernstone suggested in https://github.com/espressif/arduino-esp32/issues/5183#issuecomment-841430645 https://github.com/lbernstone/arduino-esp32-solo
Maybe they can add more information here.
Regarding to the datasheet the ESP32-U4WDH is a dual core. If it would be a single core it would get stuck in bootloader code already. It was a one core but the actual ones are dual core. Details
Thanks. Dualcore working fine… Do you have any idea why rtc wakeup is not working?
Regarding to the datasheet the ESP32-U4WDH is a dual core. If it would be a single core it would get stuck in bootloader code already. It was a one core but the actual ones are dual core. Details
Thanks @Jason2866 for the update. @esmersystems - Therefore I see no reason for not getting the RTC wakeup not working. It should work like any ESP32.
100nF is connected on VCC-RTC pin. Maybe powersupply issue? As GPIO its work fine
What is the different etween RTC function0 and function0?
Can you get ext0 to trigger on other pins?
What is the different etween RTC function0 and function0?
RTC GPIO9 can controled by the ULP (Ultra Low Processor) and it can be set to High or Low as well as trigger Interrupts while sleeping. GPIO32 is the name of the IO controlled by the GPIO Peripheral. Both are connected to the same IO Pad.
More information in https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html The ESP32 TRM also talks about it. https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#iomuxgpio
@esmersystems - I've found something in the IDF examples. https://github.com/espressif/esp-idf/blob/master/examples/system/deep_sleep/main/ext_wakeup.c
#if CONFIG_EXAMPLE_EXT0_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
const int ext_wakeup_pin_0 = 25;
#else
const int ext_wakeup_pin_0 = 3;
#endif
void example_deep_sleep_register_ext0_wakeup(void)
{
printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0);
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 1));
// Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
// EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs.
// No need to keep that power domain explicitly, unlike EXT1.
ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_0));
ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_0));
}
#endif // CONFIG_EXAMPLE_EXT0_WAKEUP
It may be necessary to run all these calls (esp_sleep_enable_ext0_wakeup(), rtc_gpio_pullup_dis(), rtc_gpio_pulldown_en()).
@esmersystems - Please check the IDF code example for EXT0, EXT1 and GPIO wakeup. You may find the necessary solution there. https://github.com/espressif/esp-idf/tree/master/examples/system/deep_sleep
@lbernstone @Jason2866 @SuGlider @kumekay
Short Summary:
GPIO wakeup doesn't work on any of the pins.
At first I suspected that the VCC_RTC supply voltage had problems, but it also supplies the touch and the touch works without any problems. The example code from the Arduino library works with a WROOM module without any problems. Wakeup only doesn't work with the ESP32-U4WDH
Have you tested one of the IDF examples? Using IDF 5.1 would be the choice since Arduino is compiled with this version. By doing that you know if the problem happens already in IDF.
Does timer wakeup work? Have you tried forcing power domains to stay on? This seems like the main difference b/w a U4 and D0. My guess would be that it is having trouble turning the ESP_PD_DOMAIN_VDDSDIO back on.
This is the standart TimerWakeup Sample. I have added this
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON);
This don'work also....
Which Board should i select for ESP32-U4WDH? I use ESP-WROOM-DA-Module
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds /
#define TIME_TO_SLEEP 5 / Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0;
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
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"); break;
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;
}
}
void setup() {
Serial.begin(115200);
delay(1000); //Take some time to open up the Serial Monitor
//Increment boot number and print it every reboot
++bootCount;
Serial.println("Boot number: " + String(bootCount));
//Print the wakeup reason for ESP32
print_wakeup_reason();
/*
First we configure the wake up source
We set our ESP32 to wake up every 5 seconds
*/
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
/*
Next we decide what all peripherals to shut down/keep on
By default, ESP32 will automatically power down the peripherals
not needed by the wakeup source, but if you want to be a poweruser
this is for you. Read in detail at the API docs
http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html
Left the line commented as an example of how to configure peripherals.
The line below turns off all RTC peripherals in deep sleep.
*/
// esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON);
//Serial.println("Configured all RTC Peripherals to be powered down in sleep");
/*
Now that we have setup a wake cause and if needed setup the
peripherals state in deep sleep, we can now start going to
deep sleep.
In the case that no wake up sources were provided but deep
sleep was started, it will sleep forever unless hardware
reset occurs.
*/
Serial.println("Going to sleep now");
Serial.flush();
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop() {
//This is not going to be called
}
Which Board should i select for ESP32-U4WDH? I use ESP-WROOM-DA-Module
DA ==> Dual Antenna module. You can try the regular "ESP32 Dev Module" or "ESP32 PICO-D4"
GPIO32 and GPIO33 can be used to connect the external 32.768 kHz crystal oscillator. Does your board have such component? It could be a reason for not working as wake up pin. What board model is that exactly?
@esmersystems - The datasheet says that the ESP32-U4WDH supports a maximum frequency of 160MHz. Please make sure this is the "CPU Frequency" selected in the Arduino Board Menu.
This is the standart TimerWakeup Sample. I have added this
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON);
This don'work also....
Which Board should i select for ESP32-U4WDH? I use ESP-WROOM-DA-Module
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds / #define TIME_TO_SLEEP 5 / Time ESP32 will go to sleep (in seconds) */ RTC_DATA_ATTR int bootCount = 0; /* Method to print the reason by which ESP32 has been awaken from sleep */ 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"); break; 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; } } void setup() { Serial.begin(115200); delay(1000); //Take some time to open up the Serial Monitor //Increment boot number and print it every reboot ++bootCount; Serial.println("Boot number: " + String(bootCount)); //Print the wakeup reason for ESP32 print_wakeup_reason(); /* First we configure the wake up source We set our ESP32 to wake up every 5 seconds */ esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds"); /* Next we decide what all peripherals to shut down/keep on By default, ESP32 will automatically power down the peripherals not needed by the wakeup source, but if you want to be a poweruser this is for you. Read in detail at the API docs http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html Left the line commented as an example of how to configure peripherals. The line below turns off all RTC peripherals in deep sleep. */ // esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON); //Serial.println("Configured all RTC Peripherals to be powered down in sleep"); /* Now that we have setup a wake cause and if needed setup the peripherals state in deep sleep, we can now start going to deep sleep. In the case that no wake up sources were provided but deep sleep was started, it will sleep forever unless hardware reset occurs. */ Serial.println("Going to sleep now"); Serial.flush(); esp_deep_sleep_start(); Serial.println("This will never be printed"); } void loop() { //This is not going to be called }
I don't see the call to esp_sleep_enable_ext0_wakeup(GPIO_NUM_32,1); //1 = High, 0 = Low in the code....
try this code:
/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots
This code is under Public Domain License.
Hardware Connections
======================
Push Button to GPIO 33 pulled down with a 10K Ohm
resistor
NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.
Author:
Pranav Cherukupalli <[email protected]>
*/
#define BUTTON_PIN_BITMASK 0x100000000 // 2^32 in hex -- GPIO32 for EXT1 call
RTC_DATA_ATTR int bootCount = 0;
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
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"); break;
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;
}
}
void setup(){
Serial.begin(115200);
delay(1000); //Take some time to open up the Serial Monitor
//Increment boot number and print it every reboot
++bootCount;
Serial.println("Boot number: " + String(bootCount));
//Print the wakeup reason for ESP32
print_wakeup_reason();
/*
First we configure the wake up source
We set our ESP32 to wake up for an external trigger.
There are two types for ESP32, ext0 and ext1 .
ext0 uses RTC_IO to wakeup thus requires RTC peripherals
to be on while ext1 uses RTC Controller so doesnt need
peripherals to be powered on.
Note that using internal pullups/pulldowns also requires
RTC peripherals to be turned on.
*/
esp_sleep_enable_ext0_wakeup(GPIO_NUM_32,1); //1 = High, 0 = Low
//If you were to use ext1, you would use it like
//esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ANY_HIGH);
//Go to sleep now
Serial.println("Going to sleep now");
esp_deep_sleep_start();
Serial.println("This will never be printed");
}
void loop(){
//This is not going to be called
}