Parsing Serial.read() strings into floating numbers

I have an IMU that sends out data in this format: !(+-)xxx.xx,(+-)xxx.xx,(+-)xxx.xx

Or, in English: An exclamation mark, then either a positive or negative number which can have from 1 to 3 digits before the period, and 2 digits after, then a comma, and then the same for the 2nd and 3rd part of the string.

I've tried parsing this output used strtok_r, which just gives me garbage, and manual whiles, ifs and thens, to no avail. I always end up with random ascii characters or 0's. Can anyone point me to a function or library that can help me out?

Here's what the latest that I've tried, all it returns is !>,>,> :

void loop() {
  int i = 0;
  while(Serial.available() > 0)
   {
    char aChar = Serial.read();
    if(aChar == '\n')
    {
           char *p = inData; //assign the string to *p
       char *str;    //intialize str
       while ((str = strtok_r(p, ",", &p)) != "\n")
            {
               Serial.println(str);
               p = NULL;
            }
       i = 0;
       //inData[] = NULL;
    }
    else
    {
       inData[i] = aChar;
       i++;
       inData[i] = '\0'; // Keep the string NULL terminated
    }
   }
}

read the character and build a string until a separator (\n) and then use sscanf(string, "%f", &yourfloat); other option is to parse it yourself while reading the float

(code not tested or compiled)

char buffer[12] ;
int idx = 0;
boolean stringComplete = false;
boolean 

void loop() 
{
  // collect chars;
  while (false == stringComplete)
  {
    if (Serial.available() > 0)
    {
      char a= Serial.read();
      if('\n'== a) 
      {
        stringComplete = true;
        buffer[idx++] = '\0';
        idx = 0;
      }
      buffer[idx++] = a;
    }
  }
  // float is now in buffer
  sscanf(buffer, "%f", &f);
  Serial.println(f);
  // process it.
}

On my Arduino Mega, I'm reading from Serial1 and sending the data to Serial for debugging. Here is my main loop:

char buffer[32] ;
int idx = 0;
boolean stringComplete = false;
float f = 000.00;

while (false == stringComplete)
  {
    if (Serial1.available() > 0)
    {
      char a= Serial1.read();
      if('\n'== a) 
      {
        stringComplete = true;
        buffer[idx++] = '\0';
        idx = 0;
      }
      buffer[idx++] = a;
    }
  }
  stringComplete = false;
  
  sscanf(buffer, "%f", &f);
  Serial.println(f);

The result is just 0.00 over and over again. I printed out the buffer right before the sscanf and it was fine.

strange..

try f = atof(buffer);

Support for floating point data on the Arduino is very limited. The sprintf function does not support the %f type, either.

You could do something like this: char s1[10]; char s2[10]; sscanf(buffer, "%s.%s", s1, s2);

This would out the part before the decimal point in s1, and the part after the decimal point in s2.

Then, convert s1 to integer i1, using atoi(). Then, convert s2 to integer i2, using atoi().

Then, set f to i2. While f is greater than 1, divide by 10. Then, add i1.