GPS coordinate conversion help!

Hi guys,

A bit of background info: i’ve made a information display unit for my 4 wheel drive, using the Venus gps with sma connector. it displays among other things, Latitude and Longitude in decimal degrees, Eg, -36.76453, 145.74653… everything works great except i need to convert this info to Degrees, Minutes, Seconds, eg -36° 76’ 53, 145° 74’ 53. to correspond with the paper maps i have. i know i need to do some maths, here’s an example of how to do it i found.

DM.m = Degrees, Minutes, Decimal Minutes (eg. 45°22.6333)

D.d = Degrees, Decimal Degrees (eg. 45.3772°)

DMS = Degrees, Minutes, Seconds (eg. 45°22’38")

D.d → DM.m (45.3772 → 45°22.6333

Multiply .d by 60 to get M.m (.3772*60=22.6333)

DM.m → DMS (45°22.6333 → 45°22’38")

Multiply .m by 60 to get S(.6333*60=38)

My question is: how do i put this in my sketch?

I know i need to use the “Latitude” and “Longitude” values and use the above method to convert it before sending it to the LCD. i hope that makes sense.

// necessary libraries

#include <TinyGPS.h> //GPS

#include <LiquidCrystal.h>

#include <OneWire.h> //for temp sensor

#include <Wire.h>

#include <LSM303DLH.h> //compass

#include <DHT.h> //temp humidity sensor

#define DHTPIN 30 // DHT sensor pin

#define DHTTYPE DHT22 // DHT 22 (AM2302)

DHT dht(DHTPIN, DHTTYPE);

LSM303DLH compass;

const int heading_min = 0; // sensor minimum,

const int heading_max = 359;

// The parameters in the brackets define which digital output pins connect to

// (in order) LCD pins: RS, enable, D4, D5, D6, and D7.

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

LiquidCrystal lcd2(12, 10, 5, 4, 3, 2); //second display

//---------------------------GPS------------------------------------------------------

#define GPSBAUD 9600 // baud rate of our GPS module. Change for your GPS module if different

TinyGPS gps; // Create an instance of the TinyGPS object

void getgps(TinyGPS &gps); // This is where you declare prototypes for the functions that will be

// using the TinyGPS library.

Serial1.begin(GPSBAUD); // setup sketch for data output speed of GPS module

lcd.begin(20, 4);

lcd2.begin(20, 4);

lcd.clear();

//lcd2.clear();

lcd.setCursor(2,1);

lcd.print(“Waiting for lock”);

}

void loop()

{

GPS_LOC ( );

Batt_V_I ( );

OutTemp ( );

Compass ( );

TempHumidSensor ( );

}

int GPS_LOC( )

{

while(Serial1.available()) // While there is data on the RX pin…

{

int c = Serial1.read(); // load the data into a variable…

if(gps.encode(c)) // if there is a new valid sentence…

{

getgps(gps); // then grab the data.

}

}

}

void getgps(TinyGPS &gps) // The getgps function will get and print the values we want.

{

float latitude, longitude, fix_age; // Define the variables that will be used

gps.f_get_position(&latitude, &longitude); // You can now print variables latitude and longitude

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Latitude : "); lcd.print(latitude,5);

lcd.setCursor(0,1);

lcd.print("Longitude: "); lcd.print(longitude,5);

lcd.setCursor(0,2);

lcd.print("Altitude : ");

lcd.print(gps.f_altitude());lcd.print(“m”);

lcd.setCursor(0,3);

lcd.print("Speed: ");

lcd.print(gps.f_speed_kmph(),0); //lcd.print(“k”);

lcd.setCursor(11,3);

lcd.print("Sats: ");

lcd.print(gps.satellites());

//Serial.print("HDOP: "); Serial.println(gps.hdop());

}

(had to delete some of my sketch to make it fit in this post)

Thanks for helping!

You can find any number of DMS conversion functions in C/C++ on the web. Here is one I use.

void Split_into_dms(float angle, unsigned int * deg, unsigned int* min, float *sec) {
  float t;
  unsigned int d, m;
  float s;

  if (angle < 0.0) {
    angle = - angle;
  }

  d = (unsigned int)angle;       
  t = (angle - (float )d)*60.0;  
  m = (unsigned int)(t);         
  s = (t - (float )m)*60.0;       

  /* Now some rounding issues */
  if (s >= 59.995) {
    s = 0.0;
    m ++;
    if (m == 60) {
      m = 0;
      d++;
    }
  }
  *deg = d;
  *min = m;
  *sec = s;

}

It would be used like this:

float latitude, lat_sec;
unsigned int lat_deg, lat_min;

Split_into_dms(latitude, &lat_deg, &lat_min, &lat_sec);

You need to keep track yourself if the angle was negative and add the appropriate (W/S) prefix. Or you can modify the function to pass in a prefix pair (EW/NS) and return a single character prefix you need.

Hey Skye, thanks for getting back to me. i’m still unsure of where to put your code into my one. any suggestions?

thanks again

“Where it makes sense”?!

Likely spot would be after you get the lat/long from the GPS (gps.f_get_position(&latitude, &longitude):wink: and before you want to display (ie. lcd.print(latitude,5); ) DMS. Those single lcd.print routines would be replaced with a series of ones to print the DMS parts.

Sounds like your coding skills need improvement. I would pick up a book on C/C++ coding for beginners and bone up. There may even be such a book devoted to the idiosyncrasies of the Arduino. Just Goggled (“book arduino software”) and found a bunch. Time to hit a good bookstore.