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.
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.
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;
}
}
}
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.
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:
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.