Go Down

Topic: Gps Coordinate conversion help (Read 6511 times)previous topic - next topic

Yeti_Monster

Jun 22, 2012, 11:12 amLast Edit: Jun 22, 2012, 11:26 am by Yeti_Monster Reason: 1
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 and example 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)

and here is my sketch.

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,

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

// -------------------------BATTERY VOLTAGE --------------------------------------------

int batteryPin = A0; // analog pin 0
int battery2Pin = A1;

float BattsensorValue;
float BattoutputValue;

const float referenceVolts = 5;   // the default reference on a 5-volt board
const float resistorFactor = 327;  // 327 = 1023 x r2 / (r1+r2)  r1 = 10000ohm   r2 = 4700ohm

// --------------------------Outside temp sensor --------------------------------------------------
int DS18S20_Pin = 22; //DS18S20 Signal pin on digital 22
OneWire ds(DS18S20_Pin);  // on digital pin 22

void setup()
{

dht.begin();

Wire.begin();

compass.enableDefault();

// Calibration values. Use the Calibrate example program to get the values for
compass.m_min.x = -1038; compass.m_min.y = -831; compass.m_min.z = -662;
compass.m_max.x = +639; compass.m_max.y = +797; compass.m_max.z = 837;

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...
{
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!

pylon

#1
Jun 22, 2012, 02:38 pm
I guess you wanna know how to do that in C (although you actually didn't ask a question).

Code: [Select]
`float long = 45.124783;int deglong = long;long -= deglong; // remove the degrees from the calculationlong *= 60; // convert to minutesint minlong = long;long -= minlong; // remove the minuts from the calculationlong *= 60; // convert to seconds`

This is what you've written in your math section converted to C code.

#2
Aug 06, 2016, 04:53 pmLast Edit: Aug 06, 2016, 04:59 pm by vadimEL
GPS data convert from DD.DDDDD to DD MM SS.SS
Code: [Select]
`void loop(){...int DD,MM;double SS;DD_DDDDDtoDDMMSS(gps.location.lat() , &DD, &MM, &SS );Serial.println(DD);Serial.println(MM);Serial.println(SS,7);}//моя функци перевода из DD_DDDDD  в  DD_MM_SSvoid DD_DDDDDtoDDMMSS( double DD_DDDDD , int *DD, int *MM, double *SS ){     *DD=(int)DD_DDDDD;//сделали из 37.45545 это 37 т.е. Градусы *MM=(int)((DD_DDDDD - *DD)*60);//получили минуты *SS=((DD_DDDDD - *DD)*60-*MM)*60;//получили секунды}`

-dev

#3
Aug 06, 2016, 09:05 pmLast Edit: Aug 06, 2016, 09:09 pm by /dev Reason: inline file :P
Just for fun, I converted your sketch to use my NeoGPS library (see below).  NeoGPS has built-in support for lat/lon in integer, float and the Degrees/Minutes/Seconds form you are asking about.  This displays the lat/lon in DMS instead of a floating-point number:

Code: [Select]
`// necessary libraries#include "NMEAGPS.h"#include <LiquidCrystal.h>#include <OneWire.h> //for temp sensor#include <Wire.h>#include <LSM303.h> //compass#include <DHT.h> //temp humidity sensor#define DHTPIN 30   // DHT sensor pin#define DHTTYPE DHT22   // DHT 22  (AM2302)DHT dht(DHTPIN, DHTTYPE);LSM303 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 differentNMEAGPS gps;  // Create an instance of the GPS objectvoid getgps(NMEAGPS &gps);   // This is where you declare prototypes for the functions that will be                             // using the GPS library.// -------------------------BATTERY VOLTAGE --------------------------------------------int batteryPin = A0; // analog pin 0int battery2Pin = A1; int BattanalogIn = A2;float BattsensorValue; float BattoutputValue; const float referenceVolts = 5;   // the default reference on a 5-volt boardconst float resistorFactor = 327;  // 327 = 1023 x r2 / (r1+r2)  r1 = 10000ohm   r2 = 4700ohm// --------------------------Outside temp sensor --------------------------------------------------int DS18S20_Pin = 22; //DS18S20 Signal pin on digital 22OneWire ds(DS18S20_Pin);  // on digital pin 22void setup(){ dht.begin();  Wire.begin();  compass.enableDefault();  // Calibration values. Use the Calibrate example program to get the values for // your compass. compass.m_min.x = -1038; compass.m_min.y = -831; compass.m_min.z = -662; compass.m_max.x = +639; compass.m_max.y = +797; compass.m_max.z = 837;    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( F("Waiting for lock") );}void loop(){ GPS_LOC ( );//Batt_V_I ( );//OutTemp ( );//Compass ( );//TempHumidSensor ( );}int GPS_LOC( ){ if (gps.available( Serial1 )) {   getgps(gps);  // then grab the data. }}void getgps( NMEAGPS &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_fix fix = gps.read();  lcd.clear();  lcd.setCursor(0,0); lcd.print( F("Latitude : ") ); if (fix.valid.location) {   //lcd.print( fix.latitude(), 5 );      // Print degrees minutes seconds.123   lcd << fix.latitudeDMS;   lcd.print( fix.latitudeDMS.NS() ); }     lcd.setCursor(0,1);  lcd.print( F("Longitude: ") ); if (fix.valid.location) {   //lcd.print( fix.longitude(), 5 );    // Print degrees minutes seconds.123   lcd << fix.longitudeDMS;   lcd.print( fix.longitudeDMS.EW() ); }  lcd.setCursor(0,2); lcd.print( F("Altitude : ") ); if (fix.valid.altitude) {   lcd.print( fix.altitude() );   lcd.print('m'); }  lcd.setCursor(0,3); lcd.print( F("Speed: ") ); if (fix.valid.speed) {   lcd.print( fix.speed_kph(), 0 );   //lcd.print( F("kph") ); }  lcd.setCursor(11,3);  lcd.print( F("Sats: ") ); if (fix.valid.satellites)   lcd.print( fix.satellites );   //Serial.print("HDOP: "); //if (fix.valid.hdop)      //Serial.println(fix.hdop);  }`

The two sketch sizes:

 Program RAM Original 10484 789 NeoGPS 10960 620
It uses 476 bytes more program space, but 169 fewer bytes of RAM.  I think you also find that the LCD doesn't flicker (if it was), and it updates exactly once per second.

Sometimes, adding your other tasks in causes you to start losing GPS data.  If that happens (or was happening), this sketch will be more immune to that.  If it still happens, you can drop in the NeoHWSerial library and handle the GPS characters in an interrupt.  See the Troubleshooting page for more info.

If you'd like to try it, follow the Install instructions, and uncomment these in GPSfix_cfg.h to enable the DMS form:

Code: [Select]
`#define GPS_FIX_LOCATION_DMS#define GPS_FIX_ALTITUDE#define GPS_FIX_SPEED#define GPS_FIX_SATELLITES`
Everything should be commented out, unless you want additional pieces.

Also uncomment this in NMEAGPS_cfg.h:

`    #define NMEAGPS_PARSING_SCRATCHPAD`

It's required for the DMS option.

BTW, you are using the old LSM303DLH, which has been deprecated.  You should probably use the newer LSM303 library instead.

Cheers,
/dev
Really, I used to be /dev.

-dev

#4
Aug 06, 2016, 10:55 pm
I just noticed a compiler bug, so you may need to download the latest NeoGPS if your Latitude shows as SOUTH when you're actually NORTH.

Cheers,
/dev
Really, I used to be /dev.

Go Up