Issue: Unable to upload code to ESP32-S3 (no blinking LED, no Serial Monitor output)

Hello everyone,

I’m facing an issue with my ESP32-S3 DevKit board on Linux (Ubuntu). I’m using PlatformIO in VS Code.

Setup:

  • Board: ESP32-S3-DevKitc-1
  • IDE: PlatformIO (freshly reinstalled)
  • Detected Port: /dev/ttyACM0`
  • platformio.ini :
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino

board_build.arduino.memory_type = qio_qspi
board_build.flash_mode = qio
board_build.psram_type = qio
board_upload.flash_size = 4MB
board_upload.maximum_size = 4194304
board_build.partitions = default.csv
board_build.extra_flags = 
  -DBOARD_HAS_PSRAM
monitor_speed = 115200
upload_speed = 460800

#Symptoms:

  • The port /dev/ttyACM0 is detected.
  • Upload fails with the following error:
A serial exception error occurred: device reports readiness to read but returned no data (device disconnected or multiple access on port?)
Note: This error originates from pySerial. It is likely not a problem with esptool, but with the hardware connection or drivers
  • During upload:
    • No LED blinks on the board.
    • No output on the Serial Monitor (even with a basic Serial.println("test"); in setup()).
  • Here’s the Serial Monitor output:
*  Executing task: platformio device monitor 

--- Terminal on /dev/ttyACM0 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H"

:white_check_mark: What I’ve tried:

  • Changed USB cable
  • Switched USB ports
  • Restarted VS Code and PlatformIO
  • Fully reinstalled PlatformIO
  • Pressed BOOT and EN buttons during upload
  • Uploaded using pio run --target upload → same error
  • Tried different LED_PIN values (2, 10, 38, 48) → no LED activity

=> My question:
How can I verify if my board is still working?
Could it be a configuration or driver issue, or is my ESP32-S3 possibly damaged?
Thanks in advance for any help :pray:

Which excact ESP32-S3 DevKit do you have?

The DevKit comes with 2 USB-C ports. One is connected to the ESP32 builtin native USB port, the other is connected to the ESP32’s UART port via an USB2SERIAL chip on the board. Try the latter one. Usually this is labled as “COM” or “UART” on the board.

Try a super simple “Hello World / blink” sketch:

#include <Arduino.h>

void setup() {
    Serial.begin(115200);
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    delay(1000);
    Serial.println("Hello World");
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

Show the complete build and upload output like so

*  Executing task: platformio run --target upload 

Processing esp32-s3-devkitc1-n16r8 (platform: espressif32; board: esp32-s3-devkitc1-n16r8; framework: arduino)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32-s3-devkitc1-n16r8.html
PLATFORM: Espressif 32 (54.3.20) > Espressif ESP32-S3-DevKitC-1-N16R8V (16 MB Flash Quad, 8 MB PSRAM Octal)
HARDWARE: ESP32S3 240MHz, 320KB RAM, 16MB Flash
DEBUG: Current (esp-builtin) On-board (esp-builtin) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: 
 - framework-arduinoespressif32 @ 3.2.0 
 - framework-arduinoespressif32-libs @ 5.4.0+sha.2f7dcd862a 
 - tool-esptoolpy @ 4.8.9 
 - tool-mkfatfs @ 2.0.1 
 - tool-mklittlefs @ 3.2.0 
 - tool-mkspiffs @ 2.230.0 (2.30) 
 - tool-riscv32-esp-elf-gdb @ 14.2.0+20240403 
 - tool-xtensa-esp-elf-gdb @ 14.2.0+20240403 
 - toolchain-riscv32-esp @ 14.2.0+20241119 
 - toolchain-xtensa-esp-elf @ 14.2.0+20241119
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 41 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Retrieving maximum program size .pio/build/esp32-s3-devkitc1-n16r8/firmware.elf
Checking size .pio/build/esp32-s3-devkitc1-n16r8/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]   6.4% (used 21012 bytes from 327680 bytes)
Flash: [=         ]   5.2% (used 339830 bytes from 6553600 bytes)
Configuring upload protocol...
AVAILABLE: cmsis-dap, esp-bridge, esp-builtin, esp-prog, espota, esptool, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa
CURRENT: upload_protocol = esptool
Looking for upload port...

Auto-detected: /dev/ttyACM0
Uploading .pio/build/esp32-s3-devkitc1-n16r8/firmware.bin
esptool.py v4.8.9
Serial port /dev/ttyACM0
Connecting....
Chip is ESP32-S3 (QFN56) (revision v0.2)
Features: WiFi, BLE, Embedded PSRAM 8MB (AP_3v3)
Crystal is 40MHz
MAC: 80:65:99:c8:58:1c
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 16MB
Flash will be erased from 0x00000000 to 0x00004fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x00063fff...
SHA digest in image updated
Compressed 20208 bytes to 13058...
Writing at 0x00000000... (100 %)
Wrote 20208 bytes (13058 compressed) at 0x00000000 in 0.4 seconds (effective 363.6 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 146...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (146 compressed) at 0x00008000 in 0.1 seconds (effective 383.7 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.1 seconds (effective 588.0 kbit/s)...
Hash of data verified.
Compressed 340224 bytes to 182646...
Writing at 0x00010000... (8 %)
Writing at 0x0001c63d... (16 %)
Writing at 0x00029c63... (25 %)
Writing at 0x0002f60e... (33 %)
Writing at 0x00035272... (41 %)
Writing at 0x0003aa39... (50 %)
Writing at 0x0004013f... (58 %)
Writing at 0x00045d55... (66 %)
Writing at 0x0004b673... (75 %)
Writing at 0x0005640b... (83 %)
Writing at 0x0005be05... (91 %)
Writing at 0x000620db... (100 %)
Wrote 340224 bytes (182646 compressed) at 0x00010000 in 3.0 seconds (effective 902.8 kbit/s)...
Hash of data verified.
Hard resetting via RTS pin...
================================================================================================ [SUCCESS] Took 8.86 seconds ================================================================================================

I’m using an ESP32-S3 Zero on Ubuntu via PlatformIO. During the upload process, I often get the error:
“A fatal error occurred: Could not open /dev/ttyACM1, the port doesn’t exist”,
or
“device reports readiness to read but returned no data.”
The serial port seems unstable: it appears as /dev/ttyACM0 or /dev/ttyACM1, then disappears. In the dmesg logs, I see lines like:
[19750.908393] cdc_acm 3-5:1.0: ttyACM0: USB ACM device
followed shortly by:
[19776.486840] usb 3-5: USB disconnect.
However, the board is properly detected at first, with idVendor=303a, idProduct=1001, and the product name: USB JTAG/serial debug unit. I’m using a proper USB data cable, and no other application is using the port.
I would like to understand how to stabilize the serial connection so I can flash my ESP32-S3 without these errors.

Okay, that explains a lot :wink:

The ESP32-S3-Zero doesn’t have the USB2UART chip. Therefore you must use the builtin USB (ARDUINO_USB_CDC_ON_BOOT) - See platformio.ini at the end.

After the sketch has been uploaded, the ESP32 is restarted. The internal USB of the ESP32 is also restarted. This interrupts the serial connection to the PC. This means that after restarting the ESP32, the serial connection is re-established - possibly with a different interface! After the upload, take a look at the available interfaces and use the interface displayed there.

The WS2812-LED is connected on GPIO 21 - See section Hardware description here

platformio.ini

[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino

board_build.arduino.memory_type = qio_qspi
board_build.flash_mode = qio
board_build.psram_type = qio
board_upload.flash_size = 4MB
board_upload.maximum_size = 4194304
board_build.partitions = default.csv

build_flags = 
  -DBOARD_HAS_PSRAM
  -D ARDUINO_USB_CDC_ON_BOOT=1
  -D PIN_NEOPIXEL=21
  -D LED_BUILTIN=SOC_GPIO_PIN_COUNT+PIN_NEOPIXEL
  -D RGB_BUILTIN=LED_BUILTIN

monitor_speed = 115200
upload_speed = 921600

main.cpp:

#include <Arduino.h>

void setup() {
    Serial.begin(115200);
}

void loop() {
    Serial.println("Hello World");
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
}

I’ll admit I only peek at this group when I’m mad at PlatformIO, but there’s a clear trend that this question is asked too often. @sivar2311 , you and @maxgerhardt are heroes for answering this question mutiple times a week.

It’s time to lobby for some different defaults. I understand the challenge of not wanting to thrash pins that might be controlled by user code but just maybe the Arduino equivalent of “Hello, World” should work on every chip that Espressif has released in the last five years.

I don’t know if PlatformIO should set those by default or if the library should default it or if it should go in the board files (announcer voice: it should not go in the board files) but this is clearly a hazardous nuisance that should not be the first experience for Every Single User of this combination.