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.
Dependents: SerialGPS_TestProgram Nucleo_SerialGPS_to_PC Nucleo_SerialGPS_to_PC SensorInterface ... more
SerialGPS.cpp
00001 /** 00002 * Serial GPS module interface driver class (Version 0.0.1) 00003 * This interface driver supports NMEA-0183 serial based modules. 00004 * 00005 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) 00006 * http://shinta.main.jp/ 00007 */ 00008 #include "SerialGPS.h" 00009 00010 /** 00011 * Create. 00012 * 00013 * @param tx A pin of transmit. 00014 * @param rx A pin of receive. 00015 * @param baud Baud rate. (Default = 9600) 00016 */ 00017 SerialGPS::SerialGPS(PinName tx, PinName rx, int baud) : ser(tx, rx), cbfuncs(NULL) { 00018 ser.baud(baud); 00019 ser.setTimeout(50); 00020 } 00021 00022 /** 00023 * Destroy. 00024 */ 00025 SerialGPS::~SerialGPS() { 00026 } 00027 00028 /** 00029 * Processing. 00030 */ 00031 bool SerialGPS::processing() { 00032 /* 00033 * Read from a serial buffer. 00034 */ 00035 static const int DATABUFSIZ = 128; 00036 char src[DATABUFSIZ]; 00037 int cnt = 0; 00038 do { 00039 cnt = 0; 00040 bool done = false; 00041 do { 00042 int c = ser.getc(); 00043 if (c < 0) { 00044 return false; 00045 } 00046 if ((c == '\r') || (c == '\n')) { 00047 done = true; 00048 c = '\0'; 00049 } 00050 src[cnt++] = c & 0xff; 00051 } while (!done); 00052 } while (cnt <= 1); 00053 00054 /* 00055 * Return if the callback function does not exists. 00056 */ 00057 if (cbfuncs == NULL) { 00058 return true; 00059 } 00060 00061 /* 00062 * Call a function for logging data. 00063 */ 00064 if (cbfuncs->cbfunc_log != NULL) { 00065 cbfuncs->cbfunc_log(src); 00066 } 00067 00068 /* 00069 * Check a check sum for the data. The data format is '$[DATA]*CS'. 00070 */ 00071 const size_t srclen = strlen(src); 00072 if ((src[0] == '$') && (src[srclen - 3] == '*')) { 00073 int cs_src; 00074 if (sscanf(src + srclen - 2, "%X", &cs_src) != 1) { 00075 printf("Invalid check sum data found.(%s)\n", src); 00076 return false; 00077 } 00078 uint8_t cs_cal = calcCheckSum(src + 1, srclen - 4); 00079 if ((uint8_t)cs_src != cs_cal) { 00080 printf("Illegal data found.(%s)\n", src); 00081 return false; 00082 } 00083 } else { 00084 printf("Invalid data format found.(%s)\n", src); 00085 return false; 00086 } 00087 00088 /* 00089 * Parse a data. 00090 */ 00091 int res = 0; 00092 char *p = src; 00093 char des[DATABUFSIZ]; 00094 if ((p = parse(p, des, sizeof(des), ",*")) != NULL) { 00095 if (strcmp(des, "$GPGGA") == 0) { 00096 res = parseAndCallbackGGA(src, cbfuncs); 00097 } else if (strcmp(des, "$GPGSA") == 0) { 00098 res = parseAndCallbackGSA(src, cbfuncs); 00099 } else if (strcmp(des, "$GPRMC") == 0) { 00100 res = parseAndCallbackRMC(src, cbfuncs); 00101 } else if (strcmp(des, "$GPGSV") == 0) { 00102 res = parseAndCallbackGSV(src, cbfuncs); 00103 } else { 00104 res = parseAndCallbackUnknown(src, cbfuncs); 00105 } 00106 } 00107 return (res == 0) ? true : false; 00108 } 00109 00110 /** 00111 * Attach a callback function. 00112 * 00113 * @param cbfuncs A pointer to a callback function structure. 00114 */ 00115 void SerialGPS::attach(gps_callback_t *cbfuncs) { 00116 SerialGPS::cbfuncs = cbfuncs; 00117 } 00118 00119 /** 00120 * Detach a callback function. 00121 */ 00122 void SerialGPS::detach(void) { 00123 SerialGPS::cbfuncs = NULL; 00124 } 00125 00126 /** 00127 * Parse a text string. 00128 */ 00129 char * SerialGPS::parse(char *src, char *des, size_t dessiz, char *delim) { 00130 for (int i = 0; i < dessiz; i++, src++, des++) { 00131 if ((*src == '\0') || (*src == '\r') || (*src == '\n')) { 00132 *des = '\0'; 00133 return NULL; 00134 } 00135 if (exists(*src, delim)) { 00136 *des = '\0'; 00137 return ++src; 00138 } 00139 *des = *src; 00140 } 00141 des = '\0'; 00142 return NULL; 00143 } 00144 00145 int SerialGPS::parseAndCallbackGGA(char *src, gps_callback_t *cbfuncs) { 00146 00147 if (cbfuncs->cbfunc_gga == NULL) { 00148 return -1; 00149 } 00150 00151 char plist[PARAM_ARRAYSIZE][PARAM_TXTMAXLEN]; 00152 char *p = src; 00153 int cnt = 0; 00154 while ((p = parse(p, plist[cnt], PARAM_TXTMAXLEN, ",*")) != NULL) { 00155 cnt++; 00156 } 00157 00158 if (cnt == 15) { 00159 gps_gga_t data; 00160 data.hour = (plist[1][0] - '0') * 10 + (plist[1][1] - '0') * 1; 00161 data.min = (plist[1][2] - '0') * 10 + (plist[1][3] - '0') * 1; 00162 data.sec = (plist[1][4] - '0') * 10 + (plist[1][5] - '0') * 1; 00163 00164 if (sscanf(plist[2], "%lf", &data.latitude) != 1) { 00165 return -2; 00166 } 00167 if (sscanf(plist[3], "%c", &data.ns) != 1) { 00168 return -3; 00169 } 00170 const char ns = data.ns; 00171 if ((ns != 'N') && (ns != 'S')) { 00172 return -4; 00173 } 00174 if (sscanf(plist[4], "%lf", &data.longitude) != 1) { 00175 return -5; 00176 } 00177 if (sscanf(plist[5], "%c", &data.ew) != 1) { 00178 return -6; 00179 } 00180 const char ew = data.ew; 00181 if ((ew != 'E') && (ew != 'W')) { 00182 return -7; 00183 } 00184 00185 data.position_fix = atoi(plist[6]); 00186 data.satellites_used = atoi(plist[7]); 00187 00188 if (sscanf(plist[8], "%lf", &data.hdop) != 1) { 00189 return -8; 00190 } 00191 00192 data.altitude = atoi(plist[9]); 00193 if (strcmp(plist[10], "M") != 0) { 00194 return -9; 00195 } 00196 00197 data.altitude = atoi(plist[11]); 00198 if (sscanf(plist[12], "%c", &data.altitude_unit) != 1) { 00199 return -10; 00200 } 00201 00202 cbfuncs->cbfunc_gga(&data); 00203 return 0; 00204 } 00205 return -11; 00206 } 00207 00208 int SerialGPS::parseAndCallbackGSA(char *src, gps_callback_t *cbfuncs) { 00209 00210 if (cbfuncs->cbfunc_gsa == NULL) { 00211 return -1; 00212 } 00213 00214 char plist[PARAM_ARRAYSIZE][PARAM_TXTMAXLEN]; 00215 char *p = src; 00216 int cnt = 0; 00217 while ((p = parse(p, plist[cnt], PARAM_TXTMAXLEN, ",*")) != NULL) { 00218 cnt++; 00219 } 00220 00221 if (cnt == 18) { 00222 gps_gsa_t data; 00223 data.selmode = plist[1][0]; 00224 if ((data.selmode != 'A') && (data.selmode != 'M')) { 00225 return -2; 00226 } 00227 00228 data.fix = atoi(plist[2]); 00229 if ((data.fix != 1) && (data.fix != 2) && (data.fix != 3)) { 00230 return -3; 00231 } 00232 00233 cbfuncs->cbfunc_gsa(&data); 00234 return 0; 00235 } 00236 return -4; 00237 } 00238 00239 int SerialGPS::parseAndCallbackRMC(char *src, gps_callback_t *cbfuncs) { 00240 00241 if (cbfuncs->cbfunc_rmc == NULL) { 00242 return -1; 00243 } 00244 00245 char plist[PARAM_ARRAYSIZE][PARAM_TXTMAXLEN]; 00246 char *p = src; 00247 int cnt = 0; 00248 while ((p = parse(p, plist[cnt], PARAM_TXTMAXLEN, ",*")) != NULL) { 00249 cnt++; 00250 } 00251 00252 if (cnt == 13) { 00253 gps_rmc_t data; 00254 data.hour = (plist[1][0] - '0') * 10 + (plist[1][1] - '0') * 1; 00255 data.min = (plist[1][2] - '0') * 10 + (plist[1][3] - '0') * 1; 00256 data.sec = (plist[1][4] - '0') * 10 + (plist[1][5] - '0') * 1; 00257 00258 data.status = plist[2][0]; 00259 00260 if (sscanf(plist[3], "%lf", &data.nl) != 1) { 00261 return -2; 00262 } 00263 if (strcmp(plist[4], "N") != 0) { 00264 return -3; 00265 } 00266 00267 if (sscanf(plist[5], "%lf", &data.el) != 1) { 00268 return -4; 00269 } 00270 if (strcmp(plist[6], "E") != 0) { 00271 return -5; 00272 } 00273 00274 cbfuncs->cbfunc_rmc(&data); 00275 return 0; 00276 } 00277 return -4; 00278 } 00279 00280 int SerialGPS::parseAndCallbackGSV(char *src, gps_callback_t *cbfuncs) { 00281 00282 if (cbfuncs->cbfunc_gsv == NULL) { 00283 return -1; 00284 } 00285 00286 char plist[PARAM_ARRAYSIZE][PARAM_TXTMAXLEN]; 00287 char *p = src; 00288 int cnt = 0; 00289 while ((p = parse(p, plist[cnt], PARAM_TXTMAXLEN, ",*")) != NULL) { 00290 cnt++; 00291 } 00292 00293 if (cnt == 20) { 00294 gps_gsv_t data; 00295 data.msgcnt = atoi(plist[1]); 00296 00297 data.msgnum = atoi(plist[2]); 00298 00299 data.satcnt = atoi(plist[3]); 00300 00301 static const int SATINFOFS = 4; 00302 for (int i = 0; i < 4; i++) { 00303 data.satellite[i].num = atoi(plist[SATINFOFS + 0 * (i * 4)]); 00304 data.satellite[i].elevation = atoi(plist[SATINFOFS + 1 * (i * 4)]); 00305 data.satellite[i].azimuth = atoi(plist[SATINFOFS + 2 * (i * 4)]); 00306 data.satellite[i].snr = atoi(plist[SATINFOFS + 3 *(i * 4)]); 00307 } 00308 00309 int chksum; 00310 if (sscanf(plist[20], "%x", &chksum) != 1) { 00311 return -2; 00312 } 00313 00314 cbfuncs->cbfunc_gsv(&data); 00315 return 0; 00316 } 00317 return -3; 00318 } 00319 00320 int SerialGPS::parseAndCallbackUnknown(char *src, gps_callback_t *cbfuncs) { 00321 return 0; 00322 } 00323 00324 uint8_t SerialGPS::calcCheckSum(char *buf, size_t siz) { 00325 uint8_t cs = 0; 00326 for (int i = 0; i < siz; i++) { 00327 cs ^= buf[i]; 00328 } 00329 return cs; 00330 }
Generated on Thu Jul 14 2022 00:05:48 by
1.7.2
Grove GPS