Go Down

Topic: Convert String From Serial Data to Numerical Value (Read 4330 times) previous topic - next topic

chiques

Hi Arrrch,

I took a look at the references you mention explaining strings but it still does not explain how to read strings coming in from the serial port.

On a good note, I was able to isolate the variables of interest (after the second comma)

Quote

135.846,4.712,282.736



Quote
4.71


For now I am willing to settle to convert the second string in to a integer. The problem I ran in to is I'm unable to save the string of digits in to an array for later use.

Code: [Select]


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]);
        int f = sensorstring[i].toInt();
    }

    Serial.println(" this is the string of interest");

    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
}



Unfortunately
Code: [Select]
int f = sensorstring[i].toInt(); does not work. I would also assume it would be out of the scope to use this value outside the brackets.

If I simply use
Code: [Select]
int f = sensorstring.toInt(); it compiles but that is only the first string before the first comma.

zoomkat



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.


If it only takes a few minutes to learn the strings answer, how about posting up the needed code.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Arrch




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.


If it only takes a few minutes to learn the strings answer, how about posting up the needed code.


I don't usually write code for people; not part of my philosophy on teaching. I realize your philosophy differs greatly from that.

Luckily I happen to have simple example sitting on my computer:

Code: [Select]
/*
* Example for Serial2Int
* When reading from the serial monitor, there are two important things to note:
* (1) Bytes are read one at a time. So when sending "246", will be read by your
* code as '2', then '4', then '6'. If you want to identify them as related in some
* way, you need a way to determine that. This example uses start and stop bytes.
* (2) Sending a number through the monitor sends it's ASCII representation, not
* the value itself. So typing 3 and hitting enter would send '3' or 51 as per the
* ascii table. To account for this, we will be using atoi(), which takes a null
* terminated array of chars, also known as a string, and produces the int equivalent.
*/

// To send a number through the serial monitor, put it between brackets
const char startByte = '<';
const char stopByte = '>';

// Maximum characters in an int + null terminated character
const byte maxBuffer = 6;

void setup() {
 Serial.begin(57600);
 Serial.println("[Serial2Int]");
}

void loop() {
 // Stores the characters between the start and stop bytes
 static char buffer[maxBuffer];
 // Keeps track of spot in buffer
 static byte index=0;
 
 if (Serial.available() > 0 ) {
   char inChar = Serial.read();
   
   if (inChar==startByte) { // If start byte is received
     index=0; // then reset buffer and start fresh
   } else if (inChar==stopByte) { // If stop byte is received
     processData(buffer); // and process the data
     index=0; // this isn't necessary, but helps limit overflow
   } else { // otherwise
     buffer[index] = inChar; // put the character into our array
     index++; // and move to the next key in the array
     buffer[index] = '\0'; // then null terminate
   }
   
   /* Overflow occurs when there are more than 5 characters in between
    * the start and stop bytes. This has to do with having limited space
    * in our array. We chose to limit our array to 5 (+1 for null terminator)
    * because an int will never be above 5 characters */
   if (index>=maxBuffer) {
     index=0;
     Serial.println("Overflow occured, next value is unreliable");
   }
 }
}

void processData(char buffer[]) {
 unsigned int value = atoi(buffer); // convert string to int
 Serial.print("Value: ");
 Serial.println(value);
}

chiques

Hi Arrrch,
I never meant to cause frustration or the obligation for a hand out. I chose Arduino because of the vast amount of sample code I can read and practice with along with the awesome support by so many vendors (including this forum). Yes, my philosophy to learn is to try (actual hands on); and keep trying until it works. I exhaust all literature that I can understand. I avoid inconveniencing those around me until I am too "lost in the woods". Right now I feel like I'm in the Amazon by some ancient undiscovered Mayan village.

That being said, thank you for the example. I will use it as a study example along with the rest of the recommendations on this thread to try to understand this functionality as much as possible.

Arrch


Hi Arrrch,
I never meant to cause frustration or the obligation for a hand out. I chose Arduino because of the vast amount of sample code I can read and practice with along with the awesome support by so many vendors (including this forum). Yes, my philosophy to learn is to try (actual hands on); and keep trying until it works. I exhaust all literature that I can understand. I avoid inconveniencing those around me until I am too "lost in the woods". Right now I feel like I'm in the Amazon by some ancient undiscovered Mayan village.



My previous reply was directed at Zoomkat.

michinyon

If your system does not have a direct way of converting a number with a decimal point
from a character to a numerical representation,   you can always do it the hard way.

Read the digits before the decimal point (on the left of it),  as an integer.
Read the digits on the right of the decimal point,  and count them.
Create a float,  and divide the second number you read by ten several times
Add the first number you read.

Example:     read   1234.567 in characters
Get 1234 from this
Get 567 from this.  There are three digits
Convert 567 to a floating point number and divide by ten, three times.
You get .567
Now add 1234 to this.  You got  1234.567



zoomkat

Quote
I don't usually write code for people; not part of my philosophy on teaching.


Many years ago in instructor training, I think that refered to as a "talking head".

Quote
Luckily I happen to have simple example sitting on my computer:


Apparently avoided a struggle. I can see the great savings in the below comparison.  8)

Code: [Select]

unsigned int value = atoi(buffer);

unsigned int n = readString.toInt();
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

chiques


If your system does not have a direct way of converting a number with a decimal point
from a character to a numerical representation,   you can always do it the hard way.

Read the digits before the decimal point (on the left of it),  as an integer.
Read the digits on the right of the decimal point,  and count them.
Create a float,  and divide the second number you read by ten several times
Add the first number you read.

Example:     read   1234.567 in characters
Get 1234 from this
Get 567 from this.  There are three digits
Convert 567 to a floating point number and divide by ten, three times.
You get .567
Now add 1234 to this.  You got  1234.567





I'm going to try this approach. None of the other functions mentioned in this post are working for me. I don't mind the practice.

johncc

You could try this, I just found it in 15 seconds on the 'net :)
Code: [Select]

float atof(char *s)
{
    float num=0;
    int radix=1;
    bool dec=1;
    bool neg=1;
    if(*s == '-')
    {
        *s++;
        neg=-1;
    }
    while(*s)
    {
        if( '0' <= *s && *s <= '9')   // isdigit(*s)
        {
            num = 10.0 * num + (*s - '0');
            if(!dec)
                radix*=10;
        }
        else
            dec=0;
        *s++;
    }
    return (num/radix) * neg;
}



Go Up