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:
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();
}
}