Using the new GPS_Logger Shield

I have a system comprised of a GPS/SD shield. This sits on an Ard Uno. This module sits in a race boat and logs the position and other data during a course run. This setup works fine. The file on the uSD card can be exported into Earthpoint and ultimately into Google Earth which shows the boats position and associated data at each point. Now I am using the same platform to measure distances based upon the current lat/lon data with respect to a starting point. My problem seems to be that I can't get high enough resolution to make these measurements for finer than a mile or 2. I declared all of the GPS data variables as floats. And its my understanding that for the Uno this means the data is 32 bits wide which seems that would be plenty of numerical resolution. The algorithm I've implemented is as follows: Distance in Miles Between Two Points = dist = acos(cos(lat_start_rad) * cos(lat_current_rad) + sin(lat_start_rad) * sin(lat_current_rad) * alpha))*3958.756 ; Where alpha = alpha = cos(lon_start_rad)*cos(lon_current_rad) + sin(lon_start_rad)*sin(lon_current_rad);

The alpha terms seems to be the one that gets truncated and causes the lack of resolution. The alpha equation is based upon the trig identity "cos(x-y) = cos(x)*cos(y) + sin(x)*son(y). Has anyone used the Uno successfully to measure distances? Thanks for any insights.

Everything you ever wanted to know and more.

You are also experiencing the accuracy loss at small distances (alpha, as you say). This wiki article mentions using the sine version of the formula to avoid the problem with cosines.

Resolution-wise, a float on the Arduino is only ~7 significant digits, so it's not great, but you can get about 1 meter resolution for the smallest change in lat/lon.

I've been working on an integer version of the Haversine for a bit, but I am also having trouble with that last term. 32-bit integers have 10 significant digits, which should be good to mm resolution. Until then, here's the C version of the floating-point formula I am using for comparison:

const float ToRad = PI / 180.0;
const float R = 6371.0088;   // radius earth in Km

static float distance( float lat1, float lon1, float lat2, float lon2 )
{
  // Haversine calculation from http://www.movable-type.co.uk/scripts/latlong.html

  lat1 *= ToRad;
  lat2 *= ToRad;
  float dLat = (lat2-lat1);
  float haverDLat = sin(dLat/2.0);
  haverDLat *= haverDLat; // squared
  
  float dLon = (lon2-lon1) * ToRad;
  float haverDLon = sin(dLon/2.0);
  haverDLon *= haverDLon; // squared
  
  float a = haverDLat + cos(lat1) * cos(lat2) * haverDLon;

  float c = 2 * atan2( sqrt(a), sqrt(1-a) );

  float d = R * c;

  return d;
}

Change the R to 3958.756 and it will be in miles, not km.

Cheers, /dev