Unexpected Serial.available() behaviour

I'm getting some confusing results from Serial.available, and can't work out why. I've modified the example at Serial.available() - Arduino Reference to this:

int incomingByte = 0;   // for incoming serial data
void setup() {
  Serial.begin(38400);     // opens serial port, sets data rate to 9600 bps
}
void loop() {
incoming();
}
void incoming(){
   // send data only when you receive data:
   do{ 
     incomingByte = Serial.read();
     // say what you got:
     Serial.write(incomingByte);
   } while (Serial.available() > 0);
}

It seems that Serial.available() is always > 0, though I know it isn't.

I've also tried using a while(Serial.available() > 0){... loop, which similarly is never run.

Is this supposed to happen?

Why are you reading data before you know it is available?

AWOL:
Why are you reading data before you know it is available?

I'm not sure I understand the question.

I don't see the functional difference between the example given, and what I have tried to do.

You call Serial.read before you check Serial.available.

It seems that Serial.available() is always > 0, though I know it isn't.

I don't see any evidence for this assertion.

I don't see the functional difference between the example given , and what I have tried to do. ,

Does "should've gone to SpecSavers" mean anything to you?

AWOL:
You call Serial.read before you check Serial.available.

It's ugly, perhaps, but I don't understand why that would be a problem; I don't need to check Serial.available to Serial.read. (or do I?). I only want to exit the loop when there is no Serial.available.

Do you understand how a do..while works, and how the "loop()" function works?

AWOL:
Do you understand how a do..while works, and how the "loop()" function works?

I think so. And I hope so. But what's confusing me is the way Serial.available() works.

AWOL:
Does "should've gone to SpecSavers" mean anything to you?

O would some power the giftie gie us to see ourselves as others see us.

The problem might be your baudrate

Serial.begin(38400);

make sure that in the code given rate and at your serial monitor is the same rate. If you don't pay attention to this important issue you may have some "strange signs".

loop gets called.
It calls incoming.
incoming calls Serial.read; whatever is read is printed (if nothing was there to read, Serial.read returns -1)
Call Serial.available.
Assume it returns zero.
do..while loop exits, incoming returns.
loop returns, gets called again, calls incoming.

See where this is going?

Uptown:
The problem might be your baudrate

Serial.begin(38400);

make sure that in the code given rate and at your serial monitor is the same rate. If you don't pay attention to this important issue you may have some "strange signs".

Thanks, Uptown. I've been using this baud rate no probs, and getting data through the serial port in both directions. But now I wanted to try to direct the remaining bytes, based on the first byte in a number of bytes. It's the Serial.stuff that's really making it difficult.

It's the Serial.stuff that's really making it difficult.

I think it is your misunderstanding that's making things difficult.

It is mostly very robust and straightforward.

AWOL:
loop gets called.
It calls incoming.
incoming calls Serial.read; whatever is read is printed (if nothing was there to read, Serial.read returns -1)
Call Serial.available.
Assume it returns zero.
do..while loop exits, incoming returns.
loop returns, gets called again, calls incoming.

See where this is going?

Let's make it simpler.

As far as I know... and I am happy to be wrong about it... 'incoming' and Serial.read have nothing to do with the flow of the programme:

loop gets called.
Call Serial.available.
Assume it returns zero.
do..while loop exits

Why would the loop get called again, if Serial.read returned -1?

I didn't write "the loop", I wrote "loop", meaning the function "loop()".

Just follow the code through, you'll see what is going on.

AWOL:

It's the Serial.stuff that's really making it difficult.

I think it is your misunderstanding that's making things difficult.

It is mostly very robust and straightforward.

Yes, it's my misunderstanding which has led to me both to this problem, and perhaps also the view that I could ask for some guidance to help me through my misunderstanding.

Why would the loop get called again, if Serial.read returned -1?

There is nothing in your code that is conditional upon the return value of Serial.read, so I can't see why you ask.

It is really hard to guide you through this because it is difficult to see how you have arrived at your conclusion.

AWOL:
I didn't write "the loop", I wrote "loop", meaning the function "loop()".

Good point. Thank you. My mistake. I was trying to isolate the problem I'm having, and in doing so simply created a different problem.

This is a better attempt to explain my problem.

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

void loop() {
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    if (inByte == 36) {
      // "$" - then get what processing has
      listening();
    }
  }
}

void listening() {
  int incomingByte;
  while(Serial.available() >0) {
   incomingByte = Serial.read();
    Serial.write(incomingByte);
  }
}

I am wondering if the second attempt to read Serial.available returns negative because it may be cleared somehow, after the first reading.

I am wondering if the second attempt to read Serial.available returns negative

Serial.available returns either zero or a positive value.
I'd be very worried if it returned a negative value.

AWOL:

Why would the loop get called again, if Serial.read returned -1?

There is nothing in your code that is conditional upon the return value of Serial.read, so I can't see why you ask.

My understanding was that the following section was conditional on Serial.read...

do{
incomingByte = Serial.read();
// say what you got:
Serial.write(incomingByte);
} while (Serial.available() > 0);

... it still is.

And why I asked is because I was confused, as we have established. I hope that clears up any confusion.

AWOL:

I am wondering if the second attempt to read Serial.available returns negative

Serial.available returns either zero or a positive value.
I'd be very worried if it returned a negative value.

Negative as in 'not a positive result'.

I'm grateful for the help, I really am. But surely you knew what I meant. It's obvious that I'm testing for > 0, and that the test is positive or negative -- i.e. true or false -- even if the only possible values for Serial.available() are in the range 0+.

Do you have any advice about why the second attempt to find serial.available() seems to say 0, when there are still bytes available?

My understanding was that the following section was conditional on Serial.read...

Only in the sense that calling Serial.read will cause Serial.available to return one less than if you hadn't called Serial.read.

Serial.available returns the number of characters in the receive buffer, so either zero or a positive number.
Serial.read will return the oldest character in the receive buffer if there is data in the buffer, or -1 if there is nothing in the receive buffer.

I'm sorry but I can't see what your problem is.

AWOL:
I'm sorry but I can't see what your problem is.

I've explained the problem. The possibilities are (in decreasing order of likelihood)...

  1. My programming abilities are insufficient.
  2. I've not understood the way the Serial.available() works.
  3. My Arduino Uno is malfunctioning.
  4. There is a problem with the Serial.available() function.

The disparity between my expectations and my programme's output persists, notwithstanding your assertion that everything is just fine. One of the above possibilities explains it. 1 & 2 being the most likely, hence I ask for advice. I'm not sure how advice in the tone of 'should have gone to Specsavers' is supposed to help, but I can promise you it doesn't seem to me to have helped. Maybe we don't understand each other's problems.

Mine are technical.