Skip to content

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

Closed
dalbert2 opened this issue Apr 23, 2021 · 25 comments
Closed

UART not able to wake ESP32 from Light Sleep #5107

dalbert2 opened this issue Apr 23, 2021 · 25 comments
Assignees
Labels
Area: ESP-IDF related ESP-IDF related issues Area: LIB Builder Depends on Lib Builder Type: Bug 🐛 All bugs
Milestone

Comments

@dalbert2
Copy link

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:

#include <Arduino.h>
#include <driver/uart.h>

  // See: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html#api-reference
  // See: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/system/sleep_modes.html#entering-light-sleep

void serialEvent();

void setup() {
  // wake from sleep every 10s
  esp_sleep_enable_timer_wakeup(10*1000000); 

  // Configure UART0
  Serial.begin(115200);
  while (!Serial) { delay(500); }
  uart_set_wakeup_threshold(UART_NUM_0, 3);   // 3 edges on U0RXD to wakeup
  esp_sleep_enable_uart_wakeup(UART_NUM_0);   // Enable UART 0 as wakeup source

  Serial.printf("ESP32 light sleep with UART wake\r\n");
  Serial.printf("SDK: %s\r\n", ESP.getSdkVersion());
  Serial.flush();

}

void loop() {
  if (Serial.available()) {
     Serial.printf("Got key: 0x%X\r\n", Serial.read());
     Serial.flush();
  } else {
     esp_light_sleep_start();
     esp_sleep_wakeup_cause_t wakeup_cause;
     wakeup_cause = esp_sleep_get_wakeup_cause();
     Serial.printf("Wake cause: %d\r\n",(int) wakeup_cause);
     Serial.flush();

  }
}

Debug Messages:

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
ESP32 light sleep with UART wake
SDK: v3.3.5-1-g85c43024c
Wake cause: 4
Wake cause: 4
etc.
@dalbert2
Copy link
Author

dalbert2 commented Apr 23, 2021

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)

     // Reconfigure GPIO3  as GPIO instead of U0RXD and wake on low level
     PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
     gpio_wakeup_enable(GPIO_NUM_3, GPIO_INTR_LOW_LEVEL);
     esp_sleep_enable_gpio_wakeup();
     // Enter light sleep mode
     esp_light_sleep_start();
     // Restore GPIO3 function as U0RXD
     PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
     esp_sleep_wakeup_cause_t wakeup_cause;
     wakeup_cause = esp_sleep_get_wakeup_cause();
     Serial.printf("Wake cause: %d\r\n",(int) wakeup_cause);
     Serial.flush();

@stale
Copy link

stale bot commented Jun 23, 2021

[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 stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Jun 23, 2021
@stale
Copy link

stale bot commented Jul 8, 2021

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

@stale stale bot closed this as completed Jul 8, 2021
@igrr igrr reopened this Jul 16, 2021
@stale
Copy link

stale bot commented Jul 16, 2021

[STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future.

@stale stale bot removed the Status: Stale Issue is stale stage (outdated/stuck) label Jul 16, 2021
@igrr igrr added the Type: Bug 🐛 All bugs label Jul 16, 2021
@igrr
Copy link
Member

igrr commented Jul 16, 2021

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.
Same problem exists in ESP-IDF driver at the moment (internal reference IDF-3183), draft MR with a fix available, planned to be merged before IDF v4.4.
This might be easiest to fix when the issue is also fixed in IDF, and the HardwareSerial is ported to the IDF driver (#5403).

@SuGlider
Copy link
Collaborator

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());
  }
}

@SuGlider
Copy link
Collaborator

SuGlider commented Aug 19, 2021

Actually, I tested the scketch above using version 1.0.6 and 2.0.0.
It works on both. ESP32 goes sleep and then wakes up when something is sent to UART0.

@dalbert2
Copy link
Author

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

@SuGlider
Copy link
Collaborator

SuGlider commented Aug 19, 2021

@dalbert2 :
The sketch you suggested never worked for 1.0.6 nor for 2.0.0.
The sketch I suggested works for both 1.0.6 and 2.0.0. -- BUT it must not initialize UART 0...

It seems that whenever Serial.begin(...) is executed, it prevents ESP32 entering in Light Sleep mode (using UART 0 as wake up port)
I also tried to execute Serial.end() before entering into sleep mode, but it didn't work as well (in both 1.0.6 and 2.0.0)

@dalbert2
Copy link
Author

dalbert2 commented Aug 19, 2021

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

@SuGlider
Copy link
Collaborator

SuGlider commented Aug 20, 2021

@dalbert2 , I think I did not express myself correctly.
When I wrote 2.0.0 I meant the new IDF based version for HardwareSerial.
It means, unfortunately, that this issue is not solved using current Arduino IDF version as suggested by @igrr - maybe he can suggest something else, or as he said, wait for a future IDF version that uses IOMUX in UART.

A potential useful information is that your sketch works fine in ESP32-S2.... in case it may help you somehow.
When using ESP32-S2 and Arduino Core 2.0.0RC1 or the new IDF Version, your sketch reports Wake Cause 8 whenever something is sent to UART0, otherwise it reports Wake Casuse 4.

It looks like using UART IDF makes no difference to this issue at the present time.

@dalbert2
Copy link
Author

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!

@SuGlider
Copy link
Collaborator

SuGlider commented Sep 24, 2021

@dalbert2 @igrr
I have news about this issue:

  1. When using the IDF latest master version from github, I have successfully created an app that starts UART IDF driver, sets UART wakeup mode and after entering in light sleep mode, it wakes up with UART reporting wakeup cause as 8 (UART).
  2. There is no difference in the way it is done in current Arduino 2.0.0 regarding UART, thus, the refactoring done is correct and there is no change necessary.
  3. In current Arduino 2.0.0 HAL, if I comment out setPins() call, it works fine, thus I traced it and I verified that the current precompiled lib we have in the 2.0.0 does not use IO MUX.
  4. After rebuilding all Arduino Libraries using the latest master IDF version and then copying those over the current ones, waking up after UART event did work perfectly well.

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 SuGlider added Area: ESP-IDF related ESP-IDF related issues Area: LIB Builder Depends on Lib Builder labels Sep 24, 2021
@Frwy
Copy link

Frwy commented Sep 30, 2021

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

@SuGlider
Copy link
Collaborator

SuGlider commented Sep 30, 2021

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

  1. clone branch idf-master from ESP32 Arduino GitHub:
    https://github.com/espressif/arduino-esp32/tree/idf-master
    This branch has the latest IDF version compiled libraries.

  2. build your own libraries based on this repository: https://github.com/espressif/esp32-arduino-lib-builder
    There are instructions for building the libraries based on a Linux OS.

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).
You can find where Arduino installs itself for each OS here:
https://support.arduino.cc/hc/en-us/articles/360018448279-Where-can-I-find-the-Arduino15-folder-

In Windows, for instance, you may need to replace
C:\Users{username}\AppData\Local\Arduino15\esp32\hardware\esp32\2.0.0-rc1\tools\sdk
with the same folder structure from (1) or in out/tools/sdk from (2).

@Frwy
Copy link

Frwy commented Oct 2, 2021

@SuGlider Thank you for the instruction. I followed the steps and got some errors.
First I installed ESP32 2.0.0 via board manager. Then I replace the "C:\Users{username}\AppData\Local\Arduino15\esp32\hardware\esp32\2.0.0\tools\sdk" folder with:
https://github.com/espressif/arduino-esp32/ same folder
When I compiled I got these errors:

Archiving built core (caching) in: C:\Users\If\AppData\Local\Temp\arduino_cache_127305\core\core_0c8c75762cecf6c9985a75f673dc94d8.a
Linking everything together...
"C:\\Users\\If\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\xtensa-esp32-elf-gcc\\gcc8_4_0-esp-2021r1/bin/xtensa-esp32-elf-g++" "-Wl,--Map=C:\\Users\\If\\AppData\\Local\\Temp\\arduino_build_948104/SleepMode.ino.map" "-LC:\\Users\\If\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0/tools/sdk/esp32/lib" "-LC:\\Users\\If\\AppData\\Local\\Arduino15\\packages\\esp32\\hardware\\esp32\\2.0.0/tools/sdk/esp32/ld" -T esp32.rom.redefined.ld -T memory.ld -T sections.ld -T esp32.rom.ld -T esp32.rom.api.ld -T esp32.rom.libgcc.ld -T esp32.rom.newlib-data.ld -T esp32.rom.syscalls.ld -T esp32.peripherals.ld -mlongcalls -Wno-frame-address -Wl,--cref -Wl,--gc-sections -fno-rtti -fno-lto -u _Z5setupv -u _Z4loopv -Wl,--wrap=mbedtls_mpi_exp_mod -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u ld_include_panic_highint_hdl -u start_app -u start_app_other_cores -u __ubsan_include -Wl,--wrap=longjmp -u __assert_func -u vfs_include_syscalls_impl -Wl,--undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u __cxa_guard_dummy -DESP32 -DCORE_DEBUG_LEVEL=0 -DARDUINO_RUNNING_CORE=1 -DARDUINO_EVENT_RUNNING_CORE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -Wl,--start-group "C:\\Users\\If\\AppData\\Local\\Temp\\arduino_build_948104\\sketch\\SleepMode.ino.cpp.o" "C:\\Users\\If\\AppData\\Local\\Temp\\arduino_build_948104\\core\\core.a" -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lasio -lbt -lcbor -lunity -lcmock -lcoap -lconsole -lnghttp -lesp-tls -lesp_adc_cal -lesp_hid -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lesp_lcd -lprotobuf-c -lprotocomm -lmdns -lesp_local_ctrl -lsdmmc -lesp_serial_slave_link -lesp_websocket_client -lexpat -lwear_levelling -lfatfs -lfreemodbus -ljsmn -ljson -llibsodium -lmqtt -lopenssl -lperfmon -lspiffs -lulp -lwifi_provisioning -lbutton -ljson_parser -ljson_generator -lesp_schedule -lesp_rainmaker -lqrcode -lws2812_led -lesp-dsp -lesp-face -lesp32-camera -lesp_littlefs -lfb_gfx -lasio -lcbor -lcmock -lunity -lcoap -lesp_hid -lesp_lcd -lesp_local_ctrl -lesp_websocket_client -lexpat -lfreemodbus -ljsmn -llibsodium -lperfmon -lesp_adc_cal -lfatfs -lwear_levelling -lopenssl -lspiffs -lesp_rainmaker -lmqtt -lwifi_provisioning -lprotocomm -lbt -lbtdm_app -lprotobuf-c -lmdns -lconsole -ljson -ljson_parser -ljson_generator -lesp_schedule -lqrcode -lpe -lfd -lfr -ldetection_cat_face -ldetection -ldl -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lphy -lesp_phy -lphy -lesp_phy -lphy -lrtc -lxt_hal -lm -lnewlib -lstdc++ -lpthread -lgcc -lcxx -lapp_trace -lgcov -lapp_trace -lgcov -lc -Wl,--end-group -Wl,-EL -o "C:\\Users\\If\\AppData\\Local\\Temp\\arduino_build_948104/SleepMode.ino.elf"
c:/users/if/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r1/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: cannot find -lesp-face
c:/users/if/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r1/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: cannot find -lpe
c:/users/if/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r1/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: cannot find -lfd
c:/users/if/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r1/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: cannot find -lfr
c:/users/if/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r1/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: cannot find -ldetection_cat_face
c:/users/if/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r1/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: cannot find -ldetection
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board ESP32 Dev Module.

I tried to find some clue to fix it but have no idea these days. Did I do something wrong?
Thanks!

@SuGlider
Copy link
Collaborator

SuGlider commented Oct 2, 2021

@Frwy,

You did it right.
Indeed those libraries are missing in the branch idf-master from arduino-esp32 repository and are not built by arrduino-lib-builder.

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.

@Frwy
Copy link

Frwy commented Oct 3, 2021

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.
To whom use the same steps to update libraries and occur similar errors when compiling:

C:\Users\If\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0/tools/sdk/esp32/include/freertos/include/freertos/FreeRTOSConfig.h:78:2: error: #error "Needs architecture-speific FreeRTOSConfig.h!"
 #error "Needs architecture-speific FreeRTOSConfig.h!"
  ^~~~~
In file included from C:\Users\If\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\cores\esp32/Arduino.h:34,
                 from C:\Users\If\AppData\Local\Temp\arduino_build_222077\sketch\SleepMode.ino.cpp:1:
C:\Users\If\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0/tools/sdk/esp32/include/freertos/include/freertos/task.h:3454:10: fatal error: freertos/task_snapshot.h: No such file or directory
 #include "freertos/task_snapshot.h"
          ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1
Error compiling for board ESP32 Dev Module.

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.
That works for me.

@SuGlider
I have check out the doc about UART. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html#_CPPv425uart_set_wakeup_threshold11uart_port_ti
The note makes me confused:

in ESP32, the wakeup signal can only be input via IO_MUX (i.e. GPIO3 should be configured as function_1 to wake up UART0, GPIO9 should be configured as function_5 to wake up UART1), UART2 does not support light sleep wakeup feature.

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!

@Frwy
Copy link

Frwy commented Oct 4, 2021

@SuGlider, According to my test result,
I can't use UART1 to wake up ESP32 (GPIO26 for UART1 RX and GPIO27 for UART1 TX) .

Serial1.begin(9600, SERIAL_8N1, 26, 27);
uart_set_wakeup_threshold(UART_NUM_1, 3);  
esp_sleep_enable_uart_wakeup(UART_NUM_1);

But I can use GPIO 26 to wake up ESP32, even it is used as UART1 RX pin.

gpio_wakeup_enable(GPIO_NUM_26, GPIO_INTR_LOW_LEVEL);
esp_sleep_enable_gpio_wakeup(); 

Did I configure wrong or miss something important?

@SuGlider
Copy link
Collaborator

SuGlider commented Oct 5, 2021

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. To whom use the same steps to update libraries and occur similar errors when compiling:

Yes, this is an issue. It's now reported in #5734
@me-no-dev will take a look at that.

@SuGlider I have check out the doc about UART. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html#_CPPv425uart_set_wakeup_threshold11uart_port_ti The note makes me confused:

in ESP32, the wakeup signal can only be input via IO_MUX (i.e. GPIO3 should be configured as function_1 to wake up UART0, GPIO9 should be configured as function_5 to wake up UART1), UART2 does not support light sleep wakeup feature.

Regarding IO_MUX, it seems there was some changes:
In the newest version of the TRM on chapter 4.10 IO_MUX Pad List, looking to table 4.10 IO_MUX Pad List
https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
It says that UART0 RX GPIO 3 uses Function Zero for IO_MUX - this is ok and it works fine.
But, for GPIO 9 (RX UART_1) and GPIO 16 (RX UART_2) it points to Function FOUR (4) instead od Function FIVE (5) as described in the Note of https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/uart.html#_CPPv425uart_set_wakeup_threshold11uart_port_ti

Looking to older TRM versions such as https://cdn-shop.adafruit.com/product-files/3269/esp32_technical_reference_manual_en_0.pdf
I can see in 4.10 IO_MUX Pad List and 4.10 IO_MUX Pad List pointing U1RXD and U2RDX to Function 5...

Thus, I think there is some sort of issue that may be present in IDF code as well... not sure.

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)?

In this case you may try waking up from GPIO instead of UART. Maybe it works in you project.

@SuGlider
Copy link
Collaborator

SuGlider commented Oct 5, 2021

@SuGlider, According to my test result, I can't use UART1 to wake up ESP32 (GPIO26 for UART1 RX and GPIO27 for UART1 TX) .

Serial1.begin(9600, SERIAL_8N1, 26, 27);
uart_set_wakeup_threshold(UART_NUM_1, 3);  
esp_sleep_enable_uart_wakeup(UART_NUM_1);

But I can use GPIO 26 to wake up ESP32, even it is used as UART1 RX pin.

gpio_wakeup_enable(GPIO_NUM_26, GPIO_INTR_LOW_LEVEL);
esp_sleep_enable_gpio_wakeup(); 

Did I configure wrong or miss something important?

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
ONLY GPIO 9 can be used for IO_MUX and Wakeup for UART1.
BUT as I said before, it says that it must select Function 4 (four) to enable it! (not Function 5)

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:
https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/sleep_modes.c#L1011-L1022

@Frwy
Copy link

Frwy commented Oct 5, 2021

@SuGlider Thanks for your detailed reply and you answered more than I need!
GPIO wake-up works for my project.
Thanks again for your precious time and hope the libraries will grow better in near future!

@SuGlider
Copy link
Collaborator

This issue is solved by latest Arduino release v2.0.1 RC1 that uses latest IDF 4.4 commits.
Please check it out at https://github.com/espressif/arduino-esp32/releases/

@enricodetoma
Copy link

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: https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/sleep_modes.c#L1011-L1022

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

@xyzzy42
Copy link

xyzzy42 commented Nov 10, 2023

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.

@dalbert2

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: ESP-IDF related ESP-IDF related issues Area: LIB Builder Depends on Lib Builder Type: Bug 🐛 All bugs
Projects
None yet
Development

No branches or pull requests

7 participants