Description
Related area
Board Support
Hardware specification
Support for ESP32C3
Is your feature request related to a problem?
https://github.com/espressif/arduino-esp32/issues/6089
Describe the solution you'd like
It needs a function to clear the TX Buffer or anything in there will be printed when port is opened, It would seem that data should be held and printed when the port is opened, but that's actually a significant problem as the sketch below demonstrates.
Describe alternatives you've considered
I tried toggling the setTxBufferSize() but it only slightly helps. I tried many others that didn't help at all and mostly only created more problems. As a temporary solution, I added the waitForCDC variable to mask the issue, but it's designed so that the board will only run if the port is open when the variable is set to true.
Additional context
The following sketch demonstrates why this function is necessary. The USBSerial example in the IDE is absolutely wrong for the ESP32C3. I fixed it, along with fixing many other issues I've seen people post about or personally experienced. If you run this proposed example sketch, leave the port closed for at least 15 seconds and then open it. The longer it's closed, the more noticeable the need for a clearTxBuffer() function is. It will print the bootloader start message and the first 13 counts, then start printing what it's supposed to print.
#if !ARDUINO_USB_CDC_ON_BOOT
#error USB CDC Ob Boot must be enabled to use this sketch
#endif
volatile bool usbActive; // when port is open, this is true. When closed, it's false.
bool waitForCDC = false; /* device resets every time port is CLOSED. This waits for
port to be open before running. */
unsigned long timer; // for non-blocking delay
unsigned long secondsActive = 0; // counts how many seconds since last start
static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
arduino_hw_cdc_event_data_t * data = (arduino_hw_cdc_event_data_t*)event_data;
switch (event_id){
case ARDUINO_HW_CDC_CONNECTED_EVENT:
// ***** clearTxBuffer() should go here *****
Serial.println("\nCDC CONNECTED\n");
usbActive = true;
break;
case ARDUINO_HW_CDC_BUS_RESET_EVENT:
Serial.println("CDC BUS RESET");
break;
case ARDUINO_HW_CDC_RX_EVENT:
Serial.printf("CDC RX EVENT [%u]: ", data->rx.len);
{
uint8_t buf[data->rx.len];
size_t len = Serial.read(buf, data->rx.len);
Serial.write(buf, len);
}
Serial.println();
break;
case ARDUINO_HW_CDC_TX_EVENT:
// No example provided
break;
case ARDUINO_HW_CDC_MAX_EVENT:
// No example provided
break;
default:
break;
}
}
void setup() {
Serial.setTxBufferSize(256); // already the default, but setting for example purposes
Serial.setRxBufferSize(256); // already the default, but setting for example purposes
Serial.onEvent(usbEventCallback); // monitors port for status changes
Serial.begin(); // start the CDC port
if(waitForCDC){ // stays here until port open if waitForCDC == true
if(usbActive == false){
while(usbActive == false){} // wait here on start until CDC port is opened
delay(1000);
}
}
timer = millis() + 1000; // set timer to 1 second from now
}
void loop() {
if(usbActive){
Serial.setTxTimeoutMs(100); // recommended value when port is open.
} else {
//The following is ABSOLUTELY NECESSARY when the port is closed!
//Otherwise, Serial writes will hang and sketch may not run properly.
Serial.setTxTimeoutMs(0); // NECESSARY value when port is closed.
}
if(millis() > timer){ // if 1 second has passed
secondsActive++; // increment seconds count
Serial.print("Seconds Active: "); Serial.println(secondsActive);
timer = millis() + 1000; // reset timer to 1 second from now
}
}