Lolin_s2_mini ESP.restart() Exception disconnects USB port

I have started working with the Wemos Lolin S2 Mini board and I am having trouble getting it to work properly.
As an example, a simple blinking led program. After the 3th flash I want it to restart. But then it crashes:

#include <Arduino.h>

bool ledLight;
byte n;
uint32_t millisBak;

void setup()
{
  pinMode(15, OUTPUT);
  Serial.println("HELLO WORLD");
  ledLight = true;
  n = 0;
  millisBak = 0;
}

void loop()
{
  if (millis() - millisBak > 1000)
  {
    Serial.print("*");
    digitalWrite(15, ledLight);
    ledLight = !ledLight;
    n++;
    millisBak = millis();
  }

  if (n > 5)
  {
    Serial.println("RESTART");
    ESP.restart();
  }
}

platformio.ini:

[env:lolin_s2_mini]
platform = espressif32
board = lolin_s2_mini
framework = arduino

Output screen:

> Executing task: C:\Users\<user>\.platformio\penv\Scripts\platformio.exe device monitor <

--- 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
--- Miniterm on COM16  9600,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
*****RESTART
Exception in thread rx:
Traceback (most recent call last):
  File "C:\Users\<user>\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Users\<user>\AppData\Local\Programs\Python\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\<user>\.platformio\penv\lib\site-packages\serial\tools\miniterm.py", line 499, in reader
    data = self.serial.read(self.serial.in_waiting or 1)
  File "C:\Users\<user>\.platformio\penv\lib\site-packages\serial\serialwin32.py", line 259, in in_waiting
    raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))

This exception is exactly the same as when I just unplug the device from the USB port during program execution.

Despite the exception, the device continues executing the program in the continuous loop of 3 flashes and a reboot. But it seems that when ESP.restart() is executed, it disconnects from the USB port and then reconnects, so in order to continue seeing the output, I have to restart the terminal.

I can’t figure out why it’s failing or what I’m doing wrong. Could you help me please?

Since the ESP32S2 chip implements the USB connection itself (it has the USB peripheral), when it restarts, it temporarily loses its USB connection and then reconnects. This is expected behavior. The same goes for other microcontrollers implementing USB themselves, such as Atmel ATSAMD21 chips.

Other microcontroller boards don’t do this if they have a dedicated USB-serial chip (e.g., CH340, CP2102, …) on them that is not affected by the restart of the main microcontroller, and thus don’t have this problem.

I’m not sure whether anything can be done against that at all – The USB disconnect is pretty much bound to happen when you ESP.restart(). I guess PlatformIO could have an option where it tries to reconnect to the lost device for a while. You can file that as a feature request in Issues · platformio/platformio-core · GitHub.

@maxgerhardt Thank you very much for your good explanation.
Looking around for an answer to this issue, I have come across the USB CDC (flag ARDUINO_USB_CDC_ON_BOOT). Is it related to this matter?

ARDUINO_USB_CDC_ON_BOOT is just the configuration flag for Arduino-ESP32 to start the USB CDC (aka, USB serial device) as soon as the ESP32 “boots”, which is, reaches the Arduino’s app_main function by which quite a bit of time has passed already. It’s not related to the “loosing USB conenction on chip reset” behavior, it just automatically starts the USB connection after the boot.

@maxgerhardt again thank you very much for your clarifications.
Following your suggestion, I’m going to make a feature request to platformio
-core

Do you know if anybody has implemented this functionality in ESP-IDF? Is there a flag we can set?