ESP32 delay required after Serial.begin

I'm still using Arduino IDE 1.8.9
and the esp32 Boards extension (by espressif Version 3.3.0)
with an ESP WROOM 32 module.

A small test sketch with nothing but void setup() and some Serial output does not work, unless I add some delay between Serial.begin and the first Serial output.

This test

void setup() {
  Serial.begin(115200);
  for (int i = 0;i < 10; i++) {
    delay(50);
    Serial.println(i);
  }
  Serial.println("---");  
}
void loop() { delay(10);}

shows that in my case a delay of more than 300 ms is required, because after an upload the output in an already open Serial Monitor starts with

7
8
9
---

Pressing the button labelled EN on my ESP, shows

ets Jul 29 2019 12:21:46

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:1
load:0x3fff0030,len:4980
load:0x40078000,len:16612
load:0x40080400,len:3480
entry 0x400805b4
0
1
2
3
4
5
6
7
8
9
---

so the
"Hard resetting via RTS pin..." at the end of an upload
does something different ?

Can someone give me some background hints for this observation, please?

The processor is doing stuff (including with the Serial port) right after start up. You only need the delay() once, right after Serial.begin(). I typically use 1000ms just to be on the safe side. I do the same thing for boards whose ``Serial``` port is native USB. In fact, for portability, I do it with code for all boards.

void setup() {
  Serial.begin(115200);
  delay(1000);
  for (int i = 0; i < 10; i++) {

    Serial.println(i);
  }
  Serial.println("---");
}

Thanks, @gfvalvo

Sure, my code was just to measure :wink: the required period somehow.

BTW: As you mention "native USB", it's interesting to me that

  Serial.begin(115200);
  while (!Serial) delay(10);  // waiting for native USB Serial to become alive
  delay (500); // You still have to wait a while on an ESP32 ...

To be clear, it's, not a problem, but just curiosity, how the multihreading OS of an ESP, or whatever (?) causes this behavior.

ESP32 WROO32 doesn't have native USB, its Serial is a regular UART. So the while() loop terminates immediately and you still need to wait for the OS, etc to finish doing its thing.

1 Like

This is more like a delay in switching between the upload, which happened through an external program, and restoring the connection to the Monitor. As you noted, pressing the reset button displays the ROM startup (starting with ets and the ROM date -- which always happens at 115200) and all your output (at the specified baud rate). So the ESP32 is not "too busy".

It is annoying when trying to test a one-off during development, but "in production" it usually does not matter. Often, you can just press the reset button if you want to see everything from the beginning. And/or have output at regular intervals from whatever is happening through the loop

It also may not matter if you have a hard-coded one-second delay at startup, but those seconds do accumulate. More egregious are some Arduino examples that have a ten-second delay for the WiFi to connect. But on some boards, the WiFi.begin call is blocking, so you are always waiting ten seconds after it connects for nothing.

The USB to TTL bridge (typically a Ch340) doesn't get reset by this so called 'hard-reset' and i actually suspect it is still running at the upload-baud rate. You could confirm this by setting the upload baud-rate and the sketch baud-rate to the same.

Thanks, @kenb4.
Yes, during upload the Serial Monitor's connection is in a passive state and obviously becomes active some time later.

That is only due, to the Serial monitor not being able to access the port at the same time as the esptool. Pretty sure that is not the cause.

Setting the upload speed to 115200 just slows down the upload.
The reboot messages as visible e.g. in a wokwi simulation, or after pressing the reset button, and other messages during the first ~400 ms are still invisible.

The baudr-rate could also be adjusted in the Serial.begin() and the monitor.

What to do. It must have something to do with the ESPtool not releasing the port on time in that case.

The USB COM port has to be released by the uploading ESPtool and can then be opened by the SerialMonitor again. That's how I understand @kenb4's response #5.

So, for quick tests where everything happens in setup() and is intended to run just once after an upload, I simply add the delay(400);
BTW: this delay can run before Serial.begin as well.

For real sketches where a quick start after reset is interesting, I know to see the full story only after using the RESET button.

Thanks for the discussion to all.