Serial.read() and save input data for calculation

Hey Group! I want to send via serial monitor a vector like x1, x2, x3 and save this data so that I can do some calculation with it... For example something like: x12, x2+3 and x35! With my code I can send the vector to my Arduino and an print it out.. but I can´t do any calculation! My program overwrite the first entry (=x1 and x2)! Or better, I can´t save the entry.. I don´t know how! I hope someone can help me... please! Thank you!!!
PS: sry, for my bad english... i´m from germany! :wink:

So here "my" CODE:

// zoomkat 10-29-10 simple delimited ',' string parce 
// from serial port input (via serial monitor)
// and print result out serial port
// CR/LF could also be a delimiter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial-delimit-21"); // so I can keep track of what is loaded
  Serial.println("Enter the vector in a mode like: x1,x2,x3");
}

void loop() {

  //expect a string like 123, 456,12
  //or like hello world,who are you?,bye!,
  while (Serial.available()) {
    delay(10);  //small delay to allow input buffer to fill

    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      break;
    }  //breaks out of capture loop to print readstring
    readString += c; 
  } //makes the string readString  

  if (readString.length() >0) {
    Serial.println(readString); //prints string to serial port out
  readString="";}  //clears variable for new input
  //Serial.println(grad_Angel) //after the calculation
  }

My calculation would be: (i.e.)

Vec= (x12+x210+sqrt(x3));
grad_Angel= (Vec*180)/PI;

delay(10); //small delay to allow input buffer to fill

If your input string is longer than ten characters, that won't work.

Ok, thank you!!! and if I write...

delay(100);

can I send a string of 100 characters???

and how can I "save" the input strings??? let´s say I want to calculate: x1x2x3... so it depends on what the user choose for x1, x2 and x3! and therefore they (=x1,x2,x3) has to be saved, or not??? maybe someone has an example how the Code might be...or how I get access of different parts of one string!

and if I write...
can I send a string of 100 characters???

No. You need to use start and end of packet markers, so there is no need to delay.

and how can I "save" the input strings?

You are already saving the input characters in a String object.

let´s say I want to calculate: x1x2x3.

What does the string x1 times the string x2 mean? What does multiplication of strings do?

Maybe stop waving your arms and show some real sample input.

@PaulS: thank you, for your quick answer!!!!!

yeah, ok a sample input....: x1=12, x2=34, x3=87!!! x1, x2, x3 will allways be integer´s...
in the serial monitor I write...

12,34,87

and because of the "," the user understands that this are 3 different numbers..
but the program reads it as one string! and that´s a little bit my problem... how can I tell the program to read the string as 3 different numbers?

First thing you need to do is send the data properly, with some kind of end of packet marker. If you are sending from the serial monitor, it can add a carriage return automatically. That makes a fine end of packet marker.

Second thing you need to do is read and store data, without the delay, until the end of packet marker arrives. Only what that marker arrives should you process the data.

Third thing you should do is get rid of the String instance and use a char array in it's place.

Fourth thing to do is to look at the documentation for strtok() (NOT strtok_r(). Don't even think about using strtok_r() instead of strtok()).

Fifth thing you need to do is look at the documentation for atoi().

@PaulS: WOW, thank you for your help and all the information!!!
I think I need 1, 2 days to inform myself about all the functions and the other stuff... :wink:
But I have found a Code which helps me a lot... [without having strtok()]

// semicolon counter
int sccount = 0;
// index of next character in string
int sindex = 0;
// the string
char c_string[20];
// the three converted integers
int a_int[3];

void setup() {
  Serial.begin(9600);
  Serial.println("serial-delimit-21"); // so I can keep track of what is loaded
  Serial.println("Enter the vector in a mode like: x1,x2,x3");
}

void loop()
{
  while(Serial.available() > 0) {
    // store the next character
    c_string[sindex] = Serial.read();
    // If it is a semicolon, count it
    if(c_string[sindex++] == ',')sccount++;
    // Put a null at the end of the current string
    c_string[sindex] = 0;
    // If we have two semicolons, we're done
    if(sccount == 3)break;
  }
  if(sccount == 3) {
    // Now parse the string into three integers
    sindex = 0;
    for(int i = 0;i < 3;i++) {
      a_int[i] = atoi(&c_string[sindex]);
      // skip to the next semicolon
      while(c_string[sindex] != ',')sindex++;
      // skip over the semicolon
      sindex++;
    }
    // zero the counts just in case there's a next time
    sindex = 0;
    sccount = 0;
    
    int product=a_int[0]*a_int[1]*a_int[2];
    
    Serial.println(a_int[0]);
    delay(100);
    Serial.println(a_int[1]);
    delay(100);
    Serial.println(a_int[2]); 
    delay(100);
    Serial.println(product);
  }
}

but without the

delay(100);

between

Serial.println

the program gets sometimes confused.. why?(it swaps a_int[0] and a_int[1])
and for "big" entries like x1=65, x2=75, x3=155 the "product" is wrong (better: I get a negativ number!)
the "product" isn´t a integer anymore... what shall I take?? (double, long, ???)

ok, sry! I solved the problem with the "big" entries..

We shared, do you want to?

Hi group! now I have a new problem... I want to enter a 2nd vector and do some calculation with both of them!
in my code I ask for the 2nd vector inside the void loop() function... I´m not sure if this is a "good" solution, because the loop() function repeats again and again.. and that´s why it overwrites the 1st vector and my code never comes to a end! so the program never do the calculation I want...

Here my code:

// semicolon counter
int sccount = 0;
int kccount=0;
// index of next character in string
int sindex = 0;
int kindex =0;
// the string
char c_string[20];
char d_string[20];
// the three converted integers

//Variablen fuer Rechnung /for the calculation at the end
double a_int[3];
double b_int[3];
double Vec_Dot;
double Vec_betrag;
double angel_1;
double Vec_angel;
double grad_Angel;


void setup() {
  Serial.begin(9600);
  Serial.println("serial-delimit-21"); // so I can keep track of what is loaded
  Serial.println("Enter the vector in a mode like: x1,x2,x3,");
  Serial.println();
}

void loop()
{
  while(Serial.available() > 0) {
    // store the next character
    c_string[sindex] = Serial.read();
    // If it is a semicolon, count it
    if(c_string[sindex++] == ',')sccount++;
    // Put a null at the end of the current string
    c_string[sindex] = 0;
    // If we have two semicolons, we're done
    if(sccount == 3)break;
  }
  if(sccount == 3) {
    // Now parse the string into three integers
    sindex = 0;
    for(int i = 0;i < 3;i++) {
      a_int[i] = atoi(&c_string[sindex]);
      // skip to the next semicolon
      while(c_string[sindex] != ',')sindex++;
      // skip over the semicolon
      sindex++;
    }
    // zero the counts just in case there's a next time
     sindex = 0;
     sccount = 0;

     
     Serial.print("x1: ");Serial.println(a_int[0]);
      delay(100);
      Serial.print("x2: ");Serial.println(a_int[1]);
      delay(100);
      Serial.print("x3: ");Serial.println(a_int[2]);
      
    Serial.println("Enter 2nd vector");
    while(Serial.available() > 0) {
    // store the next character
    d_string[kindex] = Serial.read();
    // If it is a semicolon, count it
    if(d_string[sindex++] == ',')kccount++;
    // Put a null at the end of the current string
    d_string[kindex] = 0;
    // If we have two semicolons, we're done
    if(kccount == 3)break;
  }
  if(kccount == 3) {
    // Now parse the string into three integers
    kindex = 0;
    for(int j = 0;j < 3;j++) {
      b_int[j] = atoi(&d_string[kindex]);
      // skip to the next semicolon
      while(d_string[kindex] != ',')kindex++;
      // skip over the semicolon
      kindex++;
    }
    // zero the counts just in case there's a next time
    kindex = 0;
    kccount = 0;
  
   
    //Ausgabe des Vektors
      Serial.println("The 1st vector was:");
      Serial.print("x1: ");Serial.println(a_int[0]);
      delay(100);
      Serial.print("x2: ");Serial.println(a_int[1]);
      delay(100);
      Serial.print("x3: ");Serial.println(a_int[2]);
      
      Serial.println("The 2nd vector was:");
      Serial.print("y1: ");Serial.println(b_int[0]);
      delay(100);
      Serial.print("y2: ");Serial.println(b_int[1]);
      delay(100);
     Serial.print("y3: "); Serial.println(b_int[2]);
     
      /* Here the calculation begins...
   // Berechnung der horizontalen Ebene für Schrittmotor (x,z-Koord.)
        Vec_Dot= (a_int[0]*b[0] + a_int[2]*b[2]);
        Vec_betrag = (sqrt(a_int[0]*a_int[0]+a_int[2]*a_int[2])*sqrt(b[0]*b[0]+b[2]*b[2]));
        angel_1= (Vec_Dot/Vec_betrag);
        Vec_angel= acos (angel_1);
        grad_Angel= (Vec_angel*180)/PI;
         Serial.println("Fuer die horizontale Ebene-Schrittmotor!");
         Serial.println("Angel in Bogenmass:");
         Serial.println(Vec_angel);
         Serial.println("Angel in Gradmass:");
         Serial.println(grad_Angel);
         Serial.println();
         delay(500);
         
   //Berechnung der vertikalen Ebene für Servo (y,z-Koord.)
        Vec_Dot= (a_int[1]*b[1] + a_int[2]*b[2]);
        Vec_betrag = (sqrt(a_int[1]*a_int[1]+a_int[2]*a_int[2])*sqrt(b[1]*b[1]+b[2]*b[2]));
        angel_1= (Vec_Dot/Vec_betrag);
        Vec_angel= acos (angel_1);
        grad_Angel= (Vec_angel*180)/PI;
          Serial.println("Nun fuer die vertikale Ebene-Servo!");
          Serial.println("Angel in Bogenmass:");
          delay(100);
          Serial.println(Vec_angel);
          Serial.println("Angel in Gradmass:");
          Serial.println(grad_Angel);
          Serial.println();
          */
   
  }
}}

I hope you can help me again... is there any facility to stop the loop() function at a certain/decided point?

oh, and another question...
Why the definition:

char c_string[20]

why 20??? why not 100, 10 or whatever?

Teemu:
oh, and another question...
Why the definition:

char c_string[20]

why 20??? why not 100, 10 or whatever?

Presumably, the person that wrote the code decided that was the correct length for their purposes.

@dxw00d: ok, thx for the explanation!!!
but can someone tell me, how I can add a 2nd vector to the code (I posted) and then do the calculation??

Look at the code you posted. Identify the pieces of it that relate the storing the first vector. Replicate the stuff that stores the first vector so that you have room to store a second one.

When reading and parsing the serial data, you need to keep track of whether the data is the first vector or the second vector, and store the data in the appropriate places.