why dosent this code (Read integers from serial) work??

hello. i am trying to read some integers from serial, and assign them to valuables, dependign on the letter before them.
on the one end, i have an arduino, transmiting at 115200 baud, a string : "F1,R2,S3,C4,"

and on the other end i have this code:

int final;
int value;
char ch;
int temp1;
int temp2;
int temp3;
int temp4;

void setup() {
  Serial.begin(115200); // same as in your c++ script
}

void loop()
{
  while(Serial.available()>0) {
    ch = Serial.read();
    if (ch=='F'){
      temp1=SerialInt();
    }
    else if (ch=='R'){
      temp2=SerialInt();
    }
    else if (ch=='S'){
      temp3=SerialInt();
    }
    else if (ch=='C'){
      temp4=SerialInt();
    }



  }
  Serial.print(temp1);
  Serial.print(",");
  Serial.print(temp2);
  Serial.print(",");
  Serial.print(temp3);
  Serial.print(",");
  Serial.println(temp4);

}


int SerialInt() {

  while (1)  {
    char DT = Serial.read();
    if( isDigit(DT) )// is this an ascii digit between 0 and 9?
    {
      value = (value * 10) + (DT - '0'); // yes, accumulate the value
    }
    else {
      final = value;
      value = 0; 
      return final;
    }

  }

}

but, if i lok at the terminal, although it should be supposed to be onlu "1,2,3,4" , i can clearly see that those numbers arent always the same.... any ideas???

The usual reason; you're reading serial data without checking to see if there's something to read.

Edit: resetting "value" would also prove advantageous.

Hm??? i have the :

while(Serial.avaliable()>0 )

also, if that was the case, the valuable "temp1" for instance, should not get any other value rather than "1" , since R is allways followed by "1" ?....

i have the

That's right, you do.
But only in one place.

i dont understand... where else should it be? :stuck_out_tongue:

How many reads have you got?

And it only shows that you have at least 1 it does not prove that you have as many as you want. The arduino is many many times faster than serial.

Mark

oh i think i get it. you mean it can get to the part "IF ch="F"" ,
but when it calls the SerialINT() function, the bytes after "F" havent arrived yet??

what would be a good way to do this?

what would be a good way to do this?

Wait for a character to arrive, then read it.

so, maybe, instead of sending "F1,R2,S3,C4"
i should send something like : "F1,R2,S3,C4,T"

And on the receiver side, i will have something that looks for the "T", and only then tries to parse the digits to integers??

And on the receiver side, i will have something that looks for the "T", and only then tries to parse the digits to integers??

You could do something like that by putting the characters into an array as they are received and then parsing the string. when the termination character is received. This is a good idea, but it will not solve the problem of trying to read from Serial when there is nothing there to read. At the moment you check that Serial.available() is greater than zero and immediately assume that there are several characters available by using parseInt(). Before reading from Serial you must test to know that at least one character is available.

Servo test code that gets values from character strings sent and gets the desired data from the saved Strings.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

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

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

what would be a good way to do this?

int getcwait()
{
   while (Serial.available <= 0)
      ; // spin and do nothing while waiting for data
   return Serial.read();
}

cool! thanks for the replies everyone!! i will get to some more work :slight_smile:

   while (Serial.available <= 0)

There are 0 or more bytes in the buffer. There can never be less than 0. So, the test for negative values is unnecessary.