Issue with Serial.available

I have a strange problem with the Serial.avialable() call.

I am using an arduino Leonardo to control a motorized lens focusing system.
I have a custom application running on a PC, that sends data to the Arduino over internal virtual serial port on the USB. The data is typically about 50 bytes long and new data is created about 5 times per second.
I am running at a baud rate of 38400.

To initiate a data transfer I write an "" to the serial port and then I want to wait until data is available.
On receiving the "
", the application will transmit data as soon as it becomes available.
so the code is simply

Serial.write("*"); 
   delay (25);
 while ( Serial.available()==0){
}

But It never comes out of the while loop, even though I know data has become available.

Conversely, if I do this.

Serial.write("*"); 
   delay (25);
 while ( Serial.available()>0){
char inbyte = Serial.read();
}

Then this works.

I have tried a "do while" loop where I continually read the Serial.available and assign it to a variable.

do {
bytes_available = Serial.available();
} while (bytes_available ==0);

But this also simply hangs and never comes out of the loop.
I realize that there are other ways to hold off until data is sent, but the simple while loop seemed to be the most efficient.

It just seems strange that a test for a null value does not work whereas a test for a value >0 does.
Any suggestions are most appreciated.

Please post ALL the code, always.

However, in this case, you could take a moment to read the Arduino Reference Guide regarding Serial.available().

If you do, you will learn that the function returns -1 if nothing is available, to distinguish from returning a character with value = 0.

Note that constructions like "A" form a two byte character string (C-string). Use 'A' for a single character.

Does Serial.available() really do that or do you mean Serial.read() ?

Oops, sorry, I was indeed thinking of Serial.read(). My mistake.

The problem may have more to do with this:

Serial.write("*"); 

try to add a single Serial.read() before do-while loop:

if (Serial.available() == 0) Serial.read();
do {
bytes_available = Serial.available();
} while (bytes_available ==0);

So you received something... Why don't you print out what you received... it might give you more of a clue what is happening.

Also - Can you post your full sketch.

If I actually print serial.available(), it shows 0
I believe serial.peek will return -1 if there are no bytes to read.
Either way, the loop should not hang if I am testing for serial.available() == 0

Hi
This is thefull code for my getData() function
When I do get data IHave to read it in and parse it out byte by byte, and that works fine, so the data is coming in just as expected,
I just wanted to hold off doing the parsing until I had new data, which is why I had the
simple while (serial.avialble==0) loop.

Serial.availble() should return 0 if there is no data (and so it does ), I also tried serial.peek(), which returns -1 if there is no data, but still it hangs.
In the code below I have used a flag new_data, to indicate that I am processing new data (rather than the last set) but I just don't understand why the simpler option does not work,

void GetData(int Data1[]) 
{ 
  
  bool displayDebug=0;
  int data_length=0;
  int index=0;
  int sign=1;
  int number=0;
  int accumulator=0;
  
  new_data= 0;
  
 Serial.write("*"); 
   delay (25);

  
 while ( Serial.available()>0){
      new_data= 1;                                        // 
    char inbyte = Serial.read();
    
 
    if (isDigit(inbyte) &&  index == 0) {   // This is the first digit of this data element
      index = inbyte -'0'; // sets the data index to the number 
      inbyte = Serial.read();  // index is set , so read next byte
    } 
    if (inbyte == 'x') { 
      index= 10;
      inbyte = Serial.read();  // index is set , so read next byte
    }
    if (inbyte == 'y') { 
      index= 11;
      inbyte = Serial.read();  // index is set , so read next byte
    }
    if (inbyte == '-') { /// this menas we have come to the end of the data element
       sign = -1;
       inbyte = Serial.read();
    }
    if (isDigit(inbyte) &&  index > 0) {   // This is the first number of the data strea digit of this data element
      number  = inbyte -'0';
      accumulator = accumulator *10 + number;
    }

    if (!isDigit(inbyte)) { /// this means we have come to the end of the data element /// why dont we look for a comma, this coule be a
      Data1[index] = accumulator * sign ;
      center_value= Data1[5];
      for (int i =1; i<=9;i++) {
        if (Data1[i] <0) fail=1;
    total_value = total_value + Data1[i];
      
      }
     
      number = 0;
      sign = 1;
      accumulator = 0;
      index = 0;
    }
    if (inbyte == ':') { /// this menas we have come to the end of the data Stream
      index= 0;
      number = 0 ;
      accumulator = 0;
      sign = 1;
    }
  }
}

... wrong answer. ALL the code.

I checked in the reference guide
It says:
"Serial.available() never returns -1, it can only return values from 0 to 64 (assuming the standard 64-byte buffer).

Serial.read() will return -1 if there is no data in the buffer"

and so does serial.peek() (which does not read in the byte)
I have tried testing for all of these, and I only have success when testing for a positive result.

Hi
I will try this thanks

Just so I'm clear... you are saying that nothing runs after this statement?

while (Serial.available()==0){}

Then Serial.available() must be returning 0. How are you so sure that data is actually being sent/received?

Have you got everything connected correctly?

I don't think it's a "Serial.available()" problem, but instead this:

Serial.write("*");

does not send a '*' character because Serial.write() sends bytes not strings. Thus, the remote won't see a '*' byte coming in, and doesn't send anything, so Serial.available() always returns zero.
IMHO to do what you want you must use a character, i.e. using single quote:

Serial.write('*');

Check it out and let me know.

I know that there is data available after I transmit "*" because the following code works.
I basically input all the data and parse it out.

Serial.write("*"); 
   delay (25);

  
 while ( Serial.available()>0){
                                              // 
    char inbyte = Serial.read();
    
 
    if (isDigit(inbyte) &&  index == 0) {   // This is the first digit of this data element
      index = inbyte -'0'; // sets the data index to the number 
      inbyte = Serial.read();  // index is set , so read next byte
    } 
    if (inbyte == 'x') { 
      index= 10;
      inbyte = Serial.read();  // index is set , so read next byte
    }
    if (inbyte == 'y') { 
      index= 11;
      inbyte = Serial.read();  // index is set , so read next byte
    }
    if (inbyte == '-') { /// this menas we have come to the end of the data element
       sign = -1;
       inbyte = Serial.read();
    }
    if (isDigit(inbyte) &&  index > 0) {   // This is the first number of the data strea digit of this data element
      number  = inbyte -'0';
      accumulator = accumulator *10 + number;
    }

    if (!isDigit(inbyte)) { /// this means we have come to the end of the data element /// why dont we look for a comma, this coule be a
      Data1[index] = accumulator * sign ;
      center_value= Data1[5];
           
      number = 0;
      sign = 1;
      accumulator = 0;
      index = 0;
    }
    if (inbyte == ':') { /// this menas we have come to the end of the data Stream
      index= 0;
      number = 0 ;
      accumulator = 0;
      sign = 1;
    }
  }
}

I just wanted to hold off reading until there was data available, hence the while (serial.avialable )==0 loop. I tried using serial.peek, which returns -1 when there is no data, but that hangs up also.

Even though you haven't posted ALL the code, I'll make the following observation:

In the code that doesn't work, you send an asterisk only once and wait for a response. In the code that works, you send an asterisk any time you are waiting for a response. Maybe the other side of the serial connection needs multiple asterisks to send a response?

Also try changing Serial.write("*"); to Serial.write('*'); as @docdoc suggested. It's possible that you're sending something else besides an asterisk and that the other side is responding only when you send more than one of whatever you are sending.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.