Improved, thread compatible. Adds new features

Dependents:   GroveGPS-Example

Fork of GroveGPS by Michael Ray

Committer:
JimCarver
Date:
Sun Apr 22 00:06:53 2018 +0000
Revision:
3:cc5c9faa1cc6
Parent:
1:403eb5e9e994
Child:
4:4615d6e99bb4
Improved

Who changed what in which revision?

UserRevisionLine numberNew contents of line
michaelray 0:56d6407653a7 1 #ifndef _GROVE_GPS_H_
michaelray 0:56d6407653a7 2 #define _GROVE_GPS_H_
michaelray 0:56d6407653a7 3
michaelray 0:56d6407653a7 4 #include "mbed.h"
michaelray 0:56d6407653a7 5 #include <stdlib.h>
michaelray 0:56d6407653a7 6 #include <string>
michaelray 0:56d6407653a7 7
michaelray 0:56d6407653a7 8 class GroveGPS {
michaelray 0:56d6407653a7 9
michaelray 0:56d6407653a7 10 public:
michaelray 0:56d6407653a7 11
michaelray 0:56d6407653a7 12 GroveGPS() : _last_line("") {}
michaelray 0:56d6407653a7 13
michaelray 0:56d6407653a7 14 void readCharacter(char newCharacter) {
michaelray 0:56d6407653a7 15 if (newCharacter == '\n') {
michaelray 0:56d6407653a7 16 parseLine();
michaelray 0:56d6407653a7 17 _last_line = "";
michaelray 0:56d6407653a7 18 } else {
michaelray 0:56d6407653a7 19 _last_line += newCharacter;
michaelray 0:56d6407653a7 20 }
michaelray 0:56d6407653a7 21 }
michaelray 0:56d6407653a7 22
michaelray 0:56d6407653a7 23 struct GGA {
michaelray 0:56d6407653a7 24 double utc_time; // Format: hhmmss.sss
michaelray 0:56d6407653a7 25 double latitude; // Format: ddmm.mmmm
michaelray 0:56d6407653a7 26 char ns_indicator; // Format: N=north or S=south
michaelray 0:56d6407653a7 27 double longitude; // Format: dddmm.mmmm
michaelray 0:56d6407653a7 28 char ew_indicator; // Format: E=east or W=west
michaelray 0:56d6407653a7 29 int position_fix; // Options: [0=not available, 1=GPS SPS mode, 2=Differential GPS, 6=dead reckoning]
michaelray 0:56d6407653a7 30 int sats_used; // Range: 0-12
michaelray 0:56d6407653a7 31 double hdop; // Horizontal Dilution of Precision
michaelray 0:56d6407653a7 32 double msl_altitude;
michaelray 0:56d6407653a7 33 char msl_altitude_units;
michaelray 0:56d6407653a7 34 double geoid_separation;
michaelray 0:56d6407653a7 35 char geoid_separation_units;
michaelray 0:56d6407653a7 36 long age_of_diff;
michaelray 0:56d6407653a7 37 long diff_ref_station_id;
JimCarver 1:403eb5e9e994 38 int new_flag;
michaelray 0:56d6407653a7 39 std::string checksum;
michaelray 0:56d6407653a7 40 } gps_gga;
JimCarver 1:403eb5e9e994 41
JimCarver 1:403eb5e9e994 42 struct ZDA {
JimCarver 1:403eb5e9e994 43 double utc_time; // Format: hhmmss.sss
JimCarver 1:403eb5e9e994 44 int day;
JimCarver 1:403eb5e9e994 45 int month;
JimCarver 1:403eb5e9e994 46 int year;
JimCarver 1:403eb5e9e994 47 int new_flag;
JimCarver 1:403eb5e9e994 48 std::string checksum;
JimCarver 1:403eb5e9e994 49 } gps_zda;
michaelray 0:56d6407653a7 50
JimCarver 1:403eb5e9e994 51 struct VTG {
JimCarver 1:403eb5e9e994 52 double course1;
JimCarver 1:403eb5e9e994 53 int truec;
JimCarver 1:403eb5e9e994 54 double course2;
JimCarver 1:403eb5e9e994 55 int magnetic;
JimCarver 1:403eb5e9e994 56 double speed1;
JimCarver 1:403eb5e9e994 57 int knots;
JimCarver 1:403eb5e9e994 58 double speed2;
JimCarver 1:403eb5e9e994 59 int kmh;
JimCarver 1:403eb5e9e994 60 int new_flag;
JimCarver 1:403eb5e9e994 61 std::string checksum;
JimCarver 1:403eb5e9e994 62 } gps_vtg;
JimCarver 1:403eb5e9e994 63
JimCarver 3:cc5c9faa1cc6 64 void getTimestamp(char* buffer) {
JimCarver 3:cc5c9faa1cc6 65 if (gps_gga.position_fix==0)
JimCarver 3:cc5c9faa1cc6 66 sprintf(buffer, "N/A");
JimCarver 3:cc5c9faa1cc6 67 else
JimCarver 3:cc5c9faa1cc6 68 sprintf(buffer, "%f", gps_gga.utc_time);
JimCarver 3:cc5c9faa1cc6 69 }
JimCarver 1:403eb5e9e994 70
JimCarver 1:403eb5e9e994 71 void getAltitude(char* buffer) {
JimCarver 1:403eb5e9e994 72 if (gps_gga.position_fix==0)
JimCarver 1:403eb5e9e994 73 sprintf(buffer, "N/A");
JimCarver 1:403eb5e9e994 74 else
JimCarver 1:403eb5e9e994 75 sprintf(buffer, "%f", gps_gga.msl_altitude);
JimCarver 1:403eb5e9e994 76 }
JimCarver 1:403eb5e9e994 77
JimCarver 1:403eb5e9e994 78 void getCourse(char* buffer) {
JimCarver 1:403eb5e9e994 79 if (gps_gga.position_fix==0)
JimCarver 1:403eb5e9e994 80 sprintf(buffer, "N/A");
JimCarver 1:403eb5e9e994 81 else
JimCarver 1:403eb5e9e994 82 sprintf(buffer, "%f", gps_vtg.course1);
JimCarver 1:403eb5e9e994 83 }
JimCarver 1:403eb5e9e994 84
JimCarver 1:403eb5e9e994 85 void getSpeed(char* buffer) {
JimCarver 1:403eb5e9e994 86 if (gps_gga.position_fix==0)
JimCarver 1:403eb5e9e994 87 sprintf(buffer, "N/A");
JimCarver 1:403eb5e9e994 88 else
JimCarver 1:403eb5e9e994 89 sprintf(buffer, "%f", gps_vtg.speed1);
JimCarver 1:403eb5e9e994 90 }
JimCarver 3:cc5c9faa1cc6 91
JimCarver 3:cc5c9faa1cc6 92
JimCarver 3:cc5c9faa1cc6 93 void getUncertanty(char* buffer) {
JimCarver 1:403eb5e9e994 94 if (gps_gga.position_fix==0)
JimCarver 1:403eb5e9e994 95 sprintf(buffer, "N/A");
JimCarver 1:403eb5e9e994 96 else
JimCarver 3:cc5c9faa1cc6 97 sprintf(buffer, "%f", gps_gga.hdop);
michaelray 0:56d6407653a7 98 }
JimCarver 3:cc5c9faa1cc6 99
michaelray 0:56d6407653a7 100 void getLatitude(char* buffer) {
michaelray 0:56d6407653a7 101 double coordinate = convertGPSToDecimal(gps_gga.latitude);
JimCarver 3:cc5c9faa1cc6 102 if (gps_gga.position_fix==0) {
michaelray 0:56d6407653a7 103 sprintf(buffer, "N/A");
JimCarver 3:cc5c9faa1cc6 104 } else {
JimCarver 3:cc5c9faa1cc6 105 sprintf(buffer, "%c%f", (gps_gga.ns_indicator == 'N') ? '0' : '-', coordinate);
JimCarver 3:cc5c9faa1cc6 106 }
michaelray 0:56d6407653a7 107 }
michaelray 0:56d6407653a7 108
michaelray 0:56d6407653a7 109 void getLongitude(char* buffer) {
michaelray 0:56d6407653a7 110 double coordinate = convertGPSToDecimal(gps_gga.longitude);
michaelray 0:56d6407653a7 111 if (gps_gga.position_fix==0)
michaelray 0:56d6407653a7 112 sprintf(buffer, "N/A");
michaelray 0:56d6407653a7 113 else
michaelray 0:56d6407653a7 114 sprintf(buffer, "%c%f", (gps_gga.ew_indicator == 'E') ? '0' : '-', coordinate);
michaelray 0:56d6407653a7 115 }
michaelray 0:56d6407653a7 116
michaelray 0:56d6407653a7 117 private:
michaelray 0:56d6407653a7 118 std::string _last_line;
michaelray 0:56d6407653a7 119
JimCarver 1:403eb5e9e994 120
michaelray 0:56d6407653a7 121 double convertGPSToDecimal(double coordinate) {
michaelray 0:56d6407653a7 122 int degrees = coordinate/100.0;
michaelray 0:56d6407653a7 123 int minutes = ((int)coordinate) % 100;
michaelray 0:56d6407653a7 124 double seconds = coordinate - ((int)coordinate);
michaelray 0:56d6407653a7 125 return degrees + (minutes+seconds)/60;
michaelray 0:56d6407653a7 126
michaelray 0:56d6407653a7 127 }
michaelray 0:56d6407653a7 128
michaelray 0:56d6407653a7 129 void parseLine() {
michaelray 0:56d6407653a7 130 if (_last_line.find("GPGGA") != std::string::npos) {
michaelray 0:56d6407653a7 131 parseGGA();
michaelray 0:56d6407653a7 132 }
JimCarver 1:403eb5e9e994 133 if (_last_line.find("GPZDA") != std::string::npos) {
JimCarver 1:403eb5e9e994 134 parseZDA();
JimCarver 1:403eb5e9e994 135 }
JimCarver 1:403eb5e9e994 136 if (_last_line.find("GPVTG") != std::string::npos) {
JimCarver 1:403eb5e9e994 137 parseVTG();
JimCarver 1:403eb5e9e994 138 }
JimCarver 1:403eb5e9e994 139 }
JimCarver 1:403eb5e9e994 140
JimCarver 1:403eb5e9e994 141 void parseVTG() {
JimCarver 1:403eb5e9e994 142 char* pEnd;
JimCarver 1:403eb5e9e994 143 for (int i=0; i<5; i++) {
JimCarver 1:403eb5e9e994 144 std::string current_item = _last_line.substr(0,_last_line.find(","));
JimCarver 1:403eb5e9e994 145 _last_line = _last_line.substr(_last_line.find(",")+1);
JimCarver 1:403eb5e9e994 146 if (i==0) { // NMEA Tag
JimCarver 1:403eb5e9e994 147 } else if (i==1) { // UTC time
JimCarver 1:403eb5e9e994 148 gps_vtg.course1 = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 149 } else if (i==3) {
JimCarver 1:403eb5e9e994 150 gps_vtg.course2 = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 151 } else if (i==5) {
JimCarver 1:403eb5e9e994 152 gps_vtg.speed1 = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 153 } else if (i==7) {
JimCarver 1:403eb5e9e994 154 gps_vtg.speed2 = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 155 }
JimCarver 3:cc5c9faa1cc6 156 if(gps_vtg.course2 > gps_vtg.course1) gps_vtg.course1 = gps_vtg.course2;
JimCarver 3:cc5c9faa1cc6 157 if(gps_vtg.speed2 > gps_vtg.speed1) gps_vtg.speed1 = gps_vtg.speed2;
JimCarver 1:403eb5e9e994 158 }
JimCarver 1:403eb5e9e994 159 gps_vtg.new_flag = 1;
JimCarver 1:403eb5e9e994 160 }
JimCarver 1:403eb5e9e994 161
JimCarver 1:403eb5e9e994 162 void parseZDA() {
JimCarver 1:403eb5e9e994 163 char* pEnd;
JimCarver 1:403eb5e9e994 164 for (int i=0; i<5; i++) {
JimCarver 1:403eb5e9e994 165 std::string current_item = _last_line.substr(0,_last_line.find(","));
JimCarver 1:403eb5e9e994 166 _last_line = _last_line.substr(_last_line.find(",")+1);
JimCarver 1:403eb5e9e994 167 if (i==0) { // NMEA Tag
JimCarver 1:403eb5e9e994 168 } else if (i==1) { // UTC time
JimCarver 1:403eb5e9e994 169 gps_zda.utc_time = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 170 } else if (i==2) {
JimCarver 1:403eb5e9e994 171 gps_zda.day = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 172 } else if (i==3) {
JimCarver 1:403eb5e9e994 173 gps_zda.month = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 174 } else if (i==4) {
JimCarver 1:403eb5e9e994 175 gps_zda.year = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 176 }
JimCarver 1:403eb5e9e994 177 }
JimCarver 1:403eb5e9e994 178 gps_zda.new_flag = 1;
michaelray 0:56d6407653a7 179 }
michaelray 0:56d6407653a7 180
michaelray 0:56d6407653a7 181 void parseGGA() {
michaelray 0:56d6407653a7 182 char* pEnd;
michaelray 0:56d6407653a7 183 for (int i=0; i<14; i++) {
michaelray 0:56d6407653a7 184 std::string current_item = _last_line.substr(0,_last_line.find(","));
michaelray 0:56d6407653a7 185 _last_line = _last_line.substr(_last_line.find(",")+1);
michaelray 0:56d6407653a7 186 if (i==0) { // NMEA Tag
michaelray 0:56d6407653a7 187 } else if (i==1) { // UTC time
michaelray 0:56d6407653a7 188 gps_gga.utc_time = strtod(current_item.c_str(), &pEnd);
michaelray 0:56d6407653a7 189 } else if (i==2) { // Latitude
michaelray 0:56d6407653a7 190 gps_gga.latitude = strtod(current_item.c_str(), &pEnd);
michaelray 0:56d6407653a7 191 } else if (i==3) { // Latitude North/South indicator
michaelray 0:56d6407653a7 192 gps_gga.ns_indicator = current_item[0];
michaelray 0:56d6407653a7 193 } else if (i==4) { // Longitude
michaelray 0:56d6407653a7 194 gps_gga.longitude = strtod(current_item.c_str(), &pEnd);
michaelray 0:56d6407653a7 195 } else if (i==5) { // Longitude indicator
michaelray 0:56d6407653a7 196 gps_gga.ew_indicator = current_item[0];
michaelray 0:56d6407653a7 197 } else if (i==6) {
michaelray 0:56d6407653a7 198 gps_gga.position_fix = strtod(current_item.c_str(), &pEnd);
JimCarver 1:403eb5e9e994 199 }else if (i==7) {
JimCarver 1:403eb5e9e994 200 gps_gga.sats_used = strtod(current_item.c_str(), &pEnd);
JimCarver 3:cc5c9faa1cc6 201 } else if (i==8) { // Uncertanty
JimCarver 1:403eb5e9e994 202 gps_gga.hdop = strtod(current_item.c_str(), &pEnd);
JimCarver 3:cc5c9faa1cc6 203 } else if (i==9) { // Altitude mean sea level
JimCarver 1:403eb5e9e994 204 gps_gga.msl_altitude = strtod(current_item.c_str(), &pEnd);
JimCarver 3:cc5c9faa1cc6 205 } else if (i==11) {
JimCarver 3:cc5c9faa1cc6 206 gps_gga.geoid_separation = strtod(current_item.c_str(), &pEnd);
JimCarver 3:cc5c9faa1cc6 207 gps_gga.msl_altitude += gps_gga.geoid_separation;
michaelray 0:56d6407653a7 208 }
michaelray 0:56d6407653a7 209 }
JimCarver 1:403eb5e9e994 210 gps_gga.new_flag = 1;
michaelray 0:56d6407653a7 211 }
JimCarver 1:403eb5e9e994 212
michaelray 0:56d6407653a7 213 };
michaelray 0:56d6407653a7 214
michaelray 0:56d6407653a7 215 #endif