Example code for reading from a serial GPS unit & parsing an RMC GPS string to a struct.
Fork of mbed_blinky by
GPRMCSentence.h
- Committer:
- HackerLabATTKit01
- Date:
- 2017-03-14
- Revision:
- 20:a728f1075fb1
- Parent:
- 19:cbacec32ae4b
File content as of revision 20:a728f1075fb1:
#define TIMEMAX 6 #define LATMAX 20 #define LONGMAX 20 #define SPEEDMAX 6 #define TRACKMAX 6 #define DATEMAX 6 #define MAGVARMAX 6 #define CHECKSUMMAX 10 #define DEVNULMAX 20 #define CRLF2 "\n\r" /** Tfile provides a means for parsing serially received GPRMC sentences into a location struct **/ typedef struct { char time[TIMEMAX+1]; char status; char latitude[LATMAX+1]; double dlatitude; char latdir; char longitude[LONGMAX+1]; double dlongitude; char longdir; char speed[SPEEDMAX+1]; char trackangle[TRACKMAX+1]; char date[DATEMAX+1]; char magvar[MAGVARMAX+1]; char magvardir; //char checksum[CHECKSUMMAX+1]; } GPRMCSentence; double charStrToDouble(char* str) { uint16_t decpos = 0; double num = 0.0; while((str[decpos]!='.')&&(str[decpos]!='\0')) decpos++; double multiplier = 1.0; for(uint16_t i = 1;(decpos-i)>=0;i++) { num += (multiplier*(str[decpos-i]-48)); multiplier *= 10.0; } multiplier = (1.0/10.0); for(uint16_t i = 1;str[decpos+i]!='\0';i++) { num += (multiplier*(str[decpos+i]-48)); multiplier /= 10.0; } return num; } uint16_t parseStringToGPRMCStructEntry(char* gprmcstr, char* gprmcentry, uint16_t start, uint16_t length) { int16_t i=0; while((gprmcstr[start] != ',') && (gprmcstr[start] != '\0') && (gprmcstr[start] != '\n') && (i < length)) { gprmcentry[i] = gprmcstr[start]; start++;i++; } while(i<=length) { gprmcentry[i] = '\0'; i++; } return start + 1; } void moveDecimalLeft(char* num, uint16_t places) { if (places == 0) return; else places--; uint16_t i = 0; while(num[i] != '\0') { if ((i >= places) && (num[i] == '.')) { uint16_t j; for(j=i;j>(i-places);j--) num[j] = num[j-1]; num[j] = num[j-1]; num[j-1] = '.'; break; } else i++; } } void negateCharStrNumber(char* num, uint16_t len) { for(uint16_t i=(len-1); i>0;i--) num[i] = num[i-1]; num[0] = '-'; } /************************ parseGPRMCStrToStruct: In: gprmcstr: raw char array string of gprmc sentence In: GPRMCSentece: struct object representing gprmc sentence to parse to Out: integer: < 0 : not a gprmc sentence = 0 : not valid > 0 : valid */ int8_t parseGPRMCStrToStruct(char* gprmcstr, GPRMCSentence* gprmstruct) { uint16_t pos = 7; char devnull[DEVNULMAX+1]; if ((gprmcstr[0] == '$') && (gprmcstr[1] == 'G') && (gprmcstr[2] == 'P') && (gprmcstr[3] == 'R') && (gprmcstr[4] == 'M') && (gprmcstr[5] == 'C') && (gprmcstr[6] == ',')) { pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->time,pos,TIMEMAX); if (gprmcstr[pos] != ',') pos = parseStringToGPRMCStructEntry(gprmcstr,devnull,pos,DEVNULMAX); // to get rid of time decimal, needed for some gps modules if (gprmcstr[pos] != ',') {gprmstruct->status = gprmcstr[pos];pos++;} else gprmstruct->status = '\0'; pos++; pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->latitude,pos,LATMAX); moveDecimalLeft(gprmstruct->latitude,2); gprmstruct->dlatitude = charStrToDouble(gprmstruct->latitude); if (gprmcstr[pos] != ',') {gprmstruct->latdir = gprmcstr[pos];pos++;} else gprmstruct->latdir = '\0'; if(gprmstruct->latdir == 'S') { negateCharStrNumber(gprmstruct->latitude, LATMAX); gprmstruct->dlatitude *= -1; } pos++; pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->longitude,pos,LONGMAX); moveDecimalLeft(gprmstruct->longitude,2); gprmstruct->dlongitude = charStrToDouble(gprmstruct->longitude); if (gprmcstr[pos] != ',') {gprmstruct->longdir = gprmcstr[pos];pos++;} else gprmstruct->longdir = '\0'; if(gprmstruct->longdir == 'W') { negateCharStrNumber(gprmstruct->longitude, LONGMAX); gprmstruct->dlongitude *= -1; } pos++; pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->speed,pos,SPEEDMAX); pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->trackangle,pos,TRACKMAX); pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->date,pos,DATEMAX); pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->magvar,pos,MAGVARMAX); if (gprmcstr[pos] != ',') {gprmstruct->magvardir = gprmcstr[pos];pos++;} else gprmstruct->magvardir = '\0'; pos++; //pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->checksum,pos,CHECKSUMMAX); if (gprmstruct->status == 'A') return 1; else return 0; } else return -1; } void printGPRMCSentence(GPRMCSentence* gprmcstruct, Serial *serial) { serial->printf("Time: %s" CRLF2,gprmcstruct->time); serial->printf("Status: %c" CRLF2,gprmcstruct->status); serial->printf("Lat: %s" CRLF2,gprmcstruct->latitude); serial->printf("LatDir: %c" CRLF2,gprmcstruct->latdir); serial->printf("Long: %s" CRLF2,gprmcstruct->longitude); serial->printf("LongDir: %c" CRLF2,gprmcstruct->longdir); serial->printf("Speed: %s" CRLF2,gprmcstruct->speed); serial->printf("Angle: %s" CRLF2,gprmcstruct->trackangle); serial->printf("Date: %s" CRLF2,gprmcstruct->date); serial->printf("MagVar: %s" CRLF2,gprmcstruct->magvar); serial->printf("MagDir: %c" CRLF2,gprmcstruct->magvardir); }