Pages: 1 2 [3]   Go Down
Author Topic: Convert String From Serial Data to Numerical Value  (Read 3616 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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:
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:
int f = sensorstring.toInt();
it compiles but that is only the first string before the first comma.
Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9636
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3382
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
 * 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);
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

California
Offline Offline
Faraday Member
**
Karma: 88
Posts: 3382
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Faraday Member
**
Karma: 62
Posts: 3031
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Logged

0
Offline Offline
Tesla Member
***
Karma: 145
Posts: 9636
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-cool

Code:
unsigned int value = atoi(buffer);

unsigned int n = readString.toInt();
Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Temple, Texas
Offline Offline
Sr. Member
****
Karma: 14
Posts: 361
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You could try this, I just found it in 15 seconds on the 'net smiley
Code:
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;
}

Logged

Pages: 1 2 [3]   Go Up
Jump to: