Convert String From Serial Data to Numerical Value

HazardsMind:
I'm not home right now, but I will give you a sample as soon as I can.

Edit: I was able to get this from a post I did a while back. Wow my iPhone likes to stretch things out. Sorry about that.

/*

control test
*/
#include<string.h>
int DRV1,DRV2,STRR,STRL;
int x = 0;
int y = 0;
int s = 0;
...

Hi HazardsMind,

I went through the sample you suggested and noted what "I think" each line does. The only one which I am figuring out are:

  1. void move(int x = 0,int y = 0,int s = 0); //Not sure why this needs to be done ???
  1. move(x, y, s); // DO NOT UNDERSTAND "move()"
//from http://arduino.cc/forum/index.php?topic=142777.0

/*
control test //name of program
 */
#include<string.h> //name of library needed
int DRV1,DRV2,STRR,STRL; //declare 4 integers
int x = 0; //intialize x
int y = 0; //initialize y
int s = 0; //initialize s
void move(int x = 0,int y = 0,int s = 0);  //Not sure why this needs to be done ???
//double z; //double the z variable (for more precision)
String val = ""; //set some buffer aside for val
String  X= ""; //set some buffer aside for X
String  Y= ""; //set some buffer aside for Y
String  state = ""; //set some buffer aside for state
//int state = 0; //initialize state to 0
int currentCommand = 0; //initialize current command to 0

int ledpin = 13; //set LED pin
byte Mopen = 4; //sets Mopen to B0100
byte Mclosed = 2; //sets Mclosed to B00010
byte M1L = 3;// PWM
byte M2L = 5;// PWM
byte M1R = 9;// PWM
byte M2R = 6;// PWM

void setup()
{
  pinMode(ledpin, OUTPUT);  // pin 13 (on-board LED) as OUTPUT
  pinMode(Mopen, OUTPUT);  // pin Mopen is set as an output                              
  pinMode(Mclosed, OUTPUT); // pin Mclosed is set as an output
  pinMode(M1L, OUTPUT);     //pin MIL is set as an output
  pinMode(M1R, OUTPUT);  // in MIR is set as an output
  pinMode(M2L, OUTPUT);  //pin M2L is set as an output 
  pinMode(M2R, OUTPUT); // pin M2R is set as an output
  Serial.begin(9600);       // start serial communication at 115200bps

}

void loop() {
  if( Serial.available())       // if data is available to read, this is how to check the serial part for strings
  { 
    digitalWrite(ledpin, HIGH); // if data is detected set the pint set to ledpin to HIGH (ON)
    char c= Serial.read(); // the string in serial read() is buffered in to c as characters
    if (c == ','){    //look at the incoming chars, if it is a ',' then switch the case
      currentCommand++;  //for some reason currentCommand increments????
    }
    else {   //if it is not ',' then store chars in string, keep storing the string until a , is found
      val += c;  // same as (val + c = c)val is the next string + the previous character stored in buffer
      //Serial.println(val);
      switch (currentCommand) { // for each string, currentCommand appears to increment by 1

      case 0:  //in the even there was only 1 string before the ',' X is equal to the val in buffer and val buffer is cleared ""
        X += val; // same as (X + val = val), new variable X is equal to the whole string val before the ','
        val = ""; // clear the information in the val buffer
        break; // break out of case 0
 
      case 1: //if currentCommand equals 1
        Y += val; // same as (Y + val = val), Y is now the string waiting in the val buffer
        val = ""; // clear out the val buffer
        break; //get out of case 2

      case 2:
      //Serial.println("X: "+X);
      //Serial.println("Y: "+Y);    
        state = val;   // this will only receive 1 value
        currentCommand = 0; //reset currentCommand counter to 0
        val = ""; // clear out the val buffer
        //Serial.println("state: "+state);
        //Serial.println();
        x=X.toInt();  //string to int , convert string X to integer
        y=Y.toInt();  //string to int, convert string Y to integer
        s=state.toInt();  //string to int, convert state to integer
        X=""; Y=""; state=""; //clear the X, Y and state buffer information
        move(x, y, s); // DO NOT UNDERSTAND "move()"  
        break; // get out of case 3
      }
    } 
  }
} 
//***ALL THIS STUFF BELOW IS FOR SERVO MOVEMENT
//***SENDS OUT VOLTAGE VALUES
  void move(int x, int y, int s)
  {  
      x=constrain(x, -90, 90); 
      y=constrain(y, -90, 90);

  //Movement varibles
  
  int DRV2 = map(x, -90, 0, 255, 0);
  int DRV1 = map(x, 0, 90, 0, 255);
  int STRR = map(y, -90, 0, 255, 0);
  int STRL = map(y, 0, 90, 0, 255);  

  if(x > 0)//forwards               
  {
    //Serial.println("Driving"); 
    analogWrite(M1L, abs(DRV1 - STRL)); analogWrite(M1R, abs(DRV1 - STRR));   
    analogWrite(M2L, 0); analogWrite(M2R, 0);   
  }
  else if(x < 0)//backwards               
  {
    //Serial.println("Driving"); 
    analogWrite(M1L, 0); analogWrite(M1R, 0);   
    analogWrite(M2L, abs(DRV2 - STRR)); analogWrite(M2R, abs(DRV2 - STRL));   
  }
  else if(x == 0 && y >0)//right              
  {
    //Serial.println("Driving"); 
    analogWrite(M1L, STRL); analogWrite(M1R, 0);   
    analogWrite(M2L, 0); analogWrite(M2R, STRL);   
  }
  else if(x == 0 && y < 0)//left              
  {
    //Serial.println("Driving"); 
    analogWrite(M1L, 0); analogWrite(M1R, STRR);   
    analogWrite(M2L, STRR); analogWrite(M2R, 0);   
  }

  else //full stop
  { 
    digitalWrite(M1L, LOW); digitalWrite(M1R, LOW);        
    digitalWrite(M2L, LOW); digitalWrite(M2R, LOW);    
  }

   if(s == 1)
    {
      //Serial.println("Claw Opening");
      digitalWrite(Mopen, HIGH); digitalWrite(Mclosed, LOW);
    }
    if(s == 2)
    {
      //Serial.println("Claw Closing");
      digitalWrite(Mopen, LOW); digitalWrite(Mclosed, HIGH);
    }
    if(s == 0)
    { 
      digitalWrite(Mopen, LOW);  digitalWrite(Mclosed, LOW);
    } 
   else{
    digitalWrite(ledpin, LOW);
    x=0; y=0; s=0;
  } 
 }

Phew, where to begin...

  1. void move(int x = 0,int y = 0,int s = 0); //Not sure why this needs to be done ???

This is a function prototype. The Arduino IDE handles these for you, so typically these are not necessary.

  1. move(x, y, s); // DO NOT UNDERSTAND "move()"

It's just a call to the function with the provided values.
if( Serial.available())       // if data is available to read, this is how to check the serial part for strings
characters, not strings.
char c= Serial.read(); // the string in serial read() is buffered in to c as characters
the character is read, not the string

if (c == ','){    //look at the incoming chars, if it is a ',' then switch the case
      currentCommand++;  //for some reason currentCommand increments????
    }

If the character is a deliminator (comma in this case) increment the number of commands received.

    else {   //if it is not ',' then store chars in string, keep storing the string until a , is found
      val += c;  // same as (val + c = c)val is the next string + the previous character stored in buffer
      //Serial.println(val);

If it's not a comma, concatenate it onto the String val (note the difference in capitalization, String and string are not the same thing).

void move(int x = 0,int y = 0,int s = 0); //Not sure why this needs to be done ???

Its not needed, you can take it out. I originally wrote this code using a C++ based debugger software (old software), and it had to be inserted at the top. so when I brought it to arduino, I forgot to take it out.

move(x, y, s); // DO NOT UNDERSTAND "move()"

Move() is a function I made that feeds those gotten values to my motors, it is get rid of too much cluster in my Loop function.

It is very difficult to modify code on an IPhone, so I just left everything in. I just wanted to show you an example of how to get, convert and split the data to different ints.

And they are not servos, they are DC motors. However same can be done with servos.

Arrch:
Phew, where to begin...
...

Thanks Arrch,
I would like convert this into a floating number but I'm having a hard time finding the Reference syntax in Arduino for the following C equivalents? Would you happen to know where I can find them?

atol (Convert string to long integer) obvoiusly this is "toInt()"
atof (Convert string to double)
strtol (Convert string to long integer)

You need to be clearer about what you want to do. There is a huge difference between a string and a String. The string is not a class and does not have a toInt() method.

Frankly, you should not be using the String class at all. It has a major problem that is going to, sooner or later, bite you.

PaulS:
You need to be clearer about what you want to do. There is a huge difference between a string and a String. The string is not a class and does not have a toInt() method.

Frankly, you should not be using the String class at all. It has a major problem that is going to, sooner or later, bite you.

Now I'm really lost. My goal is to convert the second string to a value so I can write some algorithms.
0.000,0.000,0.000

This looks like it's converting each ASCII character

String : ASCII

0 : 48
. : 46
0 : 48
0 : 48
0 : 48

Ref: http://arduino.cc/en/Tutorial/ASCIITable

I know this doesn't solve my conversion problem but I'm practicing difference string conversions.

This looks like it's converting each ASCII character

Please don't post code using the invisible font.

atof (Convert string to double)

double = float.

Edit.

This method is used for arrays, not strings.

It most certainly is for strings. It is NOT for non-NULL-terminated arrays of chars.

This will take some time to soak in.

Thanks

I'm not understanding why I'm unable to convert the Liters/Minute to a numberical value.

7.320,4.734,284.057
4.7340 Liters/Minute
0 in HEX

   if (sensor_stringcomplete){                                                 //if a string from the Atlas Scientific product has been received in its entirety
      Serial.println(sensorstring);                                             //use the hardware serial port to send that data to the PC

      
  for (int i=6; i<11; i++)  {
    Serial.print(sensorstring[i]);     //print each string character to verify
    float flowLong = (sensorstring[i] - '0');
                }
    Serial.print(flowLong);Serial.println(" Liters/Minute"); 
    if (flowLong < 4.5) {
    Serial.println("FLOW WARNING!!!");
    }
       Serial.print(flowLong,HEX);Serial.println("  in HEX");
       sensorstring = "";                                                      //clear the string buffer:
       sensor_stringcomplete = false;                                          //reset the flag used to tell if we have received a completed string from the Atlas Scientific product
       }

Start by fixing your indenting; it's atrocious and makes it very difficult to follow.

  for (int i=6; i<11; i++)  {
    ...
    float flowLong = (sensorstring[i] - '0');
  }

So loop through 5 characters in a string, creating a new float variable, assigning it a variable, and discarding it.

When you declare a variable like you are doing here, it is only valid inside the innermost curly braces. So the flowLong you create here isn't the same as the flowLong as you are printing to the screen. Not that fixing the scope issue will fix your issue; the algorithm you are using make absolutely no sense and will only result in floatLong containing the numeric value of the last digit.

Drop the String object. Use c style strings and atof().

Simple servo code that takes a numerical string from the serial monitor and converts it into a number for controlling a servo.

//zoomkat 3-5-12 simple delimited ',' string parce 
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

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

  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-delomit-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like 700, or 1500, or 2000,
  //or like 30, or 90, or 180,

  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);
          myservo.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          myservo.write(n);
        }

        //do stuff with the captured readString 
        readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

What is the syntax to convert to floating?

int n = readString.toInt();

Easy, readString.toFloat();

Check this out,
http://mootools.net/docs/core/Types/Number

HazardsMind:
Easy, readString.toFloat();

Check this out,
MooTools Core Documentation

Uhm, not sure what I'm doing wrong.

int n = readString.toFloat();

error: 'class String' has no member named 'toFloat'

HazardsMind:
Easy, readString.toFloat();

Not included with Arduino's version of the String object library, much like sprintf() doesn't accept the %f format specifier.

Arrch:

HazardsMind:
Easy, readString.toFloat();

Not included with Arduino's version of the String object library, much like sprintf() doesn't accept the %f format specifier.

Hi Arrrch,
Does this mean its not possible to convert a string to float in Arduino?

There is a patch you need to download to get .toFloat().
http://www.timewasters-place.com/arduino-string-and-float/

Also you wouldn't store a float value in an int, you would put it in a double.
So,
double n = readString.toFloat();

chiques:
Hi Arrrch,
Does this mean its not possible to convert a string to float in Arduino?

Consider it a sign to stop using Strings and take a few minutes to learn about strings.