Skip to content
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

Unexpected light sleep and deep sleep behaviour on ESP32-S3 #6612

Open
1 task done
idea--list opened this issue Apr 23, 2022 · 18 comments
Open
1 task done

Unexpected light sleep and deep sleep behaviour on ESP32-S3 #6612

idea--list opened this issue Apr 23, 2022 · 18 comments
Assignees
Labels
Chip: ESP32-S3 Issue is related to support of ESP32-S3 Chip Status: In Progress Issue is in progress Status: Test needed Issue needs testing

Comments

@idea--list
Copy link

Board

Adafruit ESP32-S3 Feather

Device Description

Adafruit ESP32-S3 Feather

Hardware Configuration

Nothing attached

Version

latest development Release Candidate (RC-X)

IDE Name

Arduino IDE V1.8.19

Operating System

Windows 10

Flash frequency

80MHz

PSRAM enabled

no

Upload speed

115200

Description

Began to try the ESP32-S3 today and find unexpected behaviour of the native USB-Serial converter.

When the sketch uses deep sleep:
I can hear the sound playing when the COM port detaches and even when the board is recognized when waking up after deep sleep. However the the Serial output updates only before the board goes to deep sleep for the first time. Later on the serial output does not update despite the board is waking up. Power consumption is as expected.
Did not find earlier report regarding deep sleep.

When the sketch uses light sleep:
I do not see any serial output at all (not even in the 1st cycle). Do not hear any sounds for detaching/recognition and also the power consumption drops to the expected level only in the 1st cycle but after that it remains at least 87mA without ever dropping back to low levels. Seem like the board can not reenter light sleep after it has waken up for the first time.
This might be related to #6581

Sketch

#include <WiFiClientSecure.h>

const char* ssid     = "SSID";     // your network SSID (name of wifi network)
const char* password = "password"; // your network password

const char*  server = "www.howsmyssl.com";  // Server URL


WiFiClientSecure client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  delay(15000);

  esp_sleep_enable_timer_wakeup(10e6);  //

  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  // attempt to connect to Wifi network:
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    // wait 1 second for re-trying
    delay(1000);
  }

  Serial.print("Connected to ");
  Serial.println(ssid);

  Serial.println("\nStarting connection to server...");
  client.setInsecure();//skip verification
  if (!client.connect(server, 443))
    Serial.println("Connection failed!");
  else {
    Serial.println("Connected to server!");
    // Make a HTTP request:
    client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
    client.println("Host: www.howsmyssl.com");
    client.println("Connection: close");
    client.println();

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        Serial.println("headers received");
        break;
      }
    }
    // if there are incoming bytes available
    // from the server, read them and print them:
    while (client.available()) {
      char c = client.read();
      Serial.write(c);
    }

    client.stop();

    //esp_deep_sleep_start();
    esp_light_sleep_start();
  }
}

void loop() {
  // do nothing
}

Debug Message

None

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@idea--list idea--list added the Status: Awaiting triage Issue is waiting for triage label Apr 23, 2022
@P-R-O-C-H-Y P-R-O-C-H-Y added Status: Test needed Issue needs testing Chip: ESP32-S3 Issue is related to support of ESP32-S3 Chip labels Apr 25, 2022
@idea--list
Copy link
Author

Oh, my bad... I am so used to boards that have a dedicated serial to USB converter chip 😉

However the Adafruit ESP32S3 Feather board comes only with the native USB inside the the ESP32S3 module... so when the MCU goes to light/deep sleep the board simply cuts the serial connection to the PC. And it does not reestablish a working serial connection to the PC when the board wakes up.

Is there any solution for that?

@me-no-dev
Copy link
Member

Are you using the S3 feather board definition? It should be using TinyUSB (USB-OTG) for serial, which should re-enumerate on boot.

@idea--list
Copy link
Author

@me-no-dev
These are the settings i am using:
Screenshot 2022-04-29 001842

@idea--list
Copy link
Author

idea--list commented Apr 28, 2022

By the way meanwhile i also tried putty, but even that behaves exactly the same as Arduino IDE's own serial monitor and the serial connection does not seem to automatically reestablish when the board wakes up from sleep.

However if i close the serial monitor and reopen that again just when the board is waking up, then i see the serial output generated in the actual wake cycle, but as soon the board goes to sleep next time, the serial connection breaks again, and does not reestablish automatically when the board wakes up next time.

@me-no-dev
Copy link
Member

Thanks @idea--list . I'll give it a try. Did not expect to have issues with USB-OTG :)

@me-no-dev me-no-dev self-assigned this Apr 28, 2022
@me-no-dev me-no-dev removed the Status: Awaiting triage Issue is waiting for triage label Apr 28, 2022
@VojtechBartoska VojtechBartoska added this to the 2.0.4 milestone May 4, 2022
@me-no-dev
Copy link
Member

I tested the sketch and it works fine at least on MacOS. I think that you have a small misunderstanding of how light sleep works. As opposed to Deep Sleep, Light Sleep will continue the execution from where esp_light_sleep_start was called. I added print and delay statements to the loop which printed out once light sleep was over.

Some operating systems / USB drivers might not like the fact that the ESP is not responding on the USB while in light sleep and can disable the device/halt it. At least on MacOS that does not seem to be an issue with CDC.

@VojtechBartoska can we get this tested on Linux and Windows?

@me-no-dev me-no-dev added the Status: In Progress Issue is in progress label May 9, 2022
@me-no-dev me-no-dev moved this from Todo to In Progress in Arduino ESP32 Core Project Roadmap May 9, 2022
@me-no-dev
Copy link
Member

me-no-dev commented May 11, 2022

cc @SuGlider (Please test on Windows)

@VojtechBartoska
Copy link
Contributor

@PilnyTomas please help testing this on Linux.

@PilnyTomas
Copy link
Contributor

PilnyTomas commented May 19, 2022

Linux works ok in both Arduino IDE and terminal when connected to the UART terminal on the dev board.
When connected to the USB terminal on the dev board there is only debug log output (log_x) but no serial output (Serial.print)
I have edited portion of the sketch as follows:

Serial.begin(115200);
while(!Serial){;}
Serial.println("Serial: Starting");
log_d("log: Starting");
delay(15000);
Serial.println("Serial: Entering sleep");
log_d("log: Entering sleep");

esp_sleep_enable_timer_wakeup(10e6);  //

Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
log_d("log: Attempting to connect to SSID: %s", ssid);

And the resulting output in Arduino IDE is this:

SPIWP:0xee
[   252][D][issue_6612.ino:16] setup(): log: Starting
[ 15252][D][issue_6612.ino:19] setup(): log: Entering sleep
[ 15253][D][issue_6612.ino:25] setup(): log: Attempting to connect to SSID: SSID

Also on the RESET button press, the port number in Linux changes and I have to manually switch the port number in Arduino IDE therefore I miss some output if I try to reset the board - the output was captured after flashing.

@VojtechBartoska
Copy link
Contributor

Light Sleep & Deep sleep needs to be tested, same setup with 10 seconds.

@PilnyTomas
Copy link
Contributor

Retested. Exact code and logs
Short summary: UART port works ok
USB port -> light sleep works ok, deep sleep and/or RESET button press => port switching, but otherwise seems to work.

@SuGlider
Copy link
Collaborator

SuGlider commented May 23, 2022

@me-no-dev
I have tested it with Windows. Issue confirmed.
After returning from Light Sleep, USB CDC hangs and there is no output.

I created a sketch for testing it with a "LED signaling"
Sketch below indicates that the ESP32-S3 continues to work, as seen in the RGB LED, but no CDC output anymore.
When using UART eveything works fine, UART output and the LEDs.

/ ESP32-S3 devkit board uses pin 48 as RGB NeoPixel LED
#define BUILTIN_RGBLED_PIN   48
// RMT peripheral is used to drive the RGB LED
rmt_obj_t* rmt_LED = NULL;
rmt_data_t led_data[8 * 3]; // 8 bits x 3 colors per LED
enum {WHITE, RED, GREEN, BLUE, YELLOW, CYAN, MAGENTA, OFF};
int LED_Colors[8][3] =  {
  //Green, Red, Blue
  { 0xFF, 0xFF, 0xFF }, // White
  { 0x00, 0xFF, 0x00 }, // Red
  { 0xFF, 0x00, 0x00 }, // Green
  { 0x00, 0x00, 0xFF }, // Blue
  { 0xC0, 0xFF, 0x00 }, // Yellow
  { 0xB0, 0x00, 0xFF }, // Cyan
  { 0x00, 0xD0, 0xB0 }, // Magenta
  { 0x00, 0x00, 0x00 }, // Off | Black
};

void setLEDColor(int *color, rmt_obj_t *rmtObj) {
  if (rmtObj == NULL || color == NULL) return;

  // Init data with only one led ON
  int col, bit;
  int i = 0;
  for (col = 0; col < 3; col++ ) {
    for (bit = 0; bit < 8; bit++) {
      if ( color[col] & (1 << (7 - bit)) ) {
        led_data[i].level0 = 1;
        led_data[i].duration0 = 8;
        led_data[i].level1 = 0;
        led_data[i].duration1 = 4;
      } else {
        led_data[i].level0 = 1;
        led_data[i].duration0 = 4;
        led_data[i].level1 = 0;
        led_data[i].duration1 = 8;
      }
      i++;
    }
  }
  // Send the data
  rmtWrite(rmt_LED, led_data, 8 * 3); // 8 bits x 3 colors per LED
}


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    delay(100);
  }
  if ((rmt_LED = rmtInit(BUILTIN_RGBLED_PIN, RMT_TX_MODE, RMT_MEM_64)) == NULL) {
    Serial.println("RGB LED init failed\n");
    rmt_LED = NULL;
  }
  if (rmt_LED) rmtSetTick(rmt_LED, 100);

  esp_sleep_enable_timer_wakeup(10e6);
  setLEDColor(LED_Colors[WHITE], rmt_LED);
#if 0
  // DEEP sleep test.
  Serial.println("\n\nEntering in DEEP Sleep...");
  Serial.flush();
  esp_deep_sleep_start();
  // From this point on it will never get executed back from deep sleep
  // Board will hard reset after returning from deep sleep.
  Serial.println("Got back from DEEP Sleep");
#else
  // LIGHT Sleep test.
  Serial.println("\n\nEntering in LIGHT Sleep...");
  Serial.flush();
  esp_light_sleep_start();
  Serial.println("Got back from LIGHT Sleep...\n");
#endif
  Serial.flush();
}

void loop() {
  static uint32_t count = 0;
  Serial.printf("Loop CDC OUTPUT#%d\n", count++);
  setLEDColor(LED_Colors[count & 7], rmt_LED);
  delay(2000);
}

IDE Settings for CDC:

image

@SuGlider
Copy link
Collaborator

SuGlider commented May 23, 2022

@PilnyTomas -
Do you want to try it with the sketch above and with the same IDE settings using Linux?
Bye the way, the RMT LED routines can be useful for you ;-)

If everything works fine, using CDC or UART, you should see a log output like this:

Entering in LIGHT Sleep...
Got back from LIGHT Sleep...

Loop CDC OUTPUT#0
Loop CDC OUTPUT#1
Loop CDC OUTPUT#2
Loop CDC OUTPUT#3
Loop CDC OUTPUT#4
Loop CDC OUTPUT#5
Loop CDC OUTPUT#6
Loop CDC OUTPUT#7
Loop CDC OUTPUT#8
Loop CDC OUTPUT#9

@SuGlider
Copy link
Collaborator

SuGlider commented May 23, 2022

For windows the output on CDC USB port is:

Entering in LIGHT Sleep...

And nothing else, just the LED changing colors after that....

@SuGlider
Copy link
Collaborator

SuGlider commented May 23, 2022

Update...

It seems that the whole ESP32-S3 hangs!
How to reproduce the issue:

Set Menu->Tools->Upload Mode: "UART0 / Hardware CDC"
Select the UART COM port as well, in my case, it is COM21
Upload the sketch having: Menu->Tools->USB CDC On Boot: "Enabled"
Open Serial Monitor (connected to the UART port) and wait for the ESP32-S3 BOOT messages.
With the Serial Monitor Window still open, go to the IDE Menu and change the Port to the USB CDC one, it will reset the Serial Monitor window to that port - in my case COM4
Only after that the LED goes WHITE! - you will see the output "Entering in LIGHT Sleep..." and no more output.
The sketch goes to the loop() and changes the color of the LED - red, green, blue and .... FREEZE!
It has hanged!

Now.... the trick! With the Serial Monitor still open, Change the COM port back to the UART one (in my case COM21).....
Suprise! No output any more, but the LED goes to YELLOW! and then follows the color sequence!

That's really wierd!

Change it back to the USB CDC port.... it freezes again!
Change it back to UART port... it unfreezes!

There is some sort of bug there, for sure! @me-no-dev

Update 2

The issue has to do with the Light Sleep...
removing the Light Sleep entering code, and alternating the Serial Monitor Window port between USB CDC and UART, has no effect at all. Everything works fine, LED colors and CDC output.

@me-no-dev
Copy link
Member

@SuGlider sounds like the sketch is waiting to be able to write to somewhere and since nobody is reading, the fifo is full and hanging. Switching the port probably re-sends some packet to the USB and it let's it run. On MacOS where light sleep is not an issue, the sketch continues to run without issues and switching ports.

@SuGlider
Copy link
Collaborator

SuGlider commented May 24, 2022

@SuGlider sounds like the sketch is waiting to be able to write to somewhere and since nobody is reading, the fifo is full and hanging. Switching the port probably re-sends some packet to the USB and it let's it run. On MacOS where light sleep is not an issue, the sketch continues to run without issues and switching ports.

It need deeper investigation to find why CDC can't recover and send the data from FIFO out when using Windows.

For Windows, there is this problem and after returning from light sleep it can't recover and CDC hangs along with the Arduino Task execution.
It looks like, as @me-no-dev said, that the CDC TX Task (high priority) blocks and nothing else runs in the ESP32-S3.
It sounds like a task starvation issue caused by some CDC signaling that prevents it from sending the bytes out.

@VojtechBartoska VojtechBartoska removed this from the 2.0.4 milestone Jun 1, 2022
@s-light
Copy link

s-light commented Dec 8, 2023

just stumbled on this issue on my search for *sleep examples..

i converted the example from to use the adafruit neopixel library as the rmt thing did not compile for me..

// https://github.com/espressif/arduino-esp32/issues/6612#issuecomment-1135183742

// converted to use Adafruit NeoPixel lib

#include <Adafruit_NeoPixel.h>

Adafruit_NeoPixel pixels(1, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);

enum {
    WHITE,
    RED,
    GREEN,
    BLUE,
    YELLOW,
    CYAN,
    MAGENTA,
    OFF
};
uint32_t LED_Colors[8] = {
    // Red, Green, Blue
    0xFFFFFF,  // White
    0xFF0000,  // Red
    0x00FF00,  // Green
    0x0000FF,  // Blue
    0xFFC000,  // Yellow
    0x00B0FF,  // Cyan
    0xD000B0,  // Magenta
    0x000000,  // Off | Black
};

void setup() {
    // Initialize serial and wait for port to open:
    delay(100);
    Serial.begin(115200);
    while (!Serial) {
        delay(100);
    }

    Serial.println("");
    Serial.println("test_sleep.ino");

#if defined(NEOPIXEL_POWER)
    // If this board has a power control pin, we must set it to output and high
    // in order to enable the NeoPixels. We put this in an #if defined so it can
    // be reused for other boards without compilation errors
    pinMode(NEOPIXEL_POWER, OUTPUT);
    digitalWrite(NEOPIXEL_POWER, HIGH);
#endif

    pixels.begin();  // INITIALIZE NeoPixel strip object (REQUIRED)
    pixels.setBrightness(20);  // not so bright

    esp_sleep_enable_timer_wakeup(10e6);

    pixels.fill(LED_Colors[WHITE]);

#if 0
    // DEEP sleep test.
    Serial.println("Entering in DEEP Sleep...");
    Serial.flush();
    esp_deep_sleep_start();
    // From this point on it will never get executed back from deep sleep
    // Board will hard reset after returning from deep sleep.
    Serial.println("Got back from DEEP Sleep");
#else
    // LIGHT Sleep test.
    Serial.println("Entering in LIGHT Sleep...");
    Serial.println("");
    Serial.flush();

    esp_light_sleep_start();

    Serial.println("");
    Serial.flush();
    Serial.println("Got back from LIGHT Sleep...");
#endif

    Serial.flush();
}

void loop() {
    static uint32_t count = 0;
    Serial.print("Loop CDC OUTPUT #");
    Serial.println(count++);
    pixels.fill(LED_Colors[count & 7]);
    pixels.show();
    delay(2000);
}

i tested this with an adafruit Feather ESP32-S3 Reverse TFT.

arduino-cli profile:

profiles:
  adafruit_feather_esp32s3_reversetft:
    fqbn: esp32:esp32:adafruit_feather_esp32s3_reversetft
    platforms:
      - platform: esp32:esp32 (3.0.0-alpha3)
        platform_index_url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json
    libraries:
      - Adafruit NeoPixel (1.12.0)

arduino settings
image

for me the output on my kubuntu 23.10 is:

light sleep minicom

[2023-12-08 14:16:55.041] test_sleep.ino
[2023-12-08 14:16:55.041] Entering in LIGHT Sleep...
[2023-12-08 14:17:05.275] Got back from LIGHT Sleep...
[2023-12-08 14:17:05.275] Loop CDC OUTPUT #0
[2023-12-08 14:17:07.018] Loop CDC OUTPUT #1
[2023-12-08 14:17:09.020] Loop CDC OUTPUT #2
[2023-12-08 14:17:11.022] Loop CDC OUTPUT #3

light sleep arduino ide 2.2.1

14:17:37.901 -> test_sleep.ino
14:17:37.901 -> Entering in LIGHT Sleep...
14:17:48.154 -> Got back from LIGHT Sleep...
14:17:48.154 -> Loop CDC OUTPUT #0
14:17:49.864 -> Loop CDC OUTPUT #1
14:17:51.867 -> Loop CDC OUTPUT #2
14:17:53.865 -> Loop CDC OUTPUT #3

light sleep minicom

[2023-12-08 14:21:41.552] test_sleep.ino
[2023-12-08 14:21:41.553] Entering in DEEP Sleep...
[2023-12-08 14:21:41.553] 
[2023-12-08 14:21:52.596] 
[2023-12-08 14:21:52.596] test_sleep.ino
[2023-12-08 14:21:52.597] Entering in DEEP Sleep...
[2023-12-08 14:21:52.597] 

deep sleep arduino ide 2.2.1

14:19:40.049 -> test_sleep.ino
14:19:40.049 -> Entering in DEEP Sleep...
14:19:40.049 -> 
14:19:51.047 -> 
14:19:51.047 -> test_sleep.ino
14:19:51.047 -> Entering in DEEP Sleep...
14:19:51.047 -> 

→ 😄 so for me it is working :party:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Chip: ESP32-S3 Issue is related to support of ESP32-S3 Chip Status: In Progress Issue is in progress Status: Test needed Issue needs testing
Projects
Status: In Progress
Development

No branches or pull requests

7 participants