SparkFun Forums 

Where electronics enthusiasts find answers.

Tips and questions relating to the GPS modules from SFE
By Yeti_Monster
#146667
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!
By fll-freak
#146673
You can find any number of DMS conversion functions in C/C++ on the web. Here is one I use.
Code: Select all

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:
Code: Select all
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.
By Yeti_Monster
#146716
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
By fll-freak
#146721
"Where it makes sense"?!

Likely spot would be after you get the lat/long from the GPS (gps.f_get_position(&latitude, &longitude);) 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.