problem dtostrf() to convert float-string with 8 precision

Hi...

I have problem with using dtostrf(). This function to convert float coordinate of GPS to string with 8 precision of float. here the code

LAT =-7.27658351;
LON =112.23678951;
dtostrf(LAT, 4, 8, lati);
dtostrf(LON, 4, 8, longi);

when i ran the program, the appeared string was

Latitude : -7.27658370 :: Longitude : 112.23679000

how to convert it with 8 precision of float?

i hope it solved..

thankss :slight_smile:

Arduino UNO has only 6-7 significant digits, check the IEEE754 32bit float specification for why.

Have a look at my Angle class that helps to keep accuracy, you can find the class and some discussion here - Angle library - Libraries - Arduino Forum

How do you expect to get 8 places after the decimal point when the total field width is 4 characters?

How are lati and longi defined? What does the i mean?

metropoles:
I have problem with using dtostrf(). This function to convert float coordinate of GPS to string with 8 precision of float. here the code

when i ran the program, the appeared string was

how to convert it with 8 precision of float?

i hope it solved..

You cannot get that precision from a 'float' variable which is only accurate up to 6-7 digits (digits before and after the decimal point together).

If you need higher precision, you need to deal with different data types.
For avoiding inaccuracy: DO NOT DEAL WITH FLOAT, but use integer data types only!

For example if you get your data from GPS NMEA sentences, you could store the whole degrees in an integer and the fraction of one degree in a "long" variable which represents units of 0.00000001 degrees.

Demo code for storing and printing such variables with an accuracy "whole degrees and 8 digits after the decimal point":

struct degree_t {int deg; unsigned long fraction;};

degree_t LAT = {-7, 27658351UL};
degree_t LON = {112, 23678951UL};


void printDegree(Print &device, degree_t value); // function prototype needed here for some older IDE versions
void printDegree(Print &device, degree_t value)
{
  char buf[15];
  snprintf(buf,sizeof(buf),"%d.%08lu", value.deg, value.fraction);
  device.print(buf);
}

void setup() {
  Serial.begin(9600);
  printDegree(Serial, LAT);
  Serial.println();
  printDegree(Serial, LON);
}

void loop() {
  // put your main code here, to run repeatedly:

}

PaulS:
How do you expect to get 8 places after the decimal point when the total field width is 4 characters?

It is minimum width, not total/maximum.

Floats are generally precise to under meter, which considering GPS is only good to 3 meters at least, most people can live with that. If you're on an AVR and need better precision than floats can offer, then you're stuck with integer only math. On ARM chips you could step it up to double, but double is really slow. Even if you had an FPU, all micro-controllers with FPUs that I know of only have single precision and don't give any performance gains at all to doubles. So, unless you need really great precision or floating points math is too slow, floats are fine and you mightn't need to worry about the lack of precision to 8 decimal places.

It is minimum width, not total/maximum.

Does it make sense to specify a minimum with that is less than the number of decimal places wanted?