Skip to content

Serial communication breaking at around 300 characters, regression on 2.0.10 #8522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
osomdev opened this issue Aug 14, 2023 · 6 comments · Fixed by #8559
Closed
1 task done

Serial communication breaking at around 300 characters, regression on 2.0.10 #8522

osomdev opened this issue Aug 14, 2023 · 6 comments · Fixed by #8559
Assignees
Labels
Area: Peripherals API Relates to peripheral's APIs. Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip Priority: High 🗻 Issues with high priority which needs to be solved first. Status: Needs investigation We need to do some research before taking next steps on this issue Type: Bug 🐛 All bugs Type: Regression Result of unforeseen consequences of a previous change
Milestone

Comments

@osomdev
Copy link

osomdev commented Aug 14, 2023

Board

Adafruit QT Py ESP32-C3

Device Description

Adafruit QT Py ESP32-C3 - https://www.adafruit.com/product/5405

Hardware Configuration

Nothing extra, just board.

Version

v2.0.11

IDE Name

Arduino IDE

Operating System

ubuntu 22.04

Flash frequency

80Mhz

PSRAM enabled

yes

Upload speed

921600

Description

When communicating with device over Serial with more than 256 bytes the data is truncated (most commonly round 300-350 bytes but it is not static number) despite setting buffers to 1024 bytes (setRxBufferSize, setTxBufferSize).

It was working fine in the past but stopped working after upgrade of Arduino IDE.

I've been able to narrow this down to ESP 2.0.10 version:

  • using 2.0.5 - works fine
  • using 2.0.6 - works fine
  • using 2.0.9 - works fine
  • using 2.0.10 - communication truncated
  • using 2.0.11 - communication truncated

Steps to reproduce:

  1. Create sketch which reads data from serial, setup it with bigger buffers
  2. Run sketch and feed it with 512 bytes of data
  3. Data is truncated and not received by sketch while 512 bytes should comfortably fit into 1024 bytes buffer.

Using serial monitor is sufficient to replicate this behavior.

Test string used (nothing special - just plain text):

YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

There are some similar reports (https://github.com/espressif/arduino-esp32/issues?q=is%3Aissue+is%3Aopen+setRxBufferSize+) but for versions older than 2.0.10 and other hardware.
I suspect there was new regression introduced in 2.0.10.

Video showing the unexpected behavior (pasted 512 YYY... and it was not received fully):
https://github.com/espressif/arduino-esp32/assets/5213149/e5b66c90-dff8-4acd-ac21-9830809e25c0

Sketch

void setup() {
  // tried to use 0 to force-reset buffers - did not help, leaving for reference
  // Serial.setRxBufferSize(0);
  Serial.setRxBufferSize(1024);
  // Serial.setTxBufferSize(0);
  Serial.setTxBufferSize(1024);
  //Serial.setTimeout(1);
  Serial.begin(115200);
}

#define MAX_INPUT_BUFFER_SIZE 4096

uint32_t inputBufferPos = 0;
uint8_t inputBuffer[MAX_INPUT_BUFFER_SIZE + 1];

void loop() {
  uint32_t readInLoopCount = 0;
  while (Serial.available()) {
    uint8_t readByte = Serial.read();
    inputBuffer[inputBufferPos] = readByte;
    inputBufferPos += 1;
    readInLoopCount += 1;

    if (readByte == '\n') {
      inputBuffer[inputBufferPos] = 0;
      // Serial.print((char*)inputBuffer);
      Serial.printf("GOT: %d\n", strlen((char*)inputBuffer));
      inputBufferPos = 0;
    }
    if (inputBufferPos >= MAX_INPUT_BUFFER_SIZE) {
      Serial.println("ERR INPUT TOO LONG");
      inputBufferPos = 0;
    }
  }

  if (readInLoopCount > 0) {
    Serial.printf("GOT IN LOOP: %d\n", readInLoopCount);
  }
}

Debug Message

Nothing useful, just output from my test run that I've recorded in video:

GOT: 73
GOT IN LOOP: 73
GOT: 5
GOT IN LOOP: 5
GOT: 346
GOT IN LOOP: 346
GOT: 5
GOT IN LOOP: 5
GOT: 335
GOT IN LOOP: 335
GOT IN LOOP: 353
GOT IN LOOP: 351
GOT: 709
GOT IN LOOP: 5
GOT IN LOOP: 342
GOT IN LOOP: 326
GOT: 996
GOT IN LOOP: 328
GOT: 5
GOT IN LOOP: 5

Other Steps to Reproduce

No response

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

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@osomdev osomdev added the Status: Awaiting triage Issue is waiting for triage label Aug 14, 2023
@SuGlider SuGlider self-assigned this Aug 14, 2023
@SuGlider SuGlider added Type: Regression Result of unforeseen consequences of a previous change Peripheral: UART Status: Needs investigation We need to do some research before taking next steps on this issue Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip Area: Peripherals API Relates to peripheral's APIs. and removed Status: Awaiting triage Issue is waiting for triage Peripheral: UART labels Aug 14, 2023
@SuGlider
Copy link
Collaborator

SuGlider commented Aug 14, 2023

@osomdev - Thanks for reporting.
Issue confimed. It happens with ESP32-C3 USB CDC + 2.0.10+
No issue with 2.0.9.

@SuGlider SuGlider added the Type: Bug 🐛 All bugs label Aug 14, 2023
@SuGlider
Copy link
Collaborator

@me-no-dev @VojtechBartoska - This is a regression of USB Hardware CDC in v2.0.10+
No change visible in the USBCDC.cpp of in Lib Builder arduino_tinyusb component that justifies such regression.

It can be related or to some change done in IDF 4.4.5.

@me-no-dev
Copy link
Member

@SuGlider C3 does not use tinyusb. This is about the internal HW CDC+JTAG

@me-no-dev
Copy link
Member

Calling Serial.setRxBufferSize(1024); AFTER Serial.begin(115200); helps. Buffer is still 256 bytes long after begin

@me-no-dev
Copy link
Member

To summarize:

  • Expecting large amounts of data and reading byte-by-byte is never a good option. This reads from the buffers significantly slower than eg: readStringUntil('\n') or just reading as many as there are available(). Reading slow causes the buffers to overfill and not accept more data.
  • Recent changes in the code that manages the RX/TX buffers caused any previous buffer to be freed and default 256 bytes one to be allocated. This should probably be changed, but the solution above will work until then (and in the future).

@SuGlider
Copy link
Collaborator

SuGlider commented Aug 23, 2023

@me-no-dev / @osomdev - a PR to fix it and improve the way how TX/RX buffers are set has been released. PR #8559

HWCDC::setTxBufferSize() and/or HWCDC::setRxBufferSize() can be called at any time, after or before HWCDC::begin(), even more than one time or in any order.

@github-project-automation github-project-automation bot moved this from Under investigation to Done in Arduino ESP32 Core Project Roadmap Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Peripherals API Relates to peripheral's APIs. Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip Priority: High 🗻 Issues with high priority which needs to be solved first. Status: Needs investigation We need to do some research before taking next steps on this issue Type: Bug 🐛 All bugs Type: Regression Result of unforeseen consequences of a previous change
Projects
Development

Successfully merging a pull request may close this issue.

4 participants