Pages: 1 [2]   Go Down
Author Topic: Serial.available()  (Read 2085 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19035
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You wouldn't be here. It's freezing.

Where I am it is 10 pm, 28 C (82 F). It's hot, man!
Logged


Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 308
Posts: 26472
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Think of Serial.available as a little guy who sits in your letter box, who tells how many letters there are in the box when you ask him.
If you take a letter out of the box (Serial.read) there's one fewer letter in the box, so next you ask Serial.available, he reports one fewer than last time you asked.
If you decide that you're only going to take out letters when there are three or more letters in the box.
You ask Serial.available, and he says "three".
So, you take one letter.
Then you ask again, and he says "two", so you don't take any letters.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50111
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If you decide that you're only going to take out letters when there are three or more letters in the box.
You ask Serial.available, and he says "three".
So, you take one letter.
Then you ask again, and he says "two", so you don't take any letters.
So, the trick here is when the little guy says that there are three letters, you need to take three.

Keep in mind that you still have not answered the question about what option you have chosen for the Serial Monitor, so if you type three characters and hit enter, there may be 3, 4, or 5 characters actually sent to the Arduino.

But, the idea that, because there are three or more characters to read, the characters represent a packet, and nothing but a packet is flawed. Serial data is not guaranteed to be delivered. A byte could have gotten corrupted for any number of reasons.

What you should be doing is having the Serial Monitor append something to the string you send. Then, you read and store each character that is available, followed by a NULL, unless that character is one that was added by the Serial Monitor. If it is, then the stored data is of interest, so you use it, and reset the index that defines where in the array you are storing data, along with NULLing the first element off the array.
Logged

Casorezzo, Milan, Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Keep in mind that you still have not answered the question about what option you have chosen for the Serial Monitor, so if you type three characters and hit enter, there may be 3, 4, or 5 characters actually sent to the Arduino.

after uploading the program on Arduino, I open the serial monitor, digit characters inside the communication field, and hit enter. That's it.

Referring to the following code:
Code:
int input;

void setup(){
  Serial.begin(9600);
}

void loop(){
  if(Serial.available()>=3){
  char input=Serial.read(); 
  Serial.println(input);
 
  Serial.println("what serial.available contains:");
  Serial.println(Serial.available());
}
 
}

 

if i enter "567", the Serial.print function returns "5"; that because, characters are sent to Arduino one by one, so when the first digit is sent, the if statement goes like that: "the first char enter the Arduino buffer. Now the Arduino buffer contains >= 3 elements? = NO! and so on, until i enter"7".
Now Arduino buffer contains 3 or more elements so 'if loop' is triggered, and Serial.read reads the first element stored in the buffer, that is "5"! Printing the element (Serial.available) left in the buffer, the answer is "2", and that is trivial...
But going on in the same serial monitor, typing other three char, for example "890": this is the signal returned:

Code:
6
what serial.available contains:
2
7
what serial.available contains:
3
8
what serial.available contains:
2

why after "7" character has been read, there are 3 elements left in Arduino buffer!?
 
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50111
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I asked a very simple question. What option have you selected at the bottom of the Serial Monitor dialog? I'm not going to participate in this discussion any more until you answer that question.
Logged

Casorezzo, Milan, Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I asked a very simple question. What option have you selected at the bottom of the Serial Monitor dialog? I'm not going to participate in this discussion any more until you answer that question.

At the bottom of the serial monitor there are:
-Autoscroll (flagged)
-No line ending
-9600 baud rate
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50111
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
-No line ending
You should change this to one of the other options. The others act like periods at the end of sentences, or spaces after words, to tell you where a stream of data breaks in meaningful ways.

Quote
if i enter "567", the Serial.print function returns "5";
Yes, and no. The Serial.print() function returns 1, because it printed one character. The character read was a '5', because there were 3 characters to read.

Quote
characters are sent to Arduino one by one, so when the first digit is sent, the if statement goes like that: "the first char enter the Arduino buffer. Now the Arduino buffer contains >= 3 elements? = NO! and so on, until i enter"7".
Again, yes and no. The characters are sent one by one. The test does evaluate to false because the characters arrive one by one, and for several thousands of iterations of loop, the '5' has arrived, but the '6' and '7' have not.

Only when the '6' and '7' arrive does the test evaluate to true.

But, while you are entering the characters one by one, the Serial Monitor sends them only when you hit the enter key/send icon.

Quote
Now Arduino buffer contains 3 or more elements so 'if loop' is triggered, and Serial.read reads the first element stored in the buffer, that is "5"! Printing the element (Serial.available) left in the buffer, the answer is "2", and that is trivial...
Yes. You are printing the number of elements left in the buffer, though, not the elements left in the buffer.

You really should get in the habit of identifying EVERYTHING printed to the serial port.

Code:
if(Serial.available() >= 3)
{
   char c = Serial.read();
   Serial.print("I read a [");
   Serial.print(c);
   Serial.println("]");

   Serial.print("The buffer still contains ");
   Serial.print(Serial.available());
   Serial.println(" characters");
}
Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9671
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You should change this to one of the other options.

Why, so adding non printable characters can add to the confusion?
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19035
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

With no line ending, the receiving end won't know after getting "567" if it should wait for "5678".

Confusing maybe, but even more confusing without it.
Logged


Casorezzo, Milan, Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

At the end:
data does not occupy the serial buffer on Arduino, until I hit "enter".
and the function that extracts data from the buffer is the Serial.read function. And when i call it, one digit (or character, depending on the variables initialization), comes out from the buffer and the "available elements" in the buffer decrease by one unit?

 
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50111
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
At the end:
data does not occupy the serial buffer on Arduino, until I hit "enter".
and the function that extracts data from the buffer is the Serial.read function. And when i call it, one digit (or character, depending on the variables initialization), comes out from the buffer and the "available elements" in the buffer decrease by one unit?
All true.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 495
Posts: 19035
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

data does not occupy the serial buffer on Arduino, until I hit "enter".

And when you hit <enter> the data does not instantly go into the serial buffer. So if you type "12345" you won't find the number of available bytes instantly increase from 0 to 5, it will increase slowly at the baud rate. So at 9600 baud the characters will appear at roughly 1/960 of a second apart (about one every millisecond).
Logged


0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9671
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
With no line ending, the receiving end won't know after getting "567" if it should wait for "5678".
Confusing maybe, but even more confusing without it.

That has nothing to do with the " if(Serial.available()>=3){ " issue of how many bytes are in the serial receive buffer being discussed. The person with the issue will now also have to evaluate line feeds and such if the code prints the captured string back to the serial monitor for trouble shooting.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 631
Posts: 50111
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
That has nothing to do with the " if(Serial.available()>=3){ " issue of how many bytes are in the serial receive buffer being discussed. The person with the issue will now also have to evaluate line feeds and such if the code prints the captured string back to the serial monitor for trouble shooting.
No, but OP doesn't have to care about the number of bytes to be read. Read and store anything in the buffer, unless it is the character added by the Serial Monitor. If it is a character added by the Serial Monitor, it indicates the end of a packet, and the stored packet can now be printed, converted to an int, parsed, etc. - whatever is appropriate for the data that was sent. And, no delay()s are needed.
Logged

Pages: 1 [2]   Go Up
Jump to: