arduino / arduino/ArduinoCore-avr
USB Serial on 32U4 stops incrementing Serial.available() if serial buffer has ≥2 bytes in it and more are received
- Dominant language
- C
- Stars
- 1.5k
- Forks
- 1.1k
- PR merge metrics
- No merged PRs in 30d
Description
After some investigation, I was able to narrow down my code to the minimum that reproduces the bug, then I added some code that helps me locate where it is. The problem appears to be that if more than one byte is sent, Serial.available() does not increment.
I did testing on a 32U4 where I could reproduce this bug, but I could not get this bug to show up on Uno with 9600, 115200, or 2,000,000 baud, so I think it only affects USB serial.
To reproduce the bug, make sure that Serial.available returns more than 1, then send data. It will remain at the previous value despite the data being in the buffer. If no bytes or one byte are in buffer, Serial.avaible works correctly upon sending data.
Here's my example code, which shows the changes in Serial.avaiable() and prints from the serial buffer even if Serial.available() is stuck:
```// Works perfectly on Uno (tested at 9,600, 115,200, and 2,000,000 baud). Doesnt work on Leonardo if two characters are sent.
void setup() {
Serial.begin(0); //No baudrate for USB serial
}
void loop() {
static uint8_t prevInBuffer;
static uint32_t whatsTheIssue;
if (Serial.available() != prevInBuffer){ //Print a change in buffer, so we dont spam the monitor
Serial.print(F("Buffer changed from "));
Serial.print(prevInBuffer);
Serial.print(F(" bytes to "));
Serial.print(Serial.available());
Serial.println(F(" bytes."));
prevInBuffer = Serial.available();
}
//If a couple of characters are sent, Serial.available never updates, this condition is never
//satisfied unless all characters are sent together, or one character is sent while buffer is
//empty followed by the rest together.
else if (Serial.available() >= 4){
while (Serial.available()){
Serial.print(char(Serial.read()));
}
Serial.println();
}
if (millis() - whatsTheIssue > 20000){ //is the issue with the buffer or Serial.available()?
whatsTheIssue = millis();
Serial.print(F("10 buffer characters: "));
uint8_t i = 0;
for (i=0;i<10;i++){
Serial.print(char(Serial.read()));
}
Serial.println();
}
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the supplied setup() and loop() sketch and reproduce the behavior on a Leonardo or other 32U4 board, then compare it with the Uno results described. Trace the USB Serial.available() behavior when the buffer already contains at least two bytes; done means newly received bytes are reflected without requiring a later combined send.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- arduino, c
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100