decimal places ....

hey guys

today i have been trying to get arduino to start a number that has lots of small numbers such as 87.0000001
i have tried to use long var 87.0000001F but it only prints out 87.00 on the serial

i would multiply this out to a bigger number if i could but i cannot do that
as i need to number to send of the serial in the form of 00.0000000

testing code:

float longCoord = 87.0000001F;

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println(longCoord);
delay(500);
}

thanks for your help in advance

int yourDesiredPrecision = 4;
Serial.println(longCoord, yourDesiredPrecisionInt);

Don't expect too much of a 32 bit float.

Evoium:
today i have been trying to get arduino to start a number that has lots of small numbers such as 87.0000001
i have tried to use long var 87.0000001F but it only prints out 87.00 on the serial

Serial prints much more digits if you print it like that:

Serial.println(floatNum,12);

Unfortunately 'float' is only accurate to 6-7 significant digits.

For your accuracy you'd need int64_t to keep all digits accurate.

Then you could assign something like "int64_t myNumber=870000001;"
And then you'd need to create your own output routine, faking a decimal point in between the printout "as if" this was a float number.

Don't you think you are overegging the pudding with accurateness?

well i would use less accracy if i could but i cant cause im using a gps unit. and i need to be able to change the coordinates with small amounts such as 0.0000001

i need to be able to change the coordinates with small amounts such as 0.0000001

Just out of interest, what sort of distance change does that represent ?

I'm not a 100 percent sure about this but I think that 0.0000001 is about 100mm?

I'll test it for you tomo once I set it all up again

GPS accurate to 100mm ?

well of course it cant be that accurate but it is returning values from a 100mm movement so ill need to check how reliable it is. and if indeed can be accurate to that size

Evoium:
I'm not a 100 percent sure about this but I think that 0.0000001 is about 100mm?

Not really.

Latitude degrees (and longitude degrees at the equator) are about 111 km per degree.

So 111 km * 0.0000001 = 0,0000111 km = 0,0111 m = 11,1 mm

Eleven millimeters!

But if the need is for GPS latitude/longitude values, you could store numbers with 9 to 10 signifikant digits in 'long' values.

So a longitude of -180.0000000 to +180.0000000 degrees could be stored precisely in a long of:
-180.0000000 float ==> -1800000000 long
+180.0000000 float ==> 1800000000 long

So every possible GPS coordinate could be stored in a 'long' that accurate.

But in that case you cannot use a "GPS" library which provides the values as 'float' and then convert them back. After conversion to 'float' in your GPS library, the precision is lost and you cannot get it back. You'd have to write your own NMEA parsing routine that receives the data from the GPS receiver.

The second thing is: You cannot use float math then to calculate things like distance and bearing from one point to another. So if you want to get precision calculations for distance and bearing between two GPS coordinates, you would have to create your own formulas to do so from the stored 'long' value format. Your formulas will have to use a suitable algorithm (Phytagoras theorem) and mixed float/long math for very short distance calculations with a precision of about 11 millimeters.

it is returning values from a 100mm movement so ill need to check how reliable it is. and if indeed can be accurate to that size

If you observe for a while, a GPS module will return changing values even if there is no movement.
The reported "position" will wander around, up to a few meters from a center point, but occasionally much further.

What library are you using to interface with the GPS unit?

I might be able to come up with some kind of math trick to help you.

thanks for all the posts

so the newest issue is that the arduino will not add up the values correctly from the format that i have been able to achieve. so if you run this code the first column is the smaller numbers of the coordinates (for example 0.000001), the second is the whole numbers of the coordinates (such as 87.5), and finally the last column is that total added amount.

so the issue is that when the arduino adds these values together its like the serial prints out the same result 4 beacuse its not reading the new values but then again im not entirly sure where this issue is.

code below -----

int accuracy = 6;
float LongCoord = 87.500000F;
float LongCoordData;
float LongCoordWhole;
float LongCoordResult;

void setup() {
Serial.begin(9600);
LongCoordData = ((float)LongCoord / (float)LongCoord );
LongCoordData = ((float)LongCoordData - 1);
LongCoordWhole = ((float)LongCoord / 1);
}

void loop() {
delay(200);
LongCoordData = ((float)LongCoordData + 0.000001);
LongCoordResult = (LongCoordWhole + LongCoordData );
Serial.print(LongCoordData, accuracy);
Serial.print(" ");
Serial.print(LongCoordWhole, accuracy);
Serial.print(" ");
Serial.print(LongCoordResult, accuracy);
Serial.println(" ");
}

jurs -

thank you for that information i didnt know it could possibly be that accurate cause thats amazing.
For this drone project of mine i am using the tinygps library cause its quite easy to use (first time using a gps unit) but if i cannot do what i needed then i will look into other libraries. the manufactorer suggested this library for the unit i have which is a skm53 from skylabs

i was thinking about using the gyro to get the angle of what the drone is on as well as using the accelerometer to find the acceration then double the second intergral to find the distance. but im open to suggestions the only issue is that i cannot use two gps points like you have suggested but that would work really well.

jremington -
i read about the wondering values from the gps unit and im not really sure of how to fix that besides resetting and getting new ref points for then i start the drone

odometer -
so i have actually somewhat gotten past this problem but you know how it is as soon as the first problem is fixed another problem pops up. The new issue is that the arduino wont add the values up correctly as explained above

and again THANK YOU ALL for the input and help i really appreciate it

What you have makes no sense whatsoever....

This:

LongCoordData = ((float)LongCoord / (float)LongCoord );

will always set LongCoordData to something extremely close to 1.0, or an error, if Long CoordData is initially 0.

This:

LongCoordData = ((float)LongCoordData - 1);

will then set LongCoordData to something extremely close to 0

This:

LongCoordWhole = ((float)LongCoord / 1);

does essentially nothing, since you're dividing by 1.

What on earth are you trying to accomplish here?? This is just gibberish.

Regards,
Ray L.

Always treat floating point values (float and double) as approximations. There's a limit to their accuracy. If you want your results to be accurate, then store integer (or long) values that are multiples of your smallest unit.

This applies to anything that needs to be accurate, such as currency and time.

What version of the TinyGPS library are you using? Where did you download it from?
You might want to upgrade to the latest version if you haven't already.

Evoium:
code below -----

int accuracy = 6;

What happened to your desired accuracy? From 7 digits after the decimal place (= 9 significant digits total) down to 6 digits?

Your code is a mess.

If you want to see the inaccuracy of float, I have prepared this demonstration code for you:

int accuracy = 7;
float units=0.0000001;
long LongCoord= 875000000;

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(200);  
  LongCoord   = LongCoord + 1;
  Serial.print(LongCoord); // print with 'long' accuracy
  Serial.print('\t');
  Serial.print(LongCoord*units, accuracy); // print with 'float' accuracy
  Serial.print('\t');
  long CoordDifferenceLong= LongCoord-875000000;
  Serial.print(CoordDifferenceLong); // in 'long'
  Serial.print('\t');
  Serial.print(CoordDifferenceLong*units,accuracy); // calculated in 'long', finally converted to 'float'
  Serial.print('\t');
  float CoordDifferenceFloat= LongCoord*units - 87.5000000;
  Serial.println(CoordDifferenceFloat,accuracy); // calculated in 'float'
}

In the first and second column of printed output you see:
While the last digit of your LongCoord goes up exactly by 1 in each loop, as soon as you use a 'float' calculated from that, the precision in the last digit or sometimes even two digits is lost.

In the third column you see the difference to the initial coordinate, calculated 'long'.

In the 4th column you see the same difference, converted to a float.
==> difference of coordinates in float is correct then.

And finally in the 5th column you see what happens if each calculation is done in 'float' only: Very small differences between coordinates are not calculated accurately.

But as you keep the coordinates accurate storing them in 'long', then doing the difference in 'long' math and finally converting to a difference in float, the difference is accurate (up to 6-7 significant digits).

sorry if my code doesnt make sense, this way seems to be the only way i could get the arduio unit adding small numbers together correctly. im still open to way to remake this because even i dont like this. all this code needs to do is return the results in 3 columns in the serial monitor.

these lines below take the ref point say 12.345678 = LongCoord

this line devides the given coordinates with itself to return one
LongCoordData = ((float)LongCoord / (float)LongCoord );

this line removes the 1 so that only the 0.345678 remains
LongCoordData = ((float)LongCoordData - 1);

this line takes the ref point and returns the value of the whole numbers such as 12
LongCoordWhole = ((float)LongCoord / 1);

when all these get added together we get the same result as the ref point however the arduino added it correctly. when i use another way it was not returning accrate results it would be out with 0.0003

PaulMurrayCbr -
what would be the best way to store these like you suggested? because these values will be changing lots

odometer -
i think it is tinygps v13 ill look for a update when i get home. the library is from their website

thanks all :slight_smile:

jremington -
i read about the wondering values from the gps unit and im not really sure of how to fix that besides resetting and getting new ref points for then i start the drone

You mean "wandering". There is nothing you can do about that. GPS measurements with consumer grade devices are at best dependable to +/- 3 meters, and the accuracy varies from OK to useless, depending on the number of satellites in view, obstructions of the clear sky, presence of nearby reflecting walls, etc.

The type of calculations you are attempting actually worsen the problem by increasing the errors.

Hi,
I echo jremington on this, I have that skylabs GPS and have tried other units and you will not get rid of the jitter or improve the accuracy with magic maths.

The units that are used by farmers and people needing higher accuracy, have access to a FIXED terrestrial GPS, that is within range, that acts as a master reference.

I have serviced a number of these units, and in the agricultural world usually a group of land owners buy a unit and place it central to their location.

The examples that come with TinyGPS++ are excellent, if you study them you will see that the most has been pulled from the information available with the software available.

Tom... :slight_smile: