Go Down

Topic: Newbie to Arduino needs help with strings and compares to them (Read 1 time) previous topic - next topic

brantel

Say I have an ASCII string "12345678910" and I want to pull out two of the characters and turn them into the decimal number they actually represent and do some compares on them to a decimal number, what is be best approach to this?

For instance say I want to pull out the ASCII 7 and 8 above and combine them and convert them to decimal 78 and then compare that number to a range of 00-40 = shorted, 41-69 = good, 70-99 = open.

Any ideas?

Would having the string stored in a char array make this easier because I have both versions of the string available?

Thanks in advance!

jcarrr

Do you know where in the string the interesting characters are located or are they always 7 and 8 or perhaps in positions 6 and 7 as in the example?



jp128

Look at commands like:

charAt or substr, and atoi.

To compare two strings, look at strcmp, or the == operator.
John-Paul
Geek Squad - Getting Geekier :D

brantel

Yes,  I know where they are...always on the same place.


How can I compare only two characters in the string?  How do I snatch  them out and put them back into another string in the correct order?

PaulS

If the characters are in a char array, copy them to another char array, and NULL terminate it.

Code: [Select]
char allData[] = "12345678910";
char funData[3];

funData[0] = allData[6];
funData[1] = allData[7];
funData[2] = '\0';


Then, you can use atoi.
Code: [Select]
int val = atoi(funData);

If the characters are in a String object, you can extract the substring of interest.
Code: [Select]
String allData = "12345678910";
String funData = allData.substring(6, 8);


Then, extract the character array from funData:
Code: [Select]
char buffer[3];
funData.toCharArray(buffer, 3);


Then, use atoi:
Code: [Select]
int val = atoi(buffer);

zoomkat

You can use the built in string functions to parse captured character strings. The below is for servos, but you don't need a servo to try it to see how the string from the serial monitor is captured, split, and turned into numbers.

Code: [Select]
// zoomkat 11-22-10 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550

#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1;  // create servo object to control a servo
Servo myservo2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(6);  //the pin for the servo control
  myservo2.attach(7);
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(10); 
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {
      Serial.println(readString); //see what was received
     
      // expect a string like 07002100 containing the two servo positions     
      servo1 = readString.substring(0, 4); //get the first four characters
      servo2 = readString.substring(4, 8); //get the next four characters
     
      Serial.println(servo1);  //print to serial monitor to see results
      Serial.println(servo2);
     
      int n1; //declare as number 
      int n2;
     
      char carray1[6]; //magic needed to convert string to a number
      servo1.toCharArray(carray1, sizeof(carray1));
      n1 = atoi(carray1);
     
      char carray2[6];
      servo2.toCharArray(carray2, sizeof(carray2));
      n2 = atoi(carray2);
     
      myservo1.writeMicroseconds(n1); //set servo position
      myservo2.writeMicroseconds(n2);
    readString="";
  }
}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)


brantel

Well the data I am parsing turns out it is in HEX instead of just ASCII characters.

so a sentence of my data looks like this:    =00000E1F017E250100<CR><LF>   it always starts with an = and ends with a CR &LF

I am after the the hex number 25 (hex) in this example which happens to be temperature in °C of 37 (dec)

I am already moving this sentence into a char array so how do I get only those characters and put them in a variable that can be printed as a decimal number?




PaulS

The 2 is in position 13. The 5 is in position 14. The temperature is:
Code: [Select]
int temp = (array[13] - '0') * 16 + (array[14] - '0');
The value in array[13] in your example is '2'. '2' - '0' is 2. The value in array[14] is '5'. '5' - '0' is 5. 2 * 16 is 32. 32 + 5 is 37.

brantel

I know this is kids stuff to you guys but some of us have to learn somehow.

Thanks!!!!


brantel

#10
Feb 18, 2011, 05:51 pm Last Edit: Feb 18, 2011, 10:16 pm by brantel Reason: 1
I could never get the example above to work.  It would not return the correct value with certain HEX combinations...  0A for example would not return 10, it would return something like 16????  I was not smart enough to figure out why this does not work so I gave up.

Anyway I figured out how to use the strtol function and it works great so far...

Code: [Select]

      //string is a char array that I load my ASCII sentences in from the serial port.  This works fine, the sentence data looks like this: =00000E1F017E250100

       char TempData[3]; //Create array for temperature data
      TempData[0] = string[13]; //Load the first ASCII representation of the first HEX number into the array
      TempData[1] = string[14]; //Load the second ASCII representation of the second HEX number into the array
      TempData[2] = '\0'; //Load a Null character into the array
      int Base=16; //Set the base for the strol function to HEX
      long int Temp; //Define the Temp Variable
       Temp = strtol(TempData, NULL, Base); //Run the strol function on the TempData array and return the variable to Temp
      mySerial.print(Temp, DEC); //Print TEMP

zoomkat

Well, I think hex is just a dual ascii character representation of a number. You could try something like below to capture the desired ascii characters and then convert them into a number. You can paste (ctrl-v) your string into the serial monitoe text box and experiment.

Code: [Select]
// 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, testhex;

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

void loop() {

  //expect a string like =00000E1F017E250100
    while (Serial.available()) {
    delay(1);  //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 at ,
    } 
    readString += c; //makes the string readString
  }   

  if (readString.length() >0) {
    Serial.println(readString); //prints string to serial port out
    // do other stuff with string here
         
      testhex = readString.substring(12, 14); //get the first four characters
      Serial.println(testhex);
    readString=""; //clears variable for new input
  }
}

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

Go Up