-
Notifications
You must be signed in to change notification settings - Fork 7.6k
UART not able to wake ESP32 from Light Sleep #5107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Note that I am confident the hardware is working because if I configure GPIO3 as a GPIO input prior to light sleep, then I can use the gpio_wakeup to wake on each character received. i.e. this does wake from sleep and displays wakeup cause 7 (ESP_SLEEP_WAKEUP_GPIO)
|
[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions. |
[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. |
[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future. |
This is indeed a bug. It occurs because light sleep wakeup requires UART pins to be connected via the IO MUX. HardwareSerial class (via UART HAL) always uses the GPIO matrix to configure the pins, even if the pins are the ones which can be connected via the IO MUX. |
I confirm that the PR #5549 solves this issue, using ESP32. Code used to test it: #include <esp_sleep.h>
#include <driver/uart.h>
#define LED 2
void setup() {
Serial2.begin(115200);
pinMode(LED, OUTPUT);
while (!Serial2) {
delay(500);
}
// uses UART_2 for sending messages to user
Serial2.println();
Serial2.println("LIGHT SLEEP ENABLED - type something to wake it up!");
// makes sure the message goes out before entering in Light Sleep
Serial2.flush();
int wake_thresh = 3;
uart_set_wakeup_threshold(UART_NUM_0, wake_thresh);
esp_sleep_enable_uart_wakeup(UART_NUM_0);
esp_light_sleep_start();
// ESP32 is now in light sleep mode
// Send something on UART_0 to wake it up
// Starts UART_0 now
Serial.begin(115200);
while (!Serial) {
delay(500);
}
// Clean Serial from wake up message
Serial.flush();
Serial.readString();
// uses UART_2 for sending messages to user
Serial2.println();
Serial2.println("LIGHT SLEEP WAKE UP");
Serial2.end();
Serial.println();
Serial.println("Hey, I' back! Send messages to UART_0 to see echo back...");
Serial.println();
}
void loop() {
// This function will only run when ESP32 returns from Light Sleep!
digitalWrite(LED, HIGH);
delay(50);
digitalWrite(LED, LOW);
delay(50);
while (Serial.available() > 0) {
Serial.write(Serial.read());
}
} |
Actually, I tested the scketch above using version 1.0.6 and 2.0.0. |
@SuGlider it looks like your sketch doesn't initialize UART0 until after the sleep test; do you not see the problem in 1.0.6 with the sketch I posted in the original comment? |
@dalbert2 : It seems that whenever Serial.begin(...) is executed, it prevents ESP32 entering in Light Sleep mode (using UART 0 as wake up port) |
@SuGlider the point of the defect report was that UART character reception does not wake the ESP32 from light sleep. You are correct that GPIO3 will wake it if in GPIO rather than UART mode (which is what I think your sketch demonstrates and which I also showed earlier in this thread), but once it is connected to U0RXD, it won't wake the ESP32. @igrr indicated that he understands the problem (that GPIO3 should be left connected to GPIO in the GPIOMUX and connected to UART0 through the IOMUX) @VojtechBartoska added it to the list of things to do for a future release. I just want to be clear that your sketch does not suggest that the defect is invalid; it is just another demonstration that wake-from-light-sleep using GPIO works, but it does not demonstrate wake-from-light-sleep on UART character reception. The problem configuring the pin as GPIO is that you cannot receive serial data while in light-sleep mode (the character that wakes the ESP will be lost if the pin is configured as GPIO instead of U0RXD). The ESP32 does enter light sleep mode, it just won't exit (wake up) on UART activity; that's why I used a timer and GPIO to illustrate that it is asleep and will wake on other wakeup sources. @igrr is there a workaround to connect U0RXD to GPIO3 via IOMUX and GPIO3 to GPIO via GPIOMUX either once after Serial.begin() or each time before entering light sleep? |
@dalbert2 , I think I did not express myself correctly. A potential useful information is that your sketch works fine in ESP32-S2.... in case it may help you somehow. It looks like using UART IDF makes no difference to this issue at the present time. |
Interesting, thank you @SuGlider , I will test with current IDF as well, but it sounds like it is not fixed yet. Unfortunately, I am using ESP32-WROOM32 modules; if the new IDF doesn't fix the problem, then I'm going to have to look for a workaround as mentioned above. Thanks for testing and reporting on this! |
@dalbert2 @igrr
Conclusion:It does not work currently with 2.0.0 because it is using an old IDF version that hadn't supported IO MUX in UART pin set function. This explains why it doesn't work after executing Serial.begin() - HAL initializes UART rxPin using an old IDF version that doesn't do it within IO MUX. If Serial is not initialized, it keeps default reboot setup (which I believe is based on IO MUX) and then light sleep wakeup works returning code 8 (UART wakeup). Solution to this issue:Update Arduino precompiled IDF library binaries to a newer/latest version. |
@SuGlider, May I ask how to update Arduino precompiled IDF library binaries to a newer stable version? Does that mean using Arduino Board Manager to update ESP32 version to 2.0.0? |
@Frwy, regarding this issue of not waking up using UART, the current Arduino Core 2.0.0 was built on top of a IDF commit from mid July/2021, thus it doesn't include the change made to IDF UART that supports IO MUX pin selection (from Aug/2021). Using Arduino Board Manager to update ESP32 Arduino, it'll be necessary to wait to the next Core Release, maybe v.2.0.1. There are a few ways to obtain the latest IDF version precompiled Arduino libraries:
In both cases it's necessary to replace /tools/sdk/ folder with the one from in the repository from (1), or from the equivalent folder out/ that will be created in (2). In Windows, for instance, you may need to replace |
@SuGlider Thank you for the instruction. I followed the steps and got some errors.
I tried to find some clue to fix it but have no idea these days. Did I do something wrong? |
You did it right. When I tested it, I just copied the new libraries over the previous repository, thus, keeping those library files in the folder. I guess that you have deleted the folder structure before copying the new folder over. My suggestion is to reinstall 2.0.0 and to just copy the new folder structure over it. |
Thanks for @SuGlider help, I finally update the latest IDF version precompiled Arduino libraries and wake up the ESP32 module from light sleep via UART0.
Try to copy FreeRTOSConfig.h and task_snapshot.h from "C:\Users{username}\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\sdk\esp32\include\freertos\include\esp_additions\freertos" and replay the same name file under "C:\Users{username}\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\sdk\esp32\include\freertos\include\freertos" folder. @SuGlider
My project use GPIO26 for UART1 RX and GPIO27 for UART1 TX. They work perfectly on data transfer. Can I wake the ESP32 module from the light sleep by using UART1 (another module send message to ESP32 via GPIO26)? I will test it when I have the hardware on hand. Thanks for the detailed instruction and answers again! |
@SuGlider, According to my test result,
But I can use GPIO 26 to wake up ESP32, even it is used as UART1 RX pin.
Did I configure wrong or miss something important? |
Yes, this is an issue. It's now reported in #5734
Regarding IO_MUX, it seems there was some changes: Looking to older TRM versions such as https://cdn-shop.adafruit.com/product-files/3269/esp32_technical_reference_manual_en_0.pdf Thus, I think there is some sort of issue that may be present in IDF code as well... not sure.
In this case you may try waking up from GPIO instead of UART. Maybe it works in you project. |
Actually based on the TRM https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf In chapter 4.10 IO_MUX Pad List, looking to table 4.10 IO_MUX Pad List I tested GPIO 9 with UART 1 and it didn't work... sorry. important note:UART_1 GPIO 9 and 10 are used by FLASH SPI with QIO mode. In order to use those pins, you must set DIO mode in Arduino IDE Board Menu. Summary:for ESP32 only GPIO 3 - UART_0 currently works with Light Sleep Wakeup. From IDF Code, it seems that only UART0 and UART1 are elegible for Wakeup: |
@SuGlider Thanks for your detailed reply and you answered more than I need! |
This issue is solved by latest Arduino release v2.0.1 RC1 that uses latest IDF 4.4 commits. |
@SuGlider sorry if I comment on this closed issue. I just wanted a confirmation: is UART0 still the only available UART for Light Sleep Wakeup? In my Arduino project I would like to use UART1 or UART2 with Light Sleep Wakeup, leaving UART0 for programming and debugging. |
According to ESP-IDF docs, on the ESP32 only UART0 using GPIO3 or UART1 using GPIO9 can be used as lightsleep wakeup via UART. No other UART or pin combinations will work. On newer ESP32-S[23] and C[236] chips, this is apparently not a problem and any uart/pin combo will work.
According the docs, and also my own tests, this is also true for UART wakeup. It will wake on a character but the character that caused the wakeup will still be lost. |
Hardware:
Board: ESP32 WROOM-32 on custom board
Core Installation version: 1.0.6
IDE name: VSCode with PlatformIO
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 115200
Computer OS: Windows 10
Description:
How can I wake the ESP32 from light sleep when a UART character is received?
Problem: system enters light sleep successfully, power consumption drops as expected, system wakes for timer, but UART activity does not trigger wake from sleep. Serial I/O works correctly when not entering light sleep mode.
Sketch:
Debug Messages:
The text was updated successfully, but these errors were encountered: