Improved, thread compatible. Adds new features

Dependents:   GroveGPS-Example

Fork of GroveGPS by Michael Ray

GroveGPS.h

Committer:
JimCarver
Date:
2018-05-31
Revision:
4:4615d6e99bb4
Parent:
3:cc5c9faa1cc6

File content as of revision 4:4615d6e99bb4:

#ifndef _GROVE_GPS_H_
#define _GROVE_GPS_H_

#include "mbed.h"
#include <stdlib.h>
#include <string>


class GroveGPS {

public:

	GroveGPS() : _last_line("") {

	}

	std::string _last_line;
	
	struct GGA {
		double  utc_time; 		// Format: hhmmss.sss
		double  latitude; 		// Format: ddmm.mmmm
		char    ns_indicator; 	// Format: N=north or S=south
		double  longitude;		// Format: dddmm.mmmm
		char    ew_indicator;	// Format: E=east or W=west
		int position_fix;	// Options: [0=not available, 1=GPS SPS mode, 2=Differential GPS, 6=dead reckoning]
		int sats_used;		// Range: 0-12
		double  hdop;			// Horizontal Dilution of Precision
		double  msl_altitude;
		char    msl_altitude_units;
		double  geoid_separation;
		char    geoid_separation_units;
		long    age_of_diff;
		long    diff_ref_station_id;
		int		new_flag;
		std::string  checksum;
	} gps_gga;
	
	struct ZDA {
		double  utc_time; 		// Format: hhmmss.sss
		int day;
		int month;
		int year;
		int	new_flag;
		std::string  checksum;
	} gps_zda;

	struct VTG {
		double  course1; 
		int truec;
		double  course2; 
		int magnetic;
		double  speed1; 
		int knots;
		double  speed2; 
		int kmh;
		int	new_flag;
		std::string  checksum;
	} gps_vtg;

	void getTimestamp(char* buffer) {
		if (gps_gga.position_fix==0)
			sprintf(buffer, "N/A");
		else
			sprintf(buffer, "%f", gps_gga.utc_time);
	}
    
	void getAltitude(char* buffer) {
		if (gps_gga.position_fix==0)
			sprintf(buffer, "N/A");
		else
			sprintf(buffer, "%f", gps_gga.msl_altitude);
	}
   
	void getCourse(char* buffer) {
		if (gps_gga.position_fix==0)
			sprintf(buffer, "N/A");
		else
			sprintf(buffer, "%f", gps_vtg.course1);
	}
    
	void getSpeed(char* buffer) {
		if (gps_gga.position_fix==0)
			sprintf(buffer, "N/A");
		else
			sprintf(buffer, "%f", gps_vtg.speed1);
	}

    
	void getUncertanty(char* buffer) {
		if (gps_gga.position_fix==0)
			sprintf(buffer, "N/A");
		else
			sprintf(buffer, "%f", gps_gga.hdop);
	}
     	
	void getLatitude(char* buffer) {
		double coordinate = convertGPSToDecimal(gps_gga.latitude);
		if (gps_gga.position_fix==0) {
			sprintf(buffer, "N/A");
		} else {	
		if(gps_gga.ns_indicator == 'S') coordinate *= -1.000;
		sprintf(buffer, "%f", coordinate);
		}
	}

	void getLongitude(char* buffer) {
		double coordinate = convertGPSToDecimal(gps_gga.longitude);
		if (gps_gga.position_fix==0)
			sprintf(buffer, "N/A");
		else {
		if(gps_gga.ew_indicator == 'W') coordinate *= -1.0000;
		sprintf(buffer, "%f", coordinate);
		}
	}


	double convertGPSToDecimal(double coordinate) {
		int degrees = coordinate/100.0;
		int minutes = ((int)coordinate) % 100;
		double seconds = coordinate - ((int)coordinate);
		return degrees + (minutes+seconds)/60;

	}

void parseVTG() {
  		char* pEnd;
		for (int i=0; i<5; i++) {
			std::string current_item = _last_line.substr(0,_last_line.find(","));
			_last_line = _last_line.substr(_last_line.find(",")+1);
			if (i==0) { 		// NMEA Tag
			} else if (i==1) { 	// UTC time
				gps_vtg.course1 = strtod(current_item.c_str(), &pEnd);
			} else if (i==3) {
				gps_vtg.course2 = strtod(current_item.c_str(), &pEnd);
			} else if (i==5) {
				gps_vtg.speed1 = strtod(current_item.c_str(), &pEnd);
			} else if (i==7) {
				gps_vtg.speed2 = strtod(current_item.c_str(), &pEnd);
			}
			if(gps_vtg.course2 > gps_vtg.course1) gps_vtg.course1 = gps_vtg.course2;
			if(gps_vtg.speed2 > gps_vtg.speed1) gps_vtg.speed1 = gps_vtg.speed2;
		}
	gps_vtg.new_flag = 1;	
	}
		
void parseZDA() {
  		char* pEnd;
		for (int i=0; i<5; i++) {
			std::string current_item = _last_line.substr(0,_last_line.find(","));
			_last_line = _last_line.substr(_last_line.find(",")+1);
			if (i==0) { 		// NMEA Tag
			} else if (i==1) { 	// UTC time
				gps_zda.utc_time = strtod(current_item.c_str(), &pEnd);
			} else if (i==2) {
				gps_zda.day = strtod(current_item.c_str(), &pEnd);
			} else if (i==3) {
				gps_zda.month = strtod(current_item.c_str(), &pEnd);
			} else if (i==4) {
				gps_zda.year = strtod(current_item.c_str(), &pEnd);
			}
		}
	gps_zda.new_flag = 1;	
	}

	void parseGGA() {
  		char* pEnd;
		for (int i=0; i<14; i++) {
			std::string current_item = _last_line.substr(0,_last_line.find(","));
			_last_line = _last_line.substr(_last_line.find(",")+1);
			if (i==0) { 		// NMEA Tag
			} else if (i==1) { 	// UTC time
				gps_gga.utc_time = strtod(current_item.c_str(), &pEnd);
			} else if (i==2) { 	// Latitude
				gps_gga.latitude = strtod(current_item.c_str(), &pEnd);
			} else if (i==3) { 	// Latitude North/South indicator
				gps_gga.ns_indicator = current_item[0];
			} else if (i==4) { 	// Longitude
				gps_gga.longitude = strtod(current_item.c_str(), &pEnd);
			} else if (i==5) { 	// Longitude indicator
				gps_gga.ew_indicator = current_item[0];
			} else if (i==6) {
				gps_gga.position_fix = strtod(current_item.c_str(), &pEnd);
			}else if (i==7) {
				gps_gga.sats_used = strtod(current_item.c_str(), &pEnd);
			} else if (i==8) { // Uncertanty
				gps_gga.hdop = strtod(current_item.c_str(), &pEnd);
			} else if (i==9) { //  Altitude mean sea level
				gps_gga.msl_altitude = strtod(current_item.c_str(), &pEnd);
			} else if (i==11) {
				gps_gga.geoid_separation = strtod(current_item.c_str(), &pEnd);
				gps_gga.msl_altitude += gps_gga.geoid_separation;
			}
		}
	gps_gga.new_flag = 1;
	}
	
};

#endif