arduino-esp32 icon indicating copy to clipboard operation
arduino-esp32 copied to clipboard

ESP32-U4WDH rtc wakeup

Open esmersystems opened this issue 1 year ago • 19 comments

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 avatar Feb 15 '24 14:02 esmersystems

@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.

image

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.

SuGlider avatar Feb 15 '24 20:02 SuGlider

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.

SuGlider avatar Feb 15 '24 21:02 SuGlider

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

Jason2866 avatar Feb 15 '24 21:02 Jason2866

Thanks. Dualcore working fine… Do you have any idea why rtc wakeup is not working?

esmersystems avatar Feb 15 '24 21:02 esmersystems

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.

SuGlider avatar Feb 16 '24 01:02 SuGlider

100nF is connected on VCC-RTC pin. Maybe powersupply issue? As GPIO its work fine

esmersystems avatar Feb 16 '24 05:02 esmersystems

IMG_7645

What is the different etween RTC function0 and function0?

esmersystems avatar Feb 16 '24 05:02 esmersystems

Can you get ext0 to trigger on other pins?

lbernstone avatar Feb 16 '24 05:02 lbernstone

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

image

image

SuGlider avatar Feb 16 '24 17:02 SuGlider

@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()).

SuGlider avatar Feb 16 '24 17:02 SuGlider

@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

SuGlider avatar Feb 16 '24 17:02 SuGlider

@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

esmersystems avatar Feb 19 '24 07:02 esmersystems

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.

Jason2866 avatar Feb 19 '24 14:02 Jason2866

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.

lbernstone avatar Feb 19 '24 21:02 lbernstone

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
}

esmersystems avatar Feb 20 '24 12:02 esmersystems

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?

SuGlider avatar Feb 20 '24 14:02 SuGlider

@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.

SuGlider avatar Feb 20 '24 15:02 SuGlider

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....

SuGlider avatar Feb 20 '24 15:02 SuGlider

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
}

SuGlider avatar Feb 20 '24 15:02 SuGlider