Solved: coverting a concatenated string to float

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!


It's better if you post code, but you could try atof

float heading = atof(compassheadingstring);

For reference:

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):

#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=; // 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=; // get the next byte of data
        compassheadingstring = compassheadingstring.concat(bb);
    cc=; // get the next byte of data
        compassheadingstring = compassheadingstring.concat(cc);
    dd=; // get the next byte of data
        compassheadingstring = compassheadingstring.concat(dd);
    ee=; // get the next byte of data
        compassheadingstring = compassheadingstring.concat(ee);
    // heading = atof(compassheadingstring); //this doesn’t work it won’t convert my string to a float
    // error = (360 - compassheadingstring);  //my string isn’t a number so this can’t work.

// delay(1000);  // this delay was a problem, after a few iterations the signal went to 1 and $ – very strange.


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);

Is the software serial read blocking?


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.

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


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?"

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.

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.

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.