Help - About Hardware Serial Port input string length ??

Hi Guys, I got a Bluetooth Shield v1.0 from ElecFreaks. This Bluetooth module could be controlled by AT command. There is all work OK, however when I setting AT such as AT+INQM=1,1,48 always return Failed.

I was confused, so I check the issue and found out the Serial port input string always be divided into two strings from ninth character.

The demo code and Serial port monitor as below, which get the string from Hardware Serial port and print it to SoftwareSerial Port.

Anybody could tell me why the Serial port input string be divided into two from 9th character ??

Serial data transmission is slow.

You can read what I type far faster than I can type. Serial data transmission works the same way.

The Arduino can read the data faster than it arrives. So, when there is no more data pending, it thinks it's done, so it prints out what it got.

In the same way that you know a word has ended because a space appears, and that a sentence has ended because a period appears, you need to not print what you have read until you have read a complete packet. What defines the end of the packet is critical to discover, so you know when a packet has ended, and you can use the packet.

By the way, reading data using a do/while loop is wrong. Use a while loop, instead.

A do/while loop does something, and then checks if it should do it again. You read a character that might not be there, and then check to see if you should do it again.

The while loop would perform the check first, then the read.

Finally, you are not NULL terminating the array as you add to it.

while(Serial.available() > 0)
{
   someChar[i++] = Serial.read();
   someChar[i] = '\0';
}

PaulS: Serial data transmission is slow.

You can read what I type far faster than I can type. Serial data transmission works the same way.

The Arduino can read the data faster than it arrives. So, when there is no more data pending, it thinks it's done, so it prints out what it got.

In the same way that you know a word has ended because a space appears, and that a sentence has ended because a period appears, you need to not print what you have read until you have read a complete packet. What defines the end of the packet is critical to discover, so you know when a packet has ended, and you can use the packet.

By the way, reading data using a do/while loop is wrong. Use a while loop, instead.

A do/while loop does something, and then checks if it should do it again. You read a character that might not be there, and then check to see if you should do it again.

The while loop would perform the check first, then the read.

Finally, you are not NULL terminating the array as you add to it.

while(Serial.available() > 0)
{
   someChar[i++] = Serial.read();
   someChar[i] = '\0';
}

Hi PaulS, Thanks for your reply. But I do not think this is do-while() problem. I have modified to while(), but the problem still. And I found a very funny problem. If I not use the Serial.print() in demo code, the result as below, the string be divided into two parts from first character.

However, when I add the Serial.print() to demo code, the first string be divided length depends on the print string length. Then the output is all right.

Some serial test code.

// zoomkat 7-30-11 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    Serial.println(readString);

    readString="";
  } 
}

Can you please copy and paste your code (using the Code tags - the # button above the posting box) and not screenshots of the code? Then we can copy and paste snippets in replies.

Your loop is fundamentally flawed, as Paul is trying to tell you. Sorry.

As data trickles in from your serial port you are grabbing as much as you can, but then when it runs out (as it will after a few bytes because the processor is much faster than a 9600 baud device) you exit loop, which then restarts, and resets i to zero, and someChar to an empty array.

You need to move those variables out of loop. Look around for some examples of handling serial input.

[quote author=Nick Gammon link=topic=75380.msg569504#msg569504 date=1318659414] Can you please copy and paste your code (using the Code tags - the # button above the posting box) and not screenshots of the code? Then we can copy and paste snippets in replies.

Your loop is fundamentally flawed, as Paul is trying to tell you. Sorry.

As data trickles in from your serial port you are grabbing as much as you can, but then when it runs out (as it will after a few bytes because the processor is much faster than a 9600 baud device) you exit loop, which then restarts, and resets i to zero, and someChar to an empty array.

You need to move those variables out of loop. Look around for some examples of handling serial input. [/quote]

Hi Nick , Thanks for your reply and I have resolve it now. You are right that is the Serial port is too slow. I added a delay(3) in the while loop, then the print display is all right.

Thank you very much again.

You are right that is the Serial port is too slow. I added a delay(3) in the while loop, then the print display is all right.

Now, trying changing the baud rate to 115200. The problem will return, so you can see that your "solution" isn't a solution at all. It's a band-aid.

Now, trying changing the baud rate to 115200. The problem will return, so you can see that your "solution" isn't a solution at all. It's a band-aid.

I don't think that is a totally correct statement when the string being sent is less than the available buffer size. Generally one can almost always think up a condition to make something fail. Solutions should be used that address the conditions under which they will be used.

At 9600 baud the interval between characters, if sent directly after one another, will be 1.04 mS. Thus increasing the delay from 1 mS to 3 helps it to work. But if the sending end delays for 3 mS (which it is totally allowed to do by the protocol) for example, because of some internal activity it has to do, then the "fix" will work some of the time, and not all. Plus you haven't learned how to correctly handle serial comms.

For one thing alone, you have now artificially increased the time between characters from 1.04 mS to 3 mS, thus slowing down your reception rate by almost a factor of 3.

JesonYong:
You are right that is the Serial port is too slow.

The Serial port is not too slow. The serial port is correctly processing data at the rate at which it is arriving. Your code is not correctly written to receive serial data. If anything, you could say your code is “too fast”. And being “too fast” you have to write it differently.