Search code examples
floating-pointarduinoatof

atof() returns 3 digit number into 2 digits


I am trying to parse a string sent to my arduino uno using serial communication into a float. I want to use these floats to set an RGB LED's color. My issue is, it will only read the first 2 digits. Sorta. Say I entered 100. It will only come out to 10.00. If it's 231, it will come out to 23.00. The weird thing is, if I put 32.43, it will come out 32.4300. I have no idea why it does this. Here is my code:

float led1Color[3];

...

for (int i = 0; i < 3; i++) {
    int index = content.indexOf(",");
    content = content.substring(index + 1); //removes additional text in front of numbers
    led1Color[i] = atof(content.substring(0, index).c_str());
    Serial.println(led1Color[i], 4);
}

Now lets say I sent the following: "RGBLED,43.61,52,231". First, the RGBLED is removed. Then, the 3 values the console shows me are as followed:

43.6100 52.0000 23.0000

Obviously the issue here is I need the value 231, not 23.0000. I've never actually programmed in C/C++ before, so is there something I'm missing? Why is a three digit number being converted into a two digit number?


Solution

  • Your error is the value of index. This finds the first comma correctly

    int index = content.indexOf(",");
    

    But this second substring uses the same value of index from the previous find:

    ... content.substring(0, index).c_str()  // ERROR - index is the last value
    

    So when the string is reduced to:

    content -> "52,231"
    

    index returns 2

    Then you chop of to the comma and have

    content -> "231"
    

    The code takes 2 characters from that which gives you 23.

    If you change the input to

    "RGBLED,43.61,5,231"
    

    You would get "2" for the last atof.

    If you change the input to

    "RGBLED,43.61,52.,231"
    

    You would get "231" for the last atof.

    The approach you take of reducing the string is not necessary. indexOf takes a second parameter that can specify the starting point.

    This code is on your way to a better solution because you don't use memory to keep re-assigning the content string -- it just finds the commas and processes the sections:

    index1 = content.indexOf(",");
    index2 = content.indexOf("," , index1+1);
    index3 = content.indexOf("," , index2+1);
    
    led1Color[0] = atof(content.substring(index1+1, index2).c_str());
    led1Color[1] = atof(content.substring(index2+1, index3).c_str());
    led1Color[2] = atof(content.substring(index3+1).c_str());