Serial GPS: Find Distance Between Two Points
This is some code I wrote for the reverse geocache project. It uses a LS20031 GPS module. That is attached the the TX RX lines of an ATMEGA328p. This sketch also utilizes the TinyGPS Library.
// get distance example // using TinyGPS // Written by Bill Heaster #include <TinyGPS.h> //include for the GPS handeling. // These would be saved in the EEPROM for your GeoCache // For this example we will name them as const variables const long TargetLat = 43164622; const long TargetLon = 77609596; TinyGPS gps; struct //structure to organize our variables. { float miles; float feet; float km; }distance; void setup() { Serial.begin(9600); //start serial for the GPS module } void loop() { if(isData()) { getDistance(gps,TargetLat, TargetLon); } Serial.print("Miles: "); Serial.println(distance.miles); Serial.print("KM: "); Serial.println(distance.km); Serial.print("Feet: "); Serial.println(distance.feet); } bool isData() // feed the gps object with serial info and check if we are recieving a valid packet { while (Serial.available()) { if (gps.encode(Serial.read())) return true; } return false; } void getDistance(TinyGPS &gps, long targetLat, long targetLon) { long lat, lon; unsigned long age; float latRad, lonRad; float flat, flon; float tlat, tlon; float tlatRad, tlonRad; float midLat, midLon; int samples=0; //---------------------------------------- for (samples; samples< 20; samples++) //collect a few samples to make the data more accurate.Not sure if this is the best soloution. { gps.get_position(&lat, &lon, &age); //get the coords from the tinygps object if(age >= 5000) //if the data is old { delay(3000);//wait before we make another attempt isData(); //refresh the GPS object. } else { samples = 20; } } //convert to decimal degree flat = lat /100000.0; flon = lon /100000.0; tlat = targetLat / 100000.0; tlon = targetLon / 100000.0; //convert decimal degree into radian latRad = flat * 0.017453293; lonRad = flon * 0.017453293; tlatRad = tlat * 0.017453293; tlonRad = tlon * 0.017453293; midLat = tlatRad - latRad; midLon = tlonRad - lonRad; //Calculate the distance in KM float latSin = sin((latRad - tlatRad)/2); float lonSin = sin((lonRad - tlonRad)/2); distance.km = 2 * asin(sqrt((latSin*latSin) + cos(latRad) * cos(tlatRad) * (lonSin * lonSin))); distance.km = distance.km * 6371; //convert to miles distance.miles = distance.km * 0.621371192; distance.feet = distance.miles *5280; isData(); //refresh GPS during long calculations // -------------------------------- }
2 comments
Leave a Reply
You must be logged in to post a comment.
Hi, awesome code. I`m using Leonardo with GPS data logger; i`m wondering if this code works for this equipment?
My application is that i have to save on the SD Card the distance and the time (begging and ending time).
Best Regards,
Carlos Morera.
Thank you sir. This code is used on the arduino platform. If you are looking at something more portable i have a library i wrote in C here. If the leonardo gives you raw packets ($GPRMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,ddmmyy,x.x,a*hh) then the C library will work for you.