Understanding Adafruit GPS location data 15

This tutorial strictly looks at understanding the latitude and longitude coordinates that are output by the Adafruit 66 Channel MTK3339 GPS Breakout Board V3. There is a good GPS tutorial offered by Adafruit to get you connected and up and running to the stage we can start talking about output processing.

The Adafruit GPS location output

Once your GPS unit has satellite lock you are able to request your location using the GPS.latitude &  GPS.longitude values from the Adafruit GPS library. These will return an output similar to the following (obviously quite different if you are located elsewhere than Luxembourg):

printf(GPS.latitude);
4939.4150

printf(GPS.longitude);
556.8587

If you are familiar with latitude and longitude (lat/long) coordinates you will know they are in the ranges -90 to 90 and -180 t0 180 respectively. So seeing the values in the example above sets off all sorts of alarms that something is wrong. Coordinates locate points on the earth. Typically locations are measured in degree-minutes-seconds of the aforementioned ranges, with minutes and seconds being of the range 0-59. This means that near the equator 1 arc-second equals about 31 metres. We can use decimal seconds for more accuracy. We are going to fix this before we can determine the accuracy of our GPS device.

Latitude & Longitude

Keep in mind that distance between lines of parallel, such as the Equator, tropic of Cancer and Capricorn, keep their degree – distance relationship constant (ignoring that the world isn’t a perfect sphere). The measure used to indicate the distance north or south of the equator is Latitude. As we move from the 49th parallel to the 50th, or a one degree latitude change anywhere on Earth, will always be approximately equal to 111 kilometres. Meridians, lines touching the North and South Poles, are not parallel in the geometric sense. They meet at both poles. Clearly the distance apart of two meridians changes depending on Latitude. At the equator a distance of one degree east or west will again be about 111 kilometres. At the 50th parallel which cuts through Northern Luxembourg, travelling east from the 6th to the 7th meridian will be 71 kilometres. To measure locations relative from the prime meridian, near Greenwich England, we use Longitude. This is a little bit off topic but something to keep in mind depending what you decide to do with your data, such as measure distances.

Understanding the output

The Adafruit GPS library gives lat/long in degrees and decimal minutes. Additionally the degrees and minutes are concatenated. Typically if you wish to use your data you want it in decimal degree format. This is the format used for most GIS programs and web mapping services such as Google Maps.

Parsing and transforming

We wrote a little function to clean the lat or long into correctly formatted decimal-degree double. We hope it’s helpful.

//required for fmod()
#include <math.h>;

// converts lat/long from Adafruit
// degree-minute format to decimal-degrees
double convertDegMinToDecDeg (float degMin) {
  double min = 0.0;
  double decDeg = 0.0;

  //get the minutes, fmod() requires double
  min = fmod((double)degMin, 100.0);

  //rebuild coordinates in decimal degrees
  degMin = (int) ( degMin / 100 );
  decDeg = degMin + ( min / 60 );

  return decDeg;
}

Conclusion

Using our code to clean up the original data we now get some familiar coordinates that we can directly input into Google Maps to check our receiving accuracy.

//Latitude
printf(GPS.latitude);
4939.4150
printf(convertDegMinToDecDeg(GPS.latitude));
49.656917

//Longitude
printf(GPS.longitude);
556.8587
printf(convertDegMinToDecDeg(GPS.longitude));
5.914312

This functions for all values -180 to 180.

15 thoughts on “Understanding Adafruit GPS location data

  1. Reply M.Talha Feb 12,2013 20:11

    Hello,

    This program is converting:

    printf(GPS.latitude);
    4939.4150

    printf(GPS.longitude);
    556.8587

    to Decimal Degrees but I want to convert into Degree Minute Seconds. What code should I apply?

    • Reply serialc Mar 25,2014 09:20

      Hi M. Talha,

      You want Degree Minute’ Seconds” and the sensor provides Degree Minutes’ (decimal).

      You will simply need to convert the Minutes from decimal format to Minute’ Seconds” format. I will explain this using code:

      // continuing from the code in post
      // min contains decimal value of minutes
      seconds = 60 * (min - (int)min)

  2. Reply Skipper Apr 23,2013 21:40

    Hello,
    I’ve had a go at this little snippet, and I can get the coordinates from (Slightly modified)
    Serial.print(GPS.latitude);
    but when I try Serial.print(convertDegMinToDecDeg(GPS.latitude));
    I end up with only 2 decimal points….. Any ideas?

  3. Reply Kawalski Mar 25,2014 07:46

    can i please ask how to convert the location into a link in google map to be sent as a message…

    • Reply serialc Mar 25,2014 09:28

      Hi Kawalski,

      I need a bit more information about what you are trying to achieve but once you get the output from our code – Decimal degrees you can simply paste them into Google maps’ search box.

      So if for example the sensor gives me the lat, long values of 4939.4150, 556.8587 the code converts them to 49.656917, 5.914312.

      I paste the corrected decimal degree lat, long values into http://maps.google.com or even simply http://google.com and it displays the location.

      If you are trying to plot many points then look at Google’s Fusion Tables (https://sites.google.com/site/fusiontablestalks/stories)

  4. Reply Lance Apr 4,2014 02:43

    Question though… What happens when your longitude is negative, it won’t output it that way.

    • Reply serialc Apr 4,2014 09:29

      Why not?

      Take the code:

      #include
      #include
      #include

      // converts lat/long from Adafruit
      // degree-minute format to decimal-degrees
      double convertDegMinToDecDeg (float degMin) {
      double min = 0.0;
      double decDeg = 0.0;

      //get the minutes, fmod() requires double
      min = fmod((double)degMin, 100.0);

      //rebuild coordinates in decimal degrees
      degMin = (int) ( degMin / 100 );
      decDeg = degMin + ( min / 60 );

      return decDeg;
      }

      main()
      {
      printf("%f\n", convertDegMinToDecDeg(4939.4150));
      printf("%f\n", convertDegMinToDecDeg(-4939.4150));
      printf("%f\n", convertDegMinToDecDeg(556.8587));
      printf("%f\n", convertDegMinToDecDeg(-556.8587));
      }

      Put it in http://www.compileonline.com/compile_c_online.php and look at the output.

      Notice that I state at the end of the post that “This functions for all values -180 to 180.”

  5. Reply James Medd Apr 22,2014 17:12

    Thanks for posting this, although I’m afraid I’m also unable to get negative longitude values from this code!

    • Reply Trefex Apr 22,2014 21:57

      Hello James,

      Can you please elaborate? When I try a negative value it works nicely.

      Please put your values and the code you used.

      Thanks,

      • Reply serialc Apr 23,2014 07:43

        I am wondering if the output format on the southern hemisphere is exactly the same as the north with the exception that your can request whether coordinates returned are north/south or east/west. I remember us getting back ‘N’ and ‘E’ from the GPS, perhaps you have to use these to convert to negative? We’re rather lucky being in the +/+ quadrant of the world and not having to worry about this.

        It would be ideal if someone could send us their GPS output from the southern or western hemispheres.
        C-

  6. Reply ken Jun 28,2014 11:14

    Hi
    I have purchased a Adafruit Ulitmate GPS MTK3339

    I am using the “Adafruit_GPS_Library_master”….”Parsing code.”

    I am very very new to Arduino, but i saw your above code “Parsing and transforming” & “Conclusion”

    Please can you explain where to put the “Parsing and transforming” & “Conclusion” code ?

    • Reply Trefex Jun 28,2014 16:50

      The “parsing” is a function and can go anywhere outside of the main loop. The “conclusion” code needs to go in the main loop.

      Does that help?

  7. Reply Christian V Dec 21,2015 11:20

    Hello,
    Why you take your head as you guys!
    There is in Adafruit a function that correctly gives the “X” values and “Y” in decimal degrees with the point in the right place.

    Serial.print(GPS.latitudeDegrees,5);
    Serial.print(GPS.longitudeDegrees,5);

    Have a good day

Leave a Reply to admin Cancel Reply