Reading multiple chars from Serial

Hey there!

I'm trying to modify the Razor IMU Firmware (Arduino) so that can set the Offsets Matrix during bootup.

I need to parse a String containing an int and a \r as a line delimiter... Sounds simple, but...
Seems like the first char is correct all others are only garbage.

int readInt()
{
  int tmp;
   char line[100];
  int done = 0;
  int count = 0;
  
  while (done == 0) {
   if (Serial.available() > 0) {

      line[count] = (char)Serial.read(); // store the char
      if (line[count++] == '\r'){        // if its a CR,
         line[count] = '\0';             //  zero-terminate it
         Serial.println(line); 
          done = 1;         //  and print it.

         Serial.println("loop");         // re-prompt
         count = 0;                      //  and reset the index.
      }
   }
   
}

  tmp = atoi(line);

  return tmp;

}

Serial Input 12345\r
Output: Ã1¦¢5Ã

loop

when i send single chars using Serial Monitor it seems to work correctly. But when i send multiple chars at once, it does not work.

Any body out there who can help me out?

thanks

Peter

I need to parse a String containing an int and a \r as a line delimiter.

You don't have a String. You have a string. Big difference.

What are you sending, and what are you seeing in the serial monitor?

Where is the rest of your code?

here is my entire sketch demonstrating the issue:

int AN_OFFSET[6]={
  0,0,0,0,0,0}; //Array that stores the Offset of the sensors
  
  
  

int readInt()
{
  int tmp;
  String readString;
  char line[100];
  int done = 0;
  int count = 0;
  
  while (done == 0) {
   if (Serial.available() > 0) {
      delay(1);
      line[count] = (char)Serial.read(); // store the char
      if (line[count++] == '\r'){        // if its a CR,
         line[count] = '\0';             //  zero-terminate it
         Serial.println(line); 
          done = 1;         //  and print it.

         Serial.println("loop");         // re-prompt
         count = 0;                      //  and reset the index.
      }
   }
   
}
   //  buffer[i++]='\0';

  //  char cstr[100]; // Or something long enough to hold the longest file name you will ever use.
  //  readString.toCharArray(cstr, sizeof(cstr));
  tmp = atoi(line);

  return tmp;


}

int waitforcommand()
{
  int done = 0;
  while (done < 2) {
    if (Serial.available() > 0) {
      char c = Serial.read();  //gets one byte from serial buffer
      
      if (c == '#') 
      {
        
          return 2;
        }
      
      if (c == '!') 
      {
        
          return 1;
        }
           
        
      }
       
    } 
   
  return done;

}


void setup()
{ 
Serial.begin(115200);

Serial.println("Menu:");
  
  delay(2000);
  if (waitforcommand()==2) //check if there is charecter in the serial buffer
  {
  Serial.println("Enter Values");
    
    //Read Set Values
    AN_OFFSET[0] = readInt();
    AN_OFFSET[1] = readInt();
    AN_OFFSET[2] = readInt();
    AN_OFFSET[3] = readInt();
    AN_OFFSET[4] = readInt();
    AN_OFFSET[5] = readInt();
  }
  
    for(int y=0; y<6; y++)
    Serial.println(AN_OFFSET[y]);
}

void loop() //Main Loop
{
  delay(10);
}

Sample Output:
Serial Input:

12345\r
\r
Output:
Menu:
Enter Values
Ã1¦¢5Ã

loop

Any Ideas?

  String readString;

Not used. Get rid of it.

Where is this input coming from? It looks like you have a mismatch in the serial baud rates between the sender and the Arduino.

Perhaps you need a few more blank lines in waitForCommand(). You do need to use Tools + Auto Format to fix your inconsistent indenting.

         Serial.println(line);

So, some stuff appears out of the blue on the serial monitor. How do you know what it means?

Serial.print("line = [");
Serial.print(line);
Serial.println("]");

takes very little extra time to type/compile/link/upload/execute, and provides loads more information.

Print each character as it is received. We need to understand where the mangling is happening. Print it with some identifying information!

I've already checked the single chars outputed directly and read again from the line array... Its the same "garbage". 1st char seems to be okay...

I'm using Serial Monitor with 115200 BAUD and CR. I can read the Arduinos output very well so i suspect it will not be a baud rate Problem.

Again my cleaned up code:

int AN_OFFSET[6]={
  0,0,0,0,0,0}; //Array that stores the Offset of the sensors

int readInt()
{
  int tmp;
  char line[100];
  int done = 0;
  int count = 0;

  while (done == 0) {
    if (Serial.available() > 0) {
      delay(1);
      line[count] = (char)Serial.read();
      Serial.print("read = [");
      Serial.print(line[count]);
      Serial.println("]");
      // store the char
      if (line[count++] == '\r'){        // if its a CR,
        line[count] = '\0';             //  zero-terminate it
        Serial.print("line = [");
        Serial.print(line);
        Serial.println("]");
        done = 1;         //  and print it.

        Serial.println("loop");         // re-prompt
        count = 0;                      //  and reset the index.
      }
    }

  }

  tmp = atoi(line);
  return tmp;
}

int waitforcommand()
{
  int done = 0;
  while (done < 2) {
    if (Serial.available() > 0) {
      char c = Serial.read();  //gets one byte from serial buffer
      if (c == '#') 
      {
        Serial.read(); // Read \r from buffer
        return 2;
      }
      if (c == '!') 
      {
        Serial.read(); // Read \r from buffer
        return 1;
      }
    }
  } 
  return done;
}

void setup()
{ 
  Serial.begin(115200);
  Serial.println("Menu:");
  delay(2000);
  if (waitforcommand()==2) //check if there is charecter in the serial buffer
  {
    Serial.println("Enter Values");
    //Read Set Values
    AN_OFFSET[0] = readInt();
    AN_OFFSET[1] = readInt();
    AN_OFFSET[2] = readInt();
    AN_OFFSET[3] = readInt();
    AN_OFFSET[4] = readInt();
    AN_OFFSET[5] = readInt();
  }
  for(int y=0; y<6; y++){
    Serial.print("offset = [");
    Serial.println(AN_OFFSET[y]);
    Serial.println("]");
  }
}
void loop() //Main Loop
{
  delay(10);
}

And again my Com log:
Input: => Data Sent by myself
Output: => Data from the Arduino
Remeber SerialMonitor appends \r

Output: Menu:
Input: #
Output:Enter Values
Input: 12345
Output:read = [Ã]
Output:read = [1]
Output:read = [¦]
Output:read = [¢]
Output:read = [5]
Output:read = [Ã]

The only other thing that I can suggest is that you store the value from Serial.read() into a local variable, and print that before storing it in the array.

What operating system?

Already did that. Even when i save it in a local char var its the same.

I'm using Windows7 and arduino 1.01

Can somebody test if my code works on your setup?

thanks

Yesterday i bought an arduino duemilanove and my code works with it. I don't know why it does not work on my Razor IMU with FTDI Setup.

I got an working version. It writes an char wait 50ms and then send the next char via the Serial port to the Arduino. At this slow rate it is working correctly. It is very slow and a real pain, but i guess i'll have to live with that.

I don't understand why the direction from the arduino to the pc works well but not the other way round...

petertester:
I don't understand why the direction from the arduino to the pc works well but not the other way round...

Since the serial connection is asynchronous, it's possible that there is a discrepancy between the two clocks and the PC is better at syncing to the incoming signal than the Arduino is.

Since the problem seems to be about a problem with basic comms, I suggest you would be better to investigate it with a simple 'echo' sketch that simply prints out what it receives (with descriptive text as PaulS advises). If the hard-coded string values come out correctly then you can assume that Arduino-to-PC comms works correctly; if the echoed text then comes out incorrectly, you have proved that PC-to-Arduino comms is working incorrectly. Then you could try varying the comms line parameters to try to eliminate the error.

Thank you very much for this

I will try it...
which parameters can i tweak?

Baud rate?
What else?