Go Down

Topic: Gps Coordinate conversion help (Read 1 time) previous topic - next topic

Yeti_Monster

Hi guys,


A bit of background info: i've made a information display unit for my 4 wheel drive, that displays among other things, Latitude and Longitude in decimal degrees, Eg, -36.76453, 145.74653.. but i if need to convert this info to Degrees, Minutes, Seconds, eg -36° 76' 53,  145° 74' 53. 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. 



Quote


// 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!

lesto

http://williams.best.vwh.net/avform.

pay attention, arduino's 32 bit float give some unprecise result. take a look at bignumber library
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Yeti_Monster

thanks, but thats not what i'm having trouble with

jraskell

What's the source of your longitude/latitude readings? most gps modules give reading in degrees only, ie:
145.74653 is not 145 degrees 74' 65".  It's 145.74653 degrees.

It's up to you to convert .74653 degrees into minutes and seconds. There are 60 minutes in a degree, and 60 seconds in a minute, or 3600 seconds in a degree, so .74653 degrees = 2687 seconds (or 44 minutes, 47 seconds)

MarkT

Firstly the 24 bit resolution of floating point may not be sufficient for a GPS Lat/Lon value.   Better to use a fixed-point representation, such as using a long int that is a count of millionths of a degree.

Thus 123.45678 degrees would be represented by 123456780L  (L for long).  The kind of code to do the conversion progresses from degrees through minutes to seconds and fractions of a second - this is generalized base-conversion and a straightforward way for this case might look like:

Code: [Select]

  long micro_degrees = 123456789L ;
  int  degrees = micro_degrees / 1000000L ;      // degrees = 123
  micro_degrees -= 1000000L * degrees ;          // micro_degrees = 456789
  long  milli_minutes = micro_degrees * 3 / 50 ; // miili_minutes = 27407
  int minutes = milli_minutes / 1000 ;           // minutes = 27
  milli_minutes -= 1000L * minutes ;             // milli_minutes = 407
  int centi_seconds = milli_minutes * 6 ;        // centi_seconds = 2442
  int seconds = deci_seconds / 10 ;              // seconds = 24
  centi_seconds -= 10 * seconds ;                // centi_seconds = 42

So you get 123 deg, 27 minutes, 24.42 seconds  (back check gives 123.456783 degrees, about 2 feet out.
[ I won't respond to messages, use the forum please ]

Yeti_Monster

jraskell. i get the readings from the gps, which i print the latitude and longitude like you said, to 5 decimal places

Quote

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);  // Print to LCD to 5 decimal places.
 
  lcd.setCursor(0,1);
  lcd.print("Longitude: "); lcd.print(longitude,5);



so i know i have to use the 'latitude,5'

MarkT.. could i use your example and replace first line with "long micro_degrees = (latitude,5);"     ?

lesto

long are number without decimal, so decimal part is truncated. if you want to save 5 decimal, just do


Code: [Select]
long micro_degrees = latitude*10000;
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MarkT

You just need to set micro_degrees to the (long integer) number of micro-degrees.  Made tricky by the fact that a float isn't accurate enough - you can read the part before and after the decimal point as integers and combine them.  An exercise in arithmetic.
[ I won't respond to messages, use the forum please ]

Yeti_Monster

#8
Jun 27, 2012, 12:09 pm Last Edit: Jun 27, 2012, 12:26 pm by Yeti_Monster Reason: 1
hey MarkT..

im not very good at maths, i think i even failed it in high school!

would this be how i could get it to work?

Quote

 long micro_degrees = latitude;
 int  degrees = micro_degrees / 1000000L ;      // degrees = 123
 micro_degrees -= 1000000L * degrees ;          // micro_degrees = 456789
 long  milli_minutes = micro_degrees * 3 / 50 ; // miili_minutes = 27407
 int minutes = milli_minutes / 1000 ;           // minutes = 27
 milli_minutes -= 1000L * minutes ;             // milli_minutes = 407
 int centi_seconds = milli_minutes * 6 ;        // centi_seconds = 2442
 int seconds = deci_seconds / 10 ;              // seconds = 24
 centi_seconds -= 10 * seconds ;                // centi_seconds = 42

lcd.print (micro_degrees);




i feel like i'm missing something....?

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy