# Float into char array GPS-Help

Dear community,I have the following problem in my system (I am using the arduino micro):

The idea basically consists in sendig a text message with the latitude and longitude of our current location. For doing this, I have a function which calculates your latitude and longitude and store the results in two floating variables:

float latitude
float longitude

I also have the function which sends the text message but the content obviously must be a char array.

Then, my purpose is to convert the previous floats into char arrays and build automatically a char array variable with the following format:

message sended-> Latitude:47.2035 ; Longitude: 15.3268

Searching this problem I've found the dtostrf function,and the first step which is to convert the floats in char arrays seems to be solved:

//with this code the program prints the latitude and longitude as a char array
dtostrf(latitude,10,7,char_array_1);
Serial.println(char_array_1); //Prints 47.2035
dtostrf(longitude,10,7,char_array_2);
Serial.println(char_array_2); //Prints 15.3268

//Just changing the order in the lines, the program does not works:

dtostrf(latitude,10,7,char_array_1);
dtostrf(longitude,10,7,char_rray_2);
Serial.println(char_array_1); //Prints an incorrect value 15.846
Serial.println(char_array_2);

Ok, let's assume that we have both coordenates stored with the function dtostrf, the problem I have is in the step of build the final message, since we already have the coordenates in char arrays we only have to create a biggest one:

char text1 = " Latitude:";
char text2 = " Longitude:";
char colon = ";".

// Idea -> message = "Latitude:" + char_array_1 + ";" + "Longitude:" + char_array_2

I have tried to do this with the strcat function and when I put the println commands only to check what the program does, both values (which I converted previously,char_array_1,char_array2) have never appeared,so I am not able to send the location message correctly.

I am not sure if I should use another function instead of dtostrf,or in the case that it is correct, how can I build the final message?? Do you have any idea?

I tried to explain it in the best way.

This puts it together OK to 4 decimal places:-

``````void setup()
{
Serial.begin(115200);
char latBuffer[20];
char longBuffer[20];
char fullBuffer[100];

float latitude = 47.2035;
float longitude = 15.3268;
dtostrf(latitude, 0, 4, latBuffer);
dtostrf(longitude, 0, 4, longBuffer);
sprintf_P(fullBuffer, PSTR("Latitude: %s;Longitude: %s"), latBuffer, longBuffer);
Serial.println(fullBuffer);    // Prints: "Latitude: 47.2035;Longitude: 15.3268"
}

void loop(){}
``````

but if 7 places are stipulated, the result for latitude is 47.2034990.

OldSteve:
This puts it together OK to 4 decimal places:-

``````void setup()
``````

{
Serial.begin(115200);
char latBuffer[20];
char longBuffer[20];
char fullBuffer[100];

float latitude = 47.2035;
float longitude = 15.3268;
dtostrf(latitude, 0, 4, latBuffer);
dtostrf(longitude, 0, 4, longBuffer);
sprintf_P(fullBuffer, PSTR("Latitude: %s;Longitude: %s"), latBuffer, longBuffer);
Serial.println(fullBuffer);    // Prints: "Latitude: 47.2035;Longitude: 15.3268"
}

void loop(){}

``````

but if 7 places are stipulated, the result for latitude is 47.2034990.
``````

First of all thanks for your time, unfortunately until next monday I can not prove it, can you explain me the reason of the 0 in the dtostrf function and briefly the use of sprintf_P, I tried to use sprintf but I am still having doubts about how to use it that function.
Thanks again

ianerito:
First of all thanks for your time, unfortunately until next monday I can not prove it, can you explain me the reason of the 0 in the dtostrf function

The second parameter to dtostrf, (0), is the minimum width. If that parameter is larger than the actual length of the string that's produced, (including the decimal point), the string is padded out with leading spaces.
This illustrates what I mean:-

``````void setup()
{
//  dtostrf(val, width, precision, buffer);

Serial.begin(115200);
double dVal = 123.4567;
char buffer[10];

dtostrf(dVal, 0, 3, buffer);  // Prints "123.457"
Serial.println(buffer);

dtostrf(dVal, 6, 2, buffer);  // Prints "123.46"
Serial.println(buffer);

dtostrf(dVal, 7, 2, buffer);  // Prints " 123.46"
Serial.println(buffer);
}

void loop(){}
``````

and briefly the use of sprintf_P, I tried to use sprintf but I am still having doubts about how to use it that function.
Thanks again

'sprintf_P()' stores the format string, ("Latitude: %s;Longitude: %s"), in program memory, rather than in RAM, conserving RAM storage space.

It's similar to using the F() macro for string literals:-

``````Serial.println(F("some string"));  // "some string" is stored in program memory, not RAM.
``````

OldSteve:
The second parameter to dtostrf, (0), is the minimum width. If that parameter is larger than the actual length of the string that’s produced, (including the decimal point), the string is padded out with leading spaces.
This illustrates what I mean:-

``````void setup()
``````

{
//  dtostrf(val, width, precision, buffer);

Serial.begin(115200);
double dVal = 123.4567;
char buffer[10];

dtostrf(dVal, 0, 3, buffer);  // Prints “123.457”
Serial.println(buffer);

dtostrf(dVal, 6, 2, buffer);  // Prints “123.46”
Serial.println(buffer);

dtostrf(dVal, 7, 2, buffer);  // Prints " 123.46"
Serial.println(buffer);
}

void loop(){}

``````

'sprintf_P()' stores the format string, ("Latitude: %s;Longitude: %s"), in program memory, rather than in RAM, conserving RAM storage space.

It's similar to using the F() macro for string literals:-

``````

Serial.println(F(“some string”));  // “some string” is stored in program memory, not RAM.

Thank you very much, now is all clear, I am sure that it will work.

OldSteve:
The second parameter to dtostrf, (0), is the minimum width. If that parameter is larger than the actual length of the string that's produced, (including the decimal point), the string is padded out with leading spaces.
This illustrates what I mean:-

``````void setup()
``````

{
//  dtostrf(val, width, precision, buffer);

Serial.begin(115200);
double dVal = 123.4567;
char buffer[10];

dtostrf(dVal, 0, 3, buffer);  // Prints "123.457"
Serial.println(buffer);

dtostrf(dVal, 6, 2, buffer);  // Prints "123.46"
Serial.println(buffer);

dtostrf(dVal, 7, 2, buffer);  // Prints " 123.46"
Serial.println(buffer);
}

void loop(){}

``````

'sprintf_P()' stores the format string, ("Latitude: %s;Longitude: %s"), in program memory, rather than in RAM, conserving RAM storage space.

It's similar to using the F() macro for string literals:-

``````

Serial.println(F("some string"));  // "some string" is stored in program memory, not RAM.

Dear Steve, I have changed my board from Micro to Arduino 101 with the Curie Core, and now, the dtostrf or sprintf function give me a serial representation whith strange symbols and incorrect values, dou you know something about that?
Thanks

ianerito:
Dear Steve, I have changed my board from Micro to Arduino 101 with the Curie Core, and now, the dtostrf or sprintf function give me a serial representation whith strange symbols and incorrect values, dou you know something about that?
Thanks

No, I don't. I would have thought that those functions would work the same with the 101, but maybe not. I don't have one to test. I assume that you're testing the exact same code?

OldSteve:
No, I don’t. I would have thought that those functions would work the same with the 101, but maybe not. I don’t have one to test. I assume that you’re testing the exact same code?

Yes, but due to a lot of problems with the borad 101 I changed other time my board, and now I am testing the same code with the Arduino Uno (which, in theory works equal to the first board that I used, the Arduino micro).
Your code worked perfectly with the arduino micro, but now, with the arduino uno:

Code:

char latBuffer[10];
char longBuffer[10];
dtostrf(latitude, 0, 8, latBuffer);
Serial.println(latBuffer);
dtostrf(longitude, 0, 8, longBuffer);
Serial.println(longBuffer);

And the output is:

34.02172900
6.65468550

It is a little bit strange, because as I told you, your code worked perfectly with the first board.

Ok, sometimes it works, I think I am having estability problems because my sketch uses almost all the memory

`````` dtostrf(latitude, 0, 8, latBuffer);
``````

Using a field width of 0, print the whole number, a decimal point, 8 digits after the decimal point, and a terminating NULL. How is all that data supposed to fit in a 0 character field?

Since the 0 is a minimum, and the function is (obviously) smarter than you, the 0 will be ignored. However, 8 digits after the decimal point, the decimal point, and the NULL are 10 characters. There is no room, then, for the whole number.

34.02172900

with the terminating NULL, that is 12 characters, and you just shit on memory you don't own.

Once you have done that, any expectation that code that follows will behave consistently is nothing but wishful thinking.

PaulS:

`````` dtostrf(latitude, 0, 8, latBuffer);
``````

Using a field width of 0, print the whole number, a decimal point, 8 digits after the decimal point, and a terminating NULL. How is all that data supposed to fit in a 0 character field?

The minimum width isn't the size of the buffer and setting it to zero does not declare a 0 character field at all. (It's the minimum, not the maximum.) It only determines whether or not the result will be padded with leading spaces. ie If the width is set to 8, and there are 7 chars including the decimal point, then there will be a leading space. See reply #3 for the results of my tests.

It is true, though, that his buffers aren't large enough for the resultant strings with 8 digits after the decimal point. The example I showed had a 10 char buffer but only a maximum of 3 digits to the right of the decimal point.

The minimum width isn't the size of the buffer and setting it to zero does not declare a 0 character field at all. (It's the minimum, not the maximum.)

I know that, but I also know that one looks like a doofus specifying a minimum field width that is less than the number of characters after the decimal point.

PaulS:
I know that, but I also know that one looks like a doofus specifying a minimum field width that is less than the number of characters after the decimal point.

That's not true at all, and there's definitely no justificaton for calling people 'stupid' or 'doofus'.
If no padding is needed, to right-justify or whatever, there's absolutely no reason why the minimum width shouldn't be set at 0. It doesn't have to be a value above zero unless a minimum width needs to be stipulated.

hi, can help me to make code for gps ,for distance when the gps movement ???