According to the reference Serial.available() should return the number of bytes in the serial buffer.
But, in reality, it behaves really strange. If you try to pass its value to integer variable or you try to check it with switch case statement, it always returns 1, no metter how many bytes are in the buffer.
Now, if you try to print that number, with Serial.print(Serial.available()); than the printout will show true length of the buffer.
Totally weird. Wasted whole afternoon on that.
Does anybody know how can one extract number of bytes in the serial input buffer.
Here is the code. All I am trying to do is to extact the number of characters in the serial buffer. Strangely, Serial.available() prints length, but it always retruns 0 or 1 to a variable.
How can I get the lenght out, not just 0 or 1:
byte bytBufferLength;
int intBufferLength;
char chrBufferLength;
char arrCharCommand[5];
void setup() {
// initialize the serial communication:
Serial.begin(9600);
Serial.println("Ard.> Ready ..."); Serial.println();
}
void loop() {
bytBufferLength = Serial.available();
intBufferLength = Serial.available();
chrBufferLength = Serial.available();
switch (Serial.available()) {
case 1:
Serial.print("DEBUG.00: bytBufferLength: "); Serial.println(bytBufferLength, DEC);
Serial.print("DEBUG.00: intBufferLength: "); Serial.println(intBufferLength, DEC);
Serial.print("DEBUG.00: arrBufferLength: "); Serial.println(chrBufferLength, DEC);
Serial.println();
Serial.print("DEBUG.01: Serial.available(): "); Serial.println(Serial.available(), DEC);
// Read the first four bytes from serial buffer:
arrCharCommand[0] = Serial.read();
arrCharCommand[1] = Serial.read();
arrCharCommand[2] = Serial.read();
arrCharCommand[3] = Serial.read();
arrCharCommand[4] = '\0';
Serial.print("DEBUG.02: Serial.available(): "); Serial.println(Serial.available(), DEC);
// Report back to Arduino IDE's Serial Monitor:
Serial.print("Ard.> arrCharCommand[5]= "); Serial.println(arrCharCommand);
// Send only four character commands at one time. Characters after
// the fourth will be flushed out of the serial buffer.
Serial.print("DEBUG.03: Serial.available(): "); Serial.println(Serial.available(), DEC);
FlushSerialInput();
Serial.print("DEBUG.04: Serial.available(): "); Serial.println(Serial.available(), DEC);
break;
case 0:
break;
default:
Serial.print("DEBUG.05: intBufferLength: "); Serial.println(intBufferLength, DEC);
Serial.print("DEBUG.06: Serial.available(): "); Serial.println(Serial.available(), DEC);
FlushSerialInput();
Serial.print("DEBUG.07: Serial.available(): "); Serial.println(Serial.available(), DEC);
Serial.println("Ard.> Command need to be four characters long."); Serial.println();
} // ... switch (intBufferLength)
} // ... loop()
/*
* FlushSerialInput() - deletes all the characters in the serial output buffer.
*
* Serial.flush() substentially changed its use in the later versions of the Arduino's
* IDE. Before, Serial.flush() was deleting all the characters in the input and output
* buffer. But, since 0022 or maybe even earlier, Serial.flush() is not deleting
* characters. It now only forces the remaining characters in the serial output buffer
* to go out of the buffer.
*/
void FlushSerialInput() {
while (Serial.available() > 0) Serial.read();
}
I agree. Hard to believe, in fact. Once the value has been returned back from the function call it is completely independent of the function call, so I can't think of any possible mechanism to produce effects like that. More likely imo there is something else going on to produce the effects you're seeing. I suggest you produce a minimal sketch to show the problem.
The program seems to be doing exactly what you told it to do.
If I type one long line of x into the serial monitor and then type return, this is the output:
Serial.available() returns the number of bytes in the serial buffer only if used inside Serial.print() or Serial.println() functions. I need to extract number of bytes in the buffer into an integer variable, to be able to use it inside the code.
if, for example, you typed in 58 'x' characters, than variable intBufferLength should return 58 not 0 or 1.
Serial.available() returns the number of bytes in the serial buffer only if used inside Serial.print() or Serial.println() functions
What do you mean by inside.
And while you're at it, what does Serial.available(), which returns the number of bytes in the input buffer, have to do with .print and .println which are (wait for it) output functions?
DROBNJAK:
If you try to pass its value to integer variable or you try to check it with switch case statement, it always returns 1, no metter how many bytes are in the buffer.
The following code works using the Arduino 1.0 IDE and a Uno R2 board.
void setup() {
Serial.begin(9600);
Serial.println("ready");
}
void loop() {
int count = Serial.available();
switch (count) {
case 0: Serial.println("0"); break;
case 1: Serial.println("1"); break;
default: Serial.println("d"); break;
}
}
if, for example, you typed in 58 'x' characters, than variable intBufferLength should return 58 not 0 or 1.
This statement is wrong as I have already demonstrated. What you clearly do not understand is that it takes time to transmit those 58 characters to the Arduino (I leave as an exercise for you to figure out how long it is) and during that time the Arduino is executing the loop() function thousands of times.
Now, as I said, you need to sit down with the output and follow your program through very carefully. If you can't figure out how the output happens then it isn't the program that's wrong, it's you.
[edit] Once you accept that you don't understand what is happening, then then you can perhaps ask more meaningful questions.
But first one produces input buffer length of 0, and second one produces input buffer length of 58.
There is nothing in your code that guarantees your statement to be true. It may be true based on how you send data to the board. 'Serial.available()' returns the "current" count of bytes in the buffer. 'intBufferLength' contains the count of bytes in the buffer as of sometime ago.
Let's see if I understood the process... I hope to be helpful to you and to me at the same time
Let's suppose you type 100 'x' characters into serial terminal, then send them all at once. Let's also suppose the baud rate is set to 9600.
Those 100 'x' take a significant (from the Arduino perspective) amount of time to flow from the PC, through the serial line, into the Arduino serial buffer.
While the bytes accumulate into that buffer, you're calling Serial.available() hundreds or thousands of times per second. Therefore each time the value it returns will likely be different from the previous call, depending on how many 'x' have arrived in the meantime.
The numbers represent how many 'x' chars the serial buffer contains.
x = the 'x' characters flowing through the serial line.
^ = Serial.available() calls happening while the serial transmission is going on
If you call serial.available() in the middle of the transmission, you'll get something like 3 or 4. If you wait long enough, instead, you'll get 7. And if no other chars are transmitted, you'll continue to get 7 until you call read() or some other bytes arrive.
I also suspect that calling Serial.available() so often while chars are received can lead to problems related to R/W simultaneous access to state variables inside the Serial class.
HTH
I hope I have written something meaningful. I also hope I got it correctly. Corrections are obviously welcome