Serial.available() returning unexpected value, Uno R3

When receiving serial data on my UNO R3, the Serial.avaialble() method returns "1" when there are more than 1 byte in the buffer. Is this a known bug?

For example, if I run this code:

    int iBytesInBuffer = 0;
    while ((iBytesInBuffer = Serial.available()) > 0) 
    {
      Serial.print( "Received " );Serial.print( iBytesInBuffer );Serial.println( " bytes." ); 
      byte myByte = 0;
      while( Serial.readBytes( (char*)&myByte, 1) == 1 )
      {
        Serial.print( "Read: " );Serial.println( myByte );
      }
    }

If I send the string "1 2 3 4 5", then the output is:

Received 1 bytes.
Read: 49
Read: 32
Read: 50
Read: 32
Read: 51
Read: 32
Read: 52
Read: 32
Read: 53

These are the correct ASCII values for "1 2 3 4 5", so you can see that I did receive all 9 bytes, but Serial.available() is showing only 1 byte in the buffer for some reason. The definition of Serial.available() Serial.available() - Arduino Reference says that the return value is the number of bytes available to read. The buffer will hold 64 bytes, so I'm expecting to see a 9 returned by available(). I'm new to Arduino, is my expectation here incorrect?

The serial buffer is filled within an interrupt service routine, so it is possible (and with baud rates high enough, probable) that although Serial.available() returns only 1 byte in the buffer, it will have more available if you do send some 20 bytes or more over the same serial interface in the meantime.

The buffer will hold 64 bytes, so I'm expecting to see a 9 returned by available(). I'm new to Arduino, is my expectation here incorrect?

As you didn't post the complete sketch it's hard to get a handle on the dynamic timing involved as to how long serial data has had to arrive, it's baud rate, etc, Vs when you are testing the buffer size. Plus you are reading a byte out of the serial buffer for every iteration of the while test thus decreasing the bytes available count by one, so I don't think you could ever see a full message length waiting to be read at any single iteration of the while loop?

The serial library has been around for a long time and had lots of added features, functions. and eyeballs looking at it.

I'm pretty sure you have not uncovered some bug, but rather just a lack of understanding the big picture and the dynamics involved.

Lefty

pylon you nailed it, thanks! I didn't realize it was interrupt driven. I changed my code to delay before checking the number of bytes available, like this:

    int iBytesInBuffer = 0;
    while (Serial.available() > 0) 
    {
      // Wait a bit for the serial buffer to fill itself
      delay( 1000 );
      iBytesInBuffer = Serial.available();
      Serial.print( "Received " );Serial.print( iBytesInBuffer );Serial.println( " bytes." ); 
      byte myByte = 0;
      while( Serial.readBytes( (char*)&myByte, 1) == 1 )
      {
        Serial.print( "Read: " );Serial.println( myByte );
      }
    }

And now my output is:

Received 9 bytes.
Read: 49
Read: 32
Read: 50
Read: 32
Read: 51
Read: 32
Read: 52
Read: 32
Read: 53

So clearly you were correct. Adding a little (a lot here...) delay to allow the buffer to fill does the trick. Thanks!

      while( Serial.readBytes( (char*)&myByte, 1) == 1 )
      {

Why are you using the array-of-bytes read method to read one byte at a time? That's what the read() method is for.

      // Wait a bit for the serial buffer to fill itself
      delay( 1000 );

I think that instead of "to fill itself" you meant "potentially overflow". This is a lousy way to handle serial data. Make the sender send some kind of end of packet marker, and read and store data as quickly as it arrives, but don't expect to be able to process the stored data until the end of packet marker arrives.

This was just a simple example to understand why Serial.available() wasn't returning what I expected, it's not final production code.

PaulS:

      // Wait a bit for the serial buffer to fill itself

delay( 1000 );



I think that instead of "to fill itself" you meant "potentially overflow". This is a lousy way to handle serial data. Make the sender send some kind of end of packet marker, and read and store data as quickly as it arrives, but don't expect to be able to process the stored data until the end of packet marker arrives.

You do have a good point... In this particular case, this will end up in an embedded system where I am sure there will never be more than a handful of bytes sent at once, and the sender will always wait for a reply before sending more. But I do see your point that in general you should read data as it arrives and not risk the serial buffer overflowing.

Thanks everyone for your replies!