XIAO ESP32C3 Bootloader Connection Problems after DeepSleep Test

Hello,

I have a problem with my XIAO ESP32C3.

For a project I need the deep sleep mode to save energy. For testing I have loaded a sample code from the ESP32 library on my C3. In it the controller is set to DeepSleep mode and wakes up after 5 seconds via “timer wakeup”.

Without thinking too much I loaded the program on my controller.

And now the program is on there but I can’t get anything else loaded… probably because in DeepSleep mode the COM port is also disabled.

In the serial monitor I see the output according to the example code. The last output is “Going to sleep now” and then I lose the connection. Every time I get connected to the Serial Monitor the same thing happens. This makes sense so far.

Loading a new program is not possible now. Either the COM port is not found right now, because my Windows does not recognize any device on the COM port. Or there are always other error messages that somehow say that the device is not reachable or the connection was aborted.

My next try was to put the C3 into bootloader mode to load the program then. But that does not work either. The connection between C3 and PC is stable for now. So Windows doesn’t keep reporting that a new device has been detected. COM3 also has a connection all the time. But when uploading a write timeout error occurs.

esptool.py v4.5
Serial port COM3
Connecting...

A serial exception error occurred: Write timeout
Note: This error originates from pySerial. It is likely not a problem with esptool, but with the hardware connection or drivers.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html

Also with the EspRFTestTool I can’t get a connection to flash a new .bin to the controller. First the program says “open com3 sucess”. But when flashing, the write timeout error comes again.

set to com port!
Com3 is open ser0
DEBUG:open com3 sucess
DEBUG:select test bin
DEBUG:Flash
DEBUG:['C:/Users/******/Desktop/ESP32-C3_RFTest_108_2b9b157_20211014.bin']
DEBUG:Com is closed ser0
DEBUG:close com sucessfully
ESP32C3
Connecting....
ERROR:Write timeout
WARNING:Sync fail...

Does anyone have an idea how to get a new program onto my ESP32C3?

Here is the example Code:

/*
Simple Deep Sleep with Timer Wake Up
=====================================
ESP32 offers a deep sleep mode for effective power
saving as power is an important factor for IoT
applications. In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

This code displays the most basic deep sleep with
a timer to wake it up and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli <[email protected]>
*/

#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_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");

  Serial.println("Going to sleep now");
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");

  /*
  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.
  */
}

void loop(){
  //This is not going to be called
}

Deep sleep will shutdown the usb/serial/download/debug connection, it won’t reconnect. My solution was to output all serial info to serial and to serial1 and used a second pc onnection via a serial/usb bridge (<$5). Works great. Uses #define to identify which you want to output to (optionally). I’m also sending debug output to a SSD1306 OLED display. Using one or the other I can continue to debug after deep sleep returns (via timer or interrupt). Use RTC memory to store variables you need to restart, or use Flash (or both). Getting restart from deep sleep takes effort to get everything right. But I’ve cut my power consumption by 50x with 10s time intervals and HW interrupts, but I’ve not found a way to get a interrupt from I2C or SPI devices. Also trying to monitor battery power level to trigger low battery warning.

It seems like you are facing a common issue with ESP32C3 when it enters deep sleep mode. The COM port is disabled during deep sleep mode, which makes it impossible to upload a new program to the board.

One way to overcome this problem is to manually reset the board by pressing the reset button. This will force the board to exit deep sleep mode and enable the COM port again. You can then upload a new program to the board.

If your board does not have a reset button, you can try using a jumper wire to connect the RST pin to the GND pin momentarily to reset the board. This should also force the board to exit deep sleep mode.

Another way to upload a new program to the board is to use an external programmer, such as a USB to UART adapter. This requires some additional hardware and setup, but it can be a reliable way to program the board even when it is in deep sleep mode.

Finally, you can consider using the RTC memory to store data between deep sleep cycles. This way, you can avoid the need to upload a new program to the board every time it wakes up from deep sleep. The RTC memory can store up to 8 KB of data and is not affected by deep sleep mode.

Greeting,
Rachel Gomez

Would you be willing to share the code you were using? I have been having issues getting sleep mode to work for my solution, and can’t seem to find a lot of great examples that actually describe the situation that I’m looking for.

I don’t have time to change source to an “example”. Send me an eMail to: [email protected] and I’ll get you what I had, you can then pull out what’s you need (out of ~3000 lines).

1 Like

Or you can try to reflash the bootloader with factory firmware(Q3).