Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed WDT MODSERIAL BME280
NMEA.cpp
00001 #include "NMEA.h" 00002 00003 //! NMEA, default constructor 00004 NMEA::NMEA(){ 00005 00006 currentGGAString.resize(128); 00007 currentGPRMCString.resize(128); 00008 currentUTCFromGPRMC.resize(20); 00009 currentDATEFromGPRMC.resize(10); 00010 currentLongitude.resize(15); 00011 currentLatitude.resize(15); 00012 00013 currentLongitude = "NaN"; 00014 currentLatitude = "NaN"; 00015 00016 chkSumGps.resize(2); 00017 00018 memset(tmpArrDeg,'\0',7); 00019 memset(tmpArrMin, '\0', 7); 00020 memset(tmpLongitude, '\0', 15); 00021 memset(tmpLatitude, '\0', 15); 00022 00023 iterationIndex = 0; 00024 longitudeDD = 0.0; 00025 latitudeDD = 0.0; 00026 00027 cnt_GPRMC = 0; 00028 00029 north = false; 00030 south = false; 00031 east = false; 00032 west = false; 00033 }; 00034 00035 //! ValidateData, method taking a text string for NMEA validation 00036 /*! 00037 ValidateData validates that the NMEA data string isn't corrupted. 00038 (Verification of crc) 00039 00040 \param cstStr An NMEA ascii string. 00041 \return boolean return value, true if crc corresponds to own calculated crc, else false. 00042 */ 00043 bool NMEA::ValidateData(string cstStr){ 00044 00045 //Temporary variables used locally only 00046 chkSum = 0; 00047 00048 //If for some reason the index is wrong, and the first character is not 00049 //the beginning dollar sign of a gps string, return false at once. 00050 if(cstStr[0] != '$'){ 00051 return false; 00052 } 00053 00054 iterationIndex = 0; 00055 00056 //initializing calculated checksum 00057 chkSumGps = " "; 00058 00059 //Calculating checksum to verify string integrity 00060 for(char i = 1; i < cstStr.size(); i++){ 00061 //If at end of line for crc check, break 00062 if(cstStr[i] == '*' || cstStr[i] == '\0'){ 00063 iterationIndex = i; 00064 break; 00065 } 00066 //XOR crc calculation 00067 chkSum ^= cstStr[i]; 00068 00069 } 00070 00071 //Moving the checksum received into chkSumGps 00072 iterationIndex++; 00073 chkSumGps[0] = cstStr[iterationIndex]; 00074 iterationIndex++; 00075 chkSumGps[1] = cstStr[iterationIndex]; 00076 00077 GpsCheck = strtol(chkSumGps.c_str(), NULL ,16); 00078 00079 //Verify received and calculated crc equality 00080 if(GpsCheck == chkSum){ 00081 return true; 00082 } 00083 00084 //If unequal crc bytes found return false 00085 return false; 00086 }; 00087 00088 //! StoreString, method taking a text string as argument for further handling 00089 /*! 00090 StoreString, replaces current GPRMC or GGA string, with new valid GPRMC or GGA string. 00091 00092 \param cstStr An NMEA ascii string. 00093 */ 00094 void NMEA::StoreString(string cstStr){ 00095 static std::string gga = "$GPGGA"; 00096 static std::string rmc = "$GPRMC"; 00097 00098 //If received string is a GPGGA string 00099 //copy GPGGA string to currentGGAString 00100 if(cstStr.compare(0, 6, gga) == 0){ 00101 00102 //replace current valid gga string with new valid gga string 00103 currentGGAString.replace(0, 128, cstStr); 00104 00105 } 00106 00107 //If received string is a GPRMC string 00108 //copy GPRMC string to currentGPRMCString 00109 if(cstStr.compare(0, 6, rmc) == 0){ 00110 00111 if(cnt_GPRMC > 1000){ 00112 cnt_GPRMC = 0; 00113 } 00114 cnt_GPRMC += 1; 00115 00116 //replace current valid rmc string with new valid rmc string 00117 currentGPRMCString.replace(0, 128, cstStr); 00118 00119 } 00120 00121 }; 00122 00123 00124 //! ParseCurrentUTCFromGPRMC, grabs UTC timestamp from current stored GPRMC string. 00125 /*! 00126 ParseCurrentUTCFromGPRMC, grabs UTC timestamp from current stored GPRMC string. 00127 Stores the UTC timestamp in local text string. 00128 00129 Depending on the format it will be saved as: 00130 HH:MM:SS.FFF 00131 In this case FFF are read values fom the string. 00132 eg. 14:10:22.007 00133 00134 or 00135 00136 HH:MM:SS.FFF 00137 In this case FFF are predetermined values set to 0. 00138 eg. 14:10:22.000 00139 */ 00140 void NMEA::ParseCurrentUTCFromGPRMC(){ 00141 00142 //getting utc from GPRMC string, assigned to tmpStr 00143 getXFromNMEAString(1,currentGPRMCString); 00144 00145 currentUTCFromGPRMC = ""; 00146 currentUTCFromGPRMC.resize(20); 00147 00148 //if time format == 10 characters 00149 if(strlen(tmpStr.c_str()) > 6){ 00150 00151 //HH 00152 currentUTCFromGPRMC[0] = tmpStr[0]; 00153 currentUTCFromGPRMC[1] = tmpStr[1]; 00154 currentUTCFromGPRMC[2] = ':'; 00155 00156 //MM 00157 currentUTCFromGPRMC[3] = tmpStr[2]; 00158 currentUTCFromGPRMC[4] = tmpStr[3]; 00159 currentUTCFromGPRMC[5] = ':'; 00160 00161 //SS 00162 currentUTCFromGPRMC[6] = tmpStr[4]; 00163 currentUTCFromGPRMC[7] = tmpStr[5]; 00164 currentUTCFromGPRMC[8] = '.'; 00165 00166 //FFF 00167 currentUTCFromGPRMC[9] = tmpStr[7]; 00168 currentUTCFromGPRMC[10] = tmpStr[8]; 00169 currentUTCFromGPRMC[11] = tmpStr[9]; 00170 } 00171 00172 //if time format == 6 characters 00173 if(strlen(tmpStr.c_str()) == 6){ 00174 00175 //HH 00176 currentUTCFromGPRMC[0] = tmpStr[0]; 00177 currentUTCFromGPRMC[1] = tmpStr[1]; 00178 currentUTCFromGPRMC[2] = ':'; 00179 00180 //MM 00181 currentUTCFromGPRMC[3] = tmpStr[2]; 00182 currentUTCFromGPRMC[4] = tmpStr[3]; 00183 currentUTCFromGPRMC[5] = ':'; 00184 00185 //SS 00186 currentUTCFromGPRMC[6] = tmpStr[4]; 00187 currentUTCFromGPRMC[7] = tmpStr[5]; 00188 currentUTCFromGPRMC[8] = '.'; 00189 00190 //FFF 00191 currentUTCFromGPRMC[9] = '0'; 00192 currentUTCFromGPRMC[10] = '0'; 00193 currentUTCFromGPRMC[11] = '0'; 00194 } 00195 00196 }; 00197 00198 //ParseCurrentAltitudeFromGGA grabs current altitude from GGA string 00199 00200 void NMEA::ParseCurrentAltitudeFromGGA(void) { 00201 getXFromNMEAString(9,currentGGAString); 00202 if (GGAFixVerification()) 00203 currentAltitude= tmpStr; 00204 else 00205 currentAltitude="NaN"; 00206 00207 } 00208 00209 //! ParseCurrentDateFromGPRMC, grabs current date from current GPRMC string. 00210 /*! 00211 ParseCurrentDateFromGPRMC, grabs current date from current GPRMC string. 00212 Stores the Date in a local text string. 00213 00214 will be stored in the format: 00215 YYYY/MM/DD 00216 */ 00217 int strtoint(string str, int index) { 00218 char value[3]; 00219 value[0]=str[index]; 00220 value[1]=str[index+1]; 00221 value[2]=0; 00222 return atoi(value); 00223 } 00224 00225 void NMEA::ParseCurrentDateFromGPRMC(){ 00226 00227 //Getting date from GPRMC string, assigning to tmpStr 00228 getXFromNMEAString(9,currentGPRMCString); 00229 00230 currentDATEFromGPRMC = ""; 00231 currentDATEFromGPRMC.resize(20); 00232 char tmpdate[20]; 00233 //if date string is the expected length 00234 if(strlen(tmpStr.c_str()) == 6){ 00235 int y=strtoint(tmpStr,4); 00236 int m=strtoint(tmpStr,2); 00237 int d=strtoint(tmpStr,0); 00238 struct tm t = { .tm_year=y, .tm_mon=m-1, .tm_mday=d }; 00239 t.tm_mday += 1024*7; //rollover compentation 00240 mktime(&t); 00241 strftime (tmpdate,20,"%G/%m/%d",&t); 00242 for (int i=0; i<20; i++) currentDATEFromGPRMC[i]=tmpdate[i]; 00243 } 00244 }; 00245 00246 //! GGAFixVerification, returns gps fix indication. 00247 /*! 00248 GGAFixVerification verifies gga fix status in current GGA string. 00249 00250 \return boolean value indicating GGA fix if true, else false. 00251 */ 00252 bool NMEA::GGAFixVerification(){ 00253 00254 //accessing the string after the sixth comma, which is the gga fix column 00255 00256 char commaCount = 0; 00257 char index = 0; 00258 char stringLength = strlen(currentGGAString.c_str()); 00259 00260 while((commaCount < 7) && (currentGGAString[index] != '\0') && (index < stringLength) ){ 00261 if(currentGGAString[index] == ','){ 00262 commaCount += 1; 00263 } 00264 00265 00266 //if gga fix is 1 or 2, gga fix is sufficient, return true 00267 if(commaCount == 6){ 00268 if(currentGGAString[index+1] == '1'){ 00269 return true; 00270 } 00271 00272 if(currentGGAString[index+1] == '2'){ 00273 return true; 00274 } 00275 00276 break; 00277 } 00278 00279 index += 1; 00280 00281 } 00282 00283 return false; 00284 }; 00285 00286 //! ParseCurrentLatitudeFromGPRMC, grabs current latitude from current GPRMC string. 00287 /*! 00288 Converts the latitude into decimaldegrees and stores the current latitude. 00289 */ 00290 void NMEA::ParseCurrentLatitudeFromGPRMC(){ 00291 00292 north = false; 00293 south = false; 00294 00295 memset(tmpArrDeg,'\0',7); 00296 memset(tmpArrMin, '\0', 7); 00297 memset(tmpLatitude, '\0', 15); 00298 currentLatitude = ""; 00299 currentLatitude.resize(20); 00300 00301 00302 //Getting Latitude from GPRMC string, assigning to tmpStr 00303 getXFromNMEAString(3,currentGPRMCString); 00304 00305 tmpArrDeg[0] = tmpStr[0]; 00306 tmpArrDeg[1] = tmpStr[1]; 00307 00308 tmpArrMin[0] = tmpStr[2]; 00309 tmpArrMin[1] = tmpStr[3]; 00310 tmpArrMin[2] = tmpStr[4]; 00311 tmpArrMin[3] = tmpStr[5]; 00312 tmpArrMin[4] = tmpStr[6]; 00313 00314 //getting N/S 00315 getXFromNMEAString(4,currentGPRMCString); 00316 if(tmpStr[0] == 'N' || tmpStr[0] == 'n'){ 00317 north = true; 00318 currentLatitude[0] = '+'; 00319 } 00320 00321 if(tmpStr[0] == 'S' || tmpStr[0] == 's'){ 00322 south = true; 00323 currentLatitude[0] = '-'; 00324 } 00325 00326 00327 latitudeDD = ((atof(tmpArrDeg) + (atof(tmpArrMin)/60))); 00328 00329 sprintf(tmpLatitude, "%0.6f",latitudeDD); 00330 for(int i = 0; i < strlen(tmpLatitude); i++){ 00331 currentLatitude[i+1] = tmpLatitude[i]; 00332 } 00333 }; 00334 00335 //! ParseCurrentLongitudeFromGPRMC, grabs current longitude from current GPRMC string. 00336 /*! 00337 Converts the longitude into decimaldegrees and stores the current longitude. 00338 */ 00339 void NMEA::ParseCurrentLongitudeFromGPRMC(){ 00340 00341 east = false; 00342 west = false; 00343 00344 memset(tmpArrDeg,'\0',7); 00345 memset(tmpArrMin, '\0', 7); 00346 memset(tmpLongitude, '\0', 15); 00347 currentLongitude = ""; 00348 currentLongitude.resize(20); 00349 00350 00351 //Getting Longitude from GPRMC string, assigning to tmpStr 00352 getXFromNMEAString(5,currentGPRMCString); 00353 00354 tmpArrDeg[0] = tmpStr[0]; 00355 tmpArrDeg[1] = tmpStr[1]; 00356 tmpArrDeg[2] = tmpStr[2]; 00357 00358 tmpArrMin[0] = tmpStr[3]; 00359 tmpArrMin[1] = tmpStr[4]; 00360 tmpArrMin[2] = tmpStr[5]; 00361 tmpArrMin[3] = tmpStr[6]; 00362 tmpArrMin[4] = tmpStr[7]; 00363 tmpArrMin[5] = tmpStr[8]; 00364 tmpArrMin[6] = tmpStr[9]; 00365 00366 //getting E/W 00367 getXFromNMEAString(6,currentGPRMCString); 00368 if(tmpStr[0] == 'E' || tmpStr[0] == 'e'){ 00369 east = true; 00370 currentLongitude[0] = '+'; 00371 } 00372 if(tmpStr[0] == 'W' || tmpStr[0] == 'w'){ 00373 west = true; 00374 currentLongitude[0] = '-'; 00375 } 00376 00377 longitudeDD = ((atof(tmpArrDeg) + (atof(tmpArrMin)/60))); 00378 00379 sprintf(tmpLongitude, "%0.6f",longitudeDD); 00380 for(int i = 0; i < strlen(tmpLongitude); i++){ 00381 currentLongitude[i+1] = tmpLongitude[i]; 00382 } 00383 00384 }; 00385 00386 00387 //! getXFromNMEAString, grabs desired data column from NMEA string, stores it for further manipulation in tmpStr 00388 /*! 00389 \param desiredCommaCount integer designating which column to store 00390 \param stringToParse string parameter containing the NMEA string. 00391 */ 00392 void NMEA::getXFromNMEAString(int desiredCommaCount, string stringToParse){ 00393 00394 //clearing tmpStr 00395 tmpStr = ""; 00396 tmpStr.resize(15); 00397 char stringLength = strlen(stringToParse.c_str()); 00398 00399 int commaCnt = 0; 00400 int index = 0; 00401 int idx = 0; 00402 00403 while(commaCnt < (desiredCommaCount+1) && (index < stringLength)){ 00404 00405 if(stringToParse[index] == ','){ 00406 commaCnt += 1; 00407 } 00408 00409 if((commaCnt == desiredCommaCount) && (stringToParse[index] != ',')){ 00410 tmpStr[idx] = stringToParse[index]; 00411 idx += 1; 00412 } 00413 00414 index += 1; 00415 } 00416 00417 }; 00418 00419 //! getCurrentTime, getter method returning current time from gps 00420 /*! 00421 \return returns current time from gps in format "HH:MM:SS.FFF" 00422 */ 00423 string NMEA::getCurrentTime(void){ 00424 return this->currentUTCFromGPRMC; 00425 };
Generated on Wed Jul 13 2022 08:04:14 by
