# Float Number not correct

I feel like I am always crying wolf but this platform does throw me for a loop every now and again. I am comparing floats to a threshold and for some reason I am getting an outrageously large number for the difference when the difference should be around .001.

I have four variables:

``````float gpsPrevLat = 0.0f;
float gpsPrevLon = 0.0f;
float gpsCurrLat = roundf(t.readLatDeg() * decimal)/decimal ;
float gpsCurrLon = roundf(t.readLonDeg() * decimal)/decimal ;
``````

I wanted to cut off the number to the fifth decimal point so thats the reason for the round.

I then compare these numbers every loop

``````    float latDiff = fabsf(gpsPrevLat - gpsCurrLat);
float lonDiff = fabsf(gpsPrevLon - gpsCurrLon);

Particle.publish("LoD", String(lonDiff), 60, PRIVATE);

if(latDiff > .001f || lonDiff > .001f){
Particle.publish("hM","true",60,PRIVATE);
return true;
}else{
Particle.publish("hM","false",60,PRIVATE);
return false;
}
``````

I then afterwards reset the previous variables to the current

gpsPrevLat = gpsCurrLat;
gpsPrevLon = gpsCurrLon;

This all makes sense to me. However when I reprint out the gpsPrevLat I get a crazy number

The output you see is the difference in Lon and Lat. The LaD is latitude difference and LoD is longitude difference.

How does your code behave when you pass in constants instead of `t.readLatDeg()`/`t.readLonDeg()`?

Checking all the sub-results (e.g. via `Serial.print()`) in your calculations might provide some insight where the problem starts.

BTW, since floating point variables are inherently unable to hold arbitrary numbers with full precision (even after â€śroundingâ€ť you may end up with more decimals than you expected) Iâ€™d just forget the rounding and only limit the way how you display the numebrs
Iâ€™d rather do it like this.

``````float gpsPrevLat = 0.0f;
float gpsPrevLon = 0.0f;
...
float latDiff = fabsf(gpsPrevLat - gpsCurrLat);
float lonDiff = fabsf(gpsPrevLon - gpsCurrLon);

//Particle.publish("LaD/LoD", String::format("%.5f / %.5f", latDiff, lonDiff), PRIVATE);
// but since I "despise" String I'd rather do
char data[32];
snprintf(data, sizeof(data), "%.5f / %.5f", latDiff, lonDiff);
``````
3 Likes

So when doing that I see that the issue is that gpsPrevLat is savings a really high number compared to the actual gpsCurrLat number it should be savings. So I know my issue is there but not how to solve it.

Also,
I tried that as well (not rounding) and it doesnt make a difference to my values either way. I am considering switching to doubles instead

Showing the rest of your code old help.
Maybe you got some buffer violation or pointer issues.

1 Like
``````    // This #include statement was automatically added by the Particle IDE.
#include <AssetTracker.h>

#include <math.h>

// Used to keep track of the last time we published data
long lastPublish = 0;

// How many minutes between publishes? 10+ recommended for long-time continuous publishing!
int delayMinutes = 2;

// Creating an AssetTracker named 't' for us to reference
AssetTracker t = AssetTracker();

int isMoving = 0;

//Device number
char did[9] = "58965412";

//variable to hold JSON data
char data[64];

float gpsPrevLat;
float gpsPrevLon;

int decimal = 100000;

// setup() and loop() are both required. setup() runs once when the device starts
// and is used for registering functions and variables and initializing things
void setup() {
// Sets up all the necessary AssetTracker bits
t.begin();

// Enable the GPS module. Defaults to off to save power.
// Takes 1.5s or so because of delays.
t.gpsOn();

gpsPrevLon = 0.0f;
gpsPrevLat = 0.0f;

// Opens up a Serial port so you can listen over USB
Serial.begin(9600);

Particle.function("gps", gpsPublish);
}

// loop() runs continuously
void loop() {

// You'll need to run this every loop to capture the GPS output
t.updateGPS();

// if the current time - the last time we published is greater than your set delay...
if (millis()-lastPublish > delayMinutes*60*1000) {
// Remember when we published
lastPublish = millis();
//Particle.publish("A", pubAccel, 60, PRIVATE);

// GPS requires a "fix" on the satellites to give good data,
// so we should only publish data if there's a fix
if (t.gpsFix()) {
float gpsCurrLat = roundf(t.readLatDeg() * decimal)/decimal ;
float gpsCurrLon = roundf(t.readLonDeg() * decimal)/decimal ;

bool IsMoved = hasMoved(gpsPrevLat, gpsPrevLon, gpsCurrLat, gpsCurrLon);

gpsPrevLat = gpsCurrLat;
gpsPrevLon = gpsCurrLon;
//creates a string in JSON structure
sprintf(data,"{\"did\": %s, \"gpsLat\": %e, \"gpsLon\": %e, \"isMoving\" : %d}",did,gpsCurrLat,gpsCurrLon,isMoving);
// Short publish names save data!
Particle.publish("Data", data, 60, PRIVATE);
//try webhook and check if it worked
Particle.publish("update_gps",data, 60, PRIVATE);

// Short publish names save data!

// but always report the data over serial for local development
}
}
}

// Actively ask for a GPS reading if you're impatient. Only publishes if there's
// a GPS fix, otherwise returns '0'
int gpsPublish(String command) {
if (t.gpsFix()) {

// uncomment next line if you want a manual publish to reset delay counter
// lastPublish = millis();
return 1;
} else {
return 0;
}
}

bool hasMoved(float gpsPrevLat, float gpsPrevLon, float gpsCurrLat, float gpsCurrLon){

float latDiff = fabsf(gpsPrevLat - gpsCurrLat);
float lonDiff = fabsf(gpsPrevLon - gpsCurrLon);

Particle.publish("LoD", String(lonDiff), 60, PRIVATE);

if(latDiff > .001f || lonDiff > .001f){
Particle.publish("hM","true",60,PRIVATE);
return true;
}else{
Particle.publish("hM","false",60,PRIVATE);
return false;
}
}
``````

The literals alone are already taking 49 (if I counted right ) of 63 characters, so there might be a possible problem.

To prevent buffer overflow rather go with `snprintf()`

``````snprintf(data, sizeof(data), "{\"did\": %s, \"gpsLat\": %e, \"gpsLon\": %e, \"isMoving\" : %d}",did,gpsCurrLat,gpsCurrLon,isMoving);
``````

Doing that change made my Webhook no longer work. Also it had no change to the difference in my latitude or longitude

So I ran the code last night and got outrageous numbers. Now when I run the code everything works fine and the distance is correct.

OK? I canâ€™t quite understand what the combined essence of these last two posts would be?

What change made the webhook stop?
What change made the difference come out correct?
Whatâ€™s still open now?

BTW, if the `snprintf()` change killed the webhook but cured the calculation itâ€™s a reliable indicator that your `char data[64]` is too small for your string

Looks like I got it wrong. the snprintf cured my calculation and it calls my webhook but my API attached to the webhook is not accepting it. Checking the logs to see what that is but may just increase the size of â€śdataâ€ť.

Can someone explain why snprintf cured my calculation? Iâ€™m more Java than C so the buffer and pointers are a tad difference, as in they exist heavily compared to Java.

The most probable reason is that your string was too long to fit into `char[64]` but `sprintf()` doesnâ€™t care about that and will probably have put the overhang into adjacent memory where your floats lived - consequently corrupting the contents of these floats.
And with `snprintf()` your backend wonâ€™t accept the string since now itâ€™s not a properly terminated string anymore (thatâ€™s what happens with a string in `snprintf()` that wonâ€™t fit) but will contain â€śrandomâ€ť bytes (whatever follows in RAM up to the first 0x00 byte).

BTW, if you had assigned the floats after `sprintf()` and the publish instruction, you would probably not have noticed the issue.

the function

``````snprintf(myBuffer, sizeof(myBuffer), ...)
``````

prevents inadvertantly writing past the the end of `myBuffer` which may cause the corruption of some other data

`sprintf` has no such safety mechanismâ€¦

1 Like

Ok so now that my webhook is not being called. So If I change it back to sprintf but increase the buffer size it should work fine?

Nope, just increase the buffer and never go back to `sprintf()` unless you want to plant yourself some time bombs

So I increased the buffer size however it is still not calling the webhook

`Particle.publish("update_gps",data, 60, PRIVATE);`

``````// This #include statement was automatically added by the Particle IDE.
#include <AssetTracker.h>

#include <math.h>

// How many minutes between publishes? 10+ recommended for long-time continuous publishing!
int delayMinutes = 2;

// Used to keep track of the last time we published data
long lastPublish = 0;

// Creating an AssetTracker named 't' for us to reference
AssetTracker t = AssetTracker();

int isMoving = 0;

//Device number
char did[9] = "58965412";

float gpsPrevLat;
float gpsPrevLon;

int decimal = 100000;

// setup() and loop() are both required. setup() runs once when the device starts
// and is used for registering functions and variables and initializing things
void setup() {
// Sets up all the necessary AssetTracker bits
t.begin();

// Enable the GPS module. Defaults to off to save power.
// Takes 1.5s or so because of delays.
t.gpsOn();

gpsPrevLon = 0.0f;
gpsPrevLat = 0.0f;

// Opens up a Serial port so you can listen over USB
Serial.begin(9600);

Particle.function("gps", gpsPublish);
}

// loop() runs continuously
void loop() {

//variable to hold JSON data
char data[90];

// You'll need to run this every loop to capture the GPS output
t.updateGPS();

// if the current time - the last time we published is greater than your set delay...
if (millis()-lastPublish > delayMinutes*60*1000) {
// Remember when we published
lastPublish = millis();
//Particle.publish("A", pubAccel, 60, PRIVATE);

// GPS requires a "fix" on the satellites to give good data,
// so we should only publish data if there's a fix
if (t.gpsFix()) {
float gpsCurrLat = roundf(t.readLatDeg() * decimal)/decimal ;
float gpsCurrLon = roundf(t.readLonDeg() * decimal)/decimal ;

bool isMoved = hasMoved(gpsPrevLat, gpsPrevLon, gpsCurrLat, gpsCurrLon);

if(isMoved){
gpsPrevLat = gpsCurrLat;
gpsPrevLon = gpsCurrLon;
//creates a string in JSON structure
snprintf(data,sizeof(data), "{\"did\": %s, \"gpsLat\": %e, \"gpsLon\": %e, \"isMoving\" : %d}",did,gpsCurrLat,gpsCurrLon,isMoving);
// Short publish names save data!
Particle.publish("Data", data, 60, PRIVATE);
//try webhook and check if it worked
Particle.publish("update_gps",data, 60, PRIVATE);
}
// Short publish names save data!

// but always report the data over serial for local development
}
}
}

// Actively ask for a GPS reading if you're impatient. Only publishes if there's
// a GPS fix, otherwise returns '0'
int gpsPublish(String command) {
if (t.gpsFix()) {

// uncomment next line if you want a manual publish to reset delay counter
// lastPublish = millis();
return 1;
} else {
return 0;
}
}

bool hasMoved(float gpsPrevLat, float gpsPrevLon, float gpsCurrLat, float gpsCurrLon){

float latDiff = fabsf(gpsPrevLat - gpsCurrLat);
float lonDiff = fabsf(gpsPrevLon - gpsCurrLon);

Particle.publish("LoD", String(lonDiff), 60, PRIVATE);

if(latDiff > .001f || lonDiff > .001f){
Particle.publish("hM","true",60,PRIVATE);
return true;
}else{
Particle.publish("hM","false",60,PRIVATE);
return false;
}

}``````

When i pulled the the data variable in the loop method it begin to make the webhook call.

I am going to go read about buffers. Thanks for the help!

If you can post the contents of `data` and the full output of the console for the webhook call we might be able to see whatâ€™s wrong.

You also got numerous publishes that might actually violate the rate limit of 1/sec with a burst of max. 4 with 4sec cooldown.

On movement you have 3 publishes in `hasMoved()` followed by 1 `"Data"` and hence the fifth `"update_gps"` will be blocked. So this doesnâ€™t relate to your buffers at all.

1 Like