espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.41k stars 7.37k forks source link

ESP32S3 Serial Port Available Fails When Device Powered Externally #9677

Closed Xylopyrographer closed 4 months ago

Xylopyrographer commented 4 months ago

Board

seed studio XIAO S3

Device Description

None.

Hardware Configuration

None. Test sketch uses the built-in LED.

Version

other

IDE Name

Arduino IDE v2.3.2

Operating System

macOS 14.4.1 (Sonoma)

Flash frequency

240 MHz

PSRAM enabled

no

Upload speed

921600

Description

Cannot test for availability of the Serial port unless the serial port is connected and active. Trying to do so hangs the program.

Result is the device cannot be powered up by an external supply connected to the USB port.

Load the sketch below. When connected to the serial port of the computer, the sketch executes (LED blips). Leave the device connected to the computer. Close the serial port. Reset the board, sketch hangs (LED doesn't blip). Now connect the serial port and the sketch will run.

Disconnect the board from the computer, Connect the USB port of the board to an external 5V supply. Sketch hangs (LED does not blip.) There is no way to make the sketch run.

Replace the while clause in the sketch with a hard coded delay (750 ms seems to be the minimum required) and the sketch will work (LED blips) under all the conditions stated above.

As noted in the sketch, various uses of Serial.setTxTimeoutMs( 0 ); does not change the result.

While the sketch prints a number of lines, printing just one line is sufficient to produce the error.

Sketch

#define LEDBI 21                // GPIO# for the built-in LED
#define HB_BLIP_TIME 2000       // # of ms between LED blips

void setup() {

    pinMode( LEDBI, OUTPUT );           // set up the built-in LED
    digitalWrite( LEDBI, LOW );         // for the XIAO S3, LOW = LED on

    // Serial.setTxTimeoutMs( 0 );      // placing this line before or after Serial.begin doesn't change the result
    Serial.begin( 115200 );
    while ( !Serial ) {                 /* this clause hangs the program until a serial port connection is made  */
        delay( 50 );
    }     
    // delay( 750 );                    // replace the above 'while' clause with this line and the program works

    Serial.println( "1. Lorem ipsum dolor sit amet, ei doctus invenire iracundia eum," );
    Serial.println( "2. cum ex ignota posidonium. At mea solet corpora. Mei ad lorem voluptatibus.");
    Serial.println( "3. Omnes voluptua te nec, at mei phaedrum quaestio.");
    Serial.println( "4. Vis in legendos definiebas, mei ei partem nusquam probatus,");
    Serial.println( "5 .pro diam vide ne. Habemus accumsan nec an.");
    Serial.println( "6. Debet ubique ridens duo ad, sed populo expetendis ex. Id vel omnis eligendi,");
    Serial.println( "7. ne est persius scribentur, quo an fastidii sadipscing.");
    Serial.println( "8. Te justo mandamus molestiae has, pri ex fugit commodo electram.");
    Serial.println( "9. Duo facilis appetere mediocritatem et. Sea consetetur definiebas et,");
    Serial.println( "10. sea principes repudiandae eu. Ex vis nulla eirmod labores,");
    Serial.println( "11. cu eos aperiam scaevola gubergren. Diam minimum ne mea.");
    Serial.println( "12. In has dicunt debitis. Sapientem salutatus cu sit, quaeque sapientem accommodare ea vis.");
    Serial.println( "13. Sea eius sadipscing eu. Pri eu aperiam principes.");
    Serial.println( "14. Id his labitur scriptorem, et nostrum percipitur eum." );
    // Serial.flush();         // the presence or abscence of this line does not change the result

}

void loop() {
    /*  - blips the built-in LED on the board
        - #define LEDBI ( GPIO pin connected to the LED ) outside this routine
        - #define HB_BLIP_TIME (# of ms between blips) outside this routine
        - the blip is 100 ms long, hard coded into this routine
        - routine assumes the LED is 'on' the first time this routine is called,
    */
    static bool blipState = 1;
    static unsigned long hbTime = millis();     // # of ms between blips on the LED

    if ( millis() >= hbTime ) {
        digitalWrite( LEDBI, blipState );
        blipState = !blipState;
        hbTime = millis() + ( blipState ? 100 : HB_BLIP_TIME );
    }
}

Debug Message

No debug output is produced.

Other Steps to Reproduce

Tested using Arduino-esp32 core v2.0.17 Tested with Arduino-esp32 core v2.0.14 as well, same problem.

Replacing the !Serial test above with a delay() works.

Arduino IDE setup:

USB CDC On Boot: "Enabled" CPU Frequency: "240MHz (WiFi)" Core Debug Level: "Verbose" USB DFU On Boot: "Disabled" Erase All Flash Before Sketch Upload: "Disabled" Events Run On: "Core 1" Flash Mode: "QIO 80MHz" Flash Size: "8MB (64Mb)" JTAG Adapter: "Disabled" Arduino Runs On: "Core 1" USB Firmware MSC On Boot: "Disabled" Partition Scheme: "Default with spiffs (3MB APP/1.5MB SPIFFS)" PSRAM: "Disabled" Upload Mode: "UARTO / Hardware CDC" Upload Speed: "921600" USB Mode: "Hardware CDC and JTAG" Programmer: "Esptool"

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

me-no-dev commented 4 months ago

and what is the issue here? (!Serial) will fail until you connect the port, if you want not to wait, just remove the while. It is working exactly as expected or am I missing something here?

JAndrassy commented 4 months ago

@Xylopyrographer https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/

Xylopyrographer commented 4 months ago

Issue is differing implementations of a function across the ESP32 variants. When S3 support was first added, the workaround was to add Serial.setTxTimeoutMs( 0 ); to prevent the S3 hanging. In revising an S3 code base that used an earlier version of the core, the issue came up again.

In trying to follow the bouncing ball of documentation across core releases I guess I missed the official position from Arduino (thanks for the link @JAndrassy).

With the behaviour now documented by Arduino, I'll code around the issue.

me-no-dev commented 4 months ago

we were not able to have this working properly before, but now it works correctly (and as documented)

Xylopyrographer commented 4 months ago

Documentation is good. 😉

FWIW, over in issue, https://github.com/espressif/arduino-esp32/issues/8796#issuecomment-2131305195 the same (now defunct) workaround is being used:

void setup() {
  Serial.begin(115200);
#if ARDUINO_USB_CDC_ON_BOOT
  Serial.setTxTimeoutMs(0);
#else
  while (!Serial)
    yield();
#endif
  delay(100);
.
.
.