Go Down

Topic: Solved: coverting a concatenated string to float (Read 558 times) previous topic - next topic

DavidFoe

Dec 05, 2011, 09:46 pm Last Edit: Dec 05, 2011, 10:44 pm by DavidFoe Reason: 1

A blindingly stupid question ....

I have this:  $HCHDM,287.2,M*26  sent from my compass to Arduino via serial commmunication and I have figured out how to read each of the four asci characters that indicate direction (287.2 in this case) and I have concatenated them as a string that I call compassheadingstring.   I can see the string (287.2) on the serial monitor.  My problem is simple, (as am I), I want to do math but the string i created (287.2) is not recognized as a number.   The float() function doesn't like my string of characters and gives me:  error: invalid cast from type 'String' to type 'float'  when I do:    heading = float(compassheadingstring);
How do I make the string of characters into a real number?

Thanks for any insight!

david

AWOL

It's better if you post code, but you could try atof
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

James C4S

float heading = atof(compassheadingstring);

For reference:
http://www.cplusplus.com/reference/clibrary/cstdlib/atof/
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

DavidFoe

Thanks for the atof suggestion but still no go.   Now I get:   error: cannot convert 'String' to 'const char*' for argument '1' to 'double atof(const char*)'

Here is the code (I bet if I knew better I'd be embarrassed by its uglyness):
Code: [Select]


#include <NewSoftSerial.h>

NewSoftSerial mySerial(2, 3, true);  // RX here is receive pin 2; TX pin 3
byte aa;
byte bb;
byte cc;
byte dd;
byte ee;
int var = 0;
double heading = 0;
double error = 0;
String compassheadingstring = "";
void setup() 
{
  Serial.begin(4800);  // this is the rate the computer talks to the arduino

  // set the data rate for the NewSoftSerial port
  mySerial.begin(4800);  // default rate is 4800 bps

}

void loop()                     // run over and over again

{

  if (mySerial.available())
  {
    aa= mySerial.read(); // get the byte of data

     if (aa=='$')   // $ tells us we are at the start of the NMEA message so assign var = 1
   {var = 1;
   compassheadingstring ="";
   }
    if (var == 8)
     { 
    Serial.println(" ");
       Serial.print(aa); // send the eighth asci character to the serial monitor
       compassheadingstring = compassheadingstring.concat(aa);

    bb= mySerial.read(); // get the next byte of data
        Serial.print(bb);
        compassheadingstring = compassheadingstring.concat(bb);
   
    cc= mySerial.read(); // get the next byte of data
        Serial.print(cc);
        compassheadingstring = compassheadingstring.concat(cc);
       
    dd= mySerial.read(); // get the next byte of data
         Serial.print(dd);
        compassheadingstring = compassheadingstring.concat(dd);
         
    ee= mySerial.read(); // get the next byte of data
         Serial.print(ee);
        compassheadingstring = compassheadingstring.concat(ee);
       
    // heading = atof(compassheadingstring); //this doesn't work it won't convert my string to a float
       Serial.println();
     // error = (360 - compassheadingstring);  //my string isn't a number so this can't work.
      Serial.println(error);
      Serial.print(compassheadingstring);

      var=var+4;   
       }
// delay(1000);  // this delay was a problem, after a few iterations the signal went to 1 and $ -- very strange.
  var=var+1;
 
  }



DavidFoe

Solved!

Took a bit of searching but this approach worked for me:


Re: Converting string to numeric
Reply #1 - 17.01.2011 at 06:16:36    The simplified answer:
a) the String library is a class (object).   A class can contain member variables, constants, member functions, and overloaded operators. Its a c++ thing
b) atof expect an argument of type const char * str
c) to convert the string class to a const char * str

Code:
char buf[Weight.length()];
Weight.toCharArray(buf,Weight.length());
float WVal=atof(buf);





AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

DavidFoe

AWOL,

I am blissfully ignorant of the meaning of the words "software serial read blocking".  So I haven't a clue but the thing works and I am grateful to everyone who replied.  I would never have found the atof function without your hint.   I also have no idea why the string had to be recast using:

char buf[Weight.length()];
Weight.toCharArray(buf,Weight.length());
float WVal=atof(buf);

Thanks all.

WizenedEE


I am ignorant of the meaning of the words "software serial read blocking".

FTFY

software serial = a  serial connection on pins other than 0 and 1
read = a function that looks at what was sent over the serial
blocking = takes a lot of time; more specifically don't go on to the next function until some sort of external response is gotten (in this case, whether or not read() returns some value if nothing was received over the serial lines).

Broken down:
Is ((the (software serial) read()) blocking)?
"Does the read() function used by the software serial library wait until a character is received, or does it just give an "error" value?"

AWOL

The reason I asked if it was blocking is because if it is (and it is) the only thing that is allowing your sketch to work is the fact that you print every received character out, thus delaying your sketch long enough to allow the next character to be received.

Code: [Select]
if (mySerial.available())
This says "is there at least one character available in the receive buffer?"
And then you potentially read four of them.
You should always check to see if there is data available before reading; if you remove your debug prints, your sketch may stop working.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

DavidFoe

Thanks again!  I was wondering about that exact thing.  I'll definitely put in the if(myserial.available()) statements before each read.   Easy  bit  of clean-up.

David

Go Up