Example code for reading from a serial GPS unit & parsing an RMC GPS string to a struct.

Dependencies:   mbed

Fork of mbed_blinky by Mbed

Committer:
HackerLabATTKit01
Date:
Tue Mar 14 21:22:36 2017 +0000
Revision:
20:a728f1075fb1
Parent:
19:cbacec32ae4b
Added comment option for using MODSERIAL instead of Serial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HackerLabATTKit01 16:1bf12f0bb4b9 1 #define TIMEMAX 6
HackerLabATTKit01 16:1bf12f0bb4b9 2 #define LATMAX 20
HackerLabATTKit01 16:1bf12f0bb4b9 3 #define LONGMAX 20
HackerLabATTKit01 16:1bf12f0bb4b9 4 #define SPEEDMAX 6
HackerLabATTKit01 16:1bf12f0bb4b9 5 #define TRACKMAX 6
HackerLabATTKit01 16:1bf12f0bb4b9 6 #define DATEMAX 6
HackerLabATTKit01 16:1bf12f0bb4b9 7 #define MAGVARMAX 6
HackerLabATTKit01 16:1bf12f0bb4b9 8 #define CHECKSUMMAX 10
HackerLabATTKit01 16:1bf12f0bb4b9 9 #define DEVNULMAX 20
HackerLabATTKit01 16:1bf12f0bb4b9 10
HackerLabATTKit01 16:1bf12f0bb4b9 11 #define CRLF2 "\n\r"
HackerLabATTKit01 16:1bf12f0bb4b9 12
HackerLabATTKit01 16:1bf12f0bb4b9 13 /** Tfile provides a means for parsing serially received GPRMC sentences into a location struct **/
HackerLabATTKit01 16:1bf12f0bb4b9 14
HackerLabATTKit01 16:1bf12f0bb4b9 15 typedef struct {
HackerLabATTKit01 16:1bf12f0bb4b9 16 char time[TIMEMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 17 char status;
HackerLabATTKit01 16:1bf12f0bb4b9 18 char latitude[LATMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 19 double dlatitude;
HackerLabATTKit01 16:1bf12f0bb4b9 20 char latdir;
HackerLabATTKit01 16:1bf12f0bb4b9 21 char longitude[LONGMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 22 double dlongitude;
HackerLabATTKit01 16:1bf12f0bb4b9 23 char longdir;
HackerLabATTKit01 16:1bf12f0bb4b9 24 char speed[SPEEDMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 25 char trackangle[TRACKMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 26 char date[DATEMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 27 char magvar[MAGVARMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 28 char magvardir;
HackerLabATTKit01 16:1bf12f0bb4b9 29 //char checksum[CHECKSUMMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 30 } GPRMCSentence;
HackerLabATTKit01 16:1bf12f0bb4b9 31
HackerLabATTKit01 16:1bf12f0bb4b9 32 double charStrToDouble(char* str) {
HackerLabATTKit01 16:1bf12f0bb4b9 33 uint16_t decpos = 0;
HackerLabATTKit01 16:1bf12f0bb4b9 34 double num = 0.0;
HackerLabATTKit01 16:1bf12f0bb4b9 35 while((str[decpos]!='.')&&(str[decpos]!='\0')) decpos++;
HackerLabATTKit01 16:1bf12f0bb4b9 36 double multiplier = 1.0;
HackerLabATTKit01 16:1bf12f0bb4b9 37 for(uint16_t i = 1;(decpos-i)>=0;i++) {
HackerLabATTKit01 16:1bf12f0bb4b9 38 num += (multiplier*(str[decpos-i]-48));
HackerLabATTKit01 16:1bf12f0bb4b9 39 multiplier *= 10.0;
HackerLabATTKit01 16:1bf12f0bb4b9 40 }
HackerLabATTKit01 16:1bf12f0bb4b9 41 multiplier = (1.0/10.0);
HackerLabATTKit01 16:1bf12f0bb4b9 42 for(uint16_t i = 1;str[decpos+i]!='\0';i++) {
HackerLabATTKit01 16:1bf12f0bb4b9 43 num += (multiplier*(str[decpos+i]-48));
HackerLabATTKit01 16:1bf12f0bb4b9 44 multiplier /= 10.0;
HackerLabATTKit01 16:1bf12f0bb4b9 45 }
HackerLabATTKit01 16:1bf12f0bb4b9 46 return num;
HackerLabATTKit01 16:1bf12f0bb4b9 47 }
HackerLabATTKit01 16:1bf12f0bb4b9 48
HackerLabATTKit01 16:1bf12f0bb4b9 49 uint16_t parseStringToGPRMCStructEntry(char* gprmcstr, char* gprmcentry, uint16_t start, uint16_t length) {
HackerLabATTKit01 16:1bf12f0bb4b9 50 int16_t i=0;
HackerLabATTKit01 16:1bf12f0bb4b9 51 while((gprmcstr[start] != ',') &&
HackerLabATTKit01 16:1bf12f0bb4b9 52 (gprmcstr[start] != '\0') &&
HackerLabATTKit01 16:1bf12f0bb4b9 53 (gprmcstr[start] != '\n') &&
HackerLabATTKit01 16:1bf12f0bb4b9 54 (i < length)) {
HackerLabATTKit01 16:1bf12f0bb4b9 55 gprmcentry[i] = gprmcstr[start];
HackerLabATTKit01 16:1bf12f0bb4b9 56 start++;i++;
HackerLabATTKit01 16:1bf12f0bb4b9 57 }
HackerLabATTKit01 16:1bf12f0bb4b9 58 while(i<=length) {
HackerLabATTKit01 16:1bf12f0bb4b9 59 gprmcentry[i] = '\0';
HackerLabATTKit01 16:1bf12f0bb4b9 60 i++;
HackerLabATTKit01 16:1bf12f0bb4b9 61 }
HackerLabATTKit01 16:1bf12f0bb4b9 62 return start + 1;
HackerLabATTKit01 16:1bf12f0bb4b9 63 }
HackerLabATTKit01 16:1bf12f0bb4b9 64
HackerLabATTKit01 16:1bf12f0bb4b9 65 void moveDecimalLeft(char* num, uint16_t places) {
HackerLabATTKit01 16:1bf12f0bb4b9 66 if (places == 0) return;
HackerLabATTKit01 16:1bf12f0bb4b9 67 else places--;
HackerLabATTKit01 16:1bf12f0bb4b9 68 uint16_t i = 0;
HackerLabATTKit01 16:1bf12f0bb4b9 69 while(num[i] != '\0') {
HackerLabATTKit01 16:1bf12f0bb4b9 70 if ((i >= places) && (num[i] == '.')) {
HackerLabATTKit01 16:1bf12f0bb4b9 71 uint16_t j;
HackerLabATTKit01 16:1bf12f0bb4b9 72 for(j=i;j>(i-places);j--) num[j] = num[j-1];
HackerLabATTKit01 16:1bf12f0bb4b9 73 num[j] = num[j-1];
HackerLabATTKit01 16:1bf12f0bb4b9 74 num[j-1] = '.';
HackerLabATTKit01 16:1bf12f0bb4b9 75 break;
HackerLabATTKit01 16:1bf12f0bb4b9 76 }
HackerLabATTKit01 16:1bf12f0bb4b9 77 else i++;
HackerLabATTKit01 16:1bf12f0bb4b9 78 }
HackerLabATTKit01 16:1bf12f0bb4b9 79 }
HackerLabATTKit01 16:1bf12f0bb4b9 80
HackerLabATTKit01 16:1bf12f0bb4b9 81 void negateCharStrNumber(char* num, uint16_t len) {
HackerLabATTKit01 16:1bf12f0bb4b9 82 for(uint16_t i=(len-1); i>0;i--) num[i] = num[i-1];
HackerLabATTKit01 16:1bf12f0bb4b9 83 num[0] = '-';
HackerLabATTKit01 16:1bf12f0bb4b9 84 }
HackerLabATTKit01 16:1bf12f0bb4b9 85
HackerLabATTKit01 16:1bf12f0bb4b9 86 /************************
HackerLabATTKit01 16:1bf12f0bb4b9 87 parseGPRMCStrToStruct:
HackerLabATTKit01 16:1bf12f0bb4b9 88
HackerLabATTKit01 16:1bf12f0bb4b9 89 In: gprmcstr: raw char array string of gprmc sentence
HackerLabATTKit01 16:1bf12f0bb4b9 90 In: GPRMCSentece: struct object representing gprmc sentence to parse to
HackerLabATTKit01 16:1bf12f0bb4b9 91
HackerLabATTKit01 16:1bf12f0bb4b9 92 Out: integer: < 0 : not a gprmc sentence
HackerLabATTKit01 16:1bf12f0bb4b9 93 = 0 : not valid
HackerLabATTKit01 16:1bf12f0bb4b9 94 > 0 : valid
HackerLabATTKit01 16:1bf12f0bb4b9 95
HackerLabATTKit01 16:1bf12f0bb4b9 96 */
HackerLabATTKit01 16:1bf12f0bb4b9 97 int8_t parseGPRMCStrToStruct(char* gprmcstr, GPRMCSentence* gprmstruct) {
HackerLabATTKit01 16:1bf12f0bb4b9 98 uint16_t pos = 7;
HackerLabATTKit01 16:1bf12f0bb4b9 99 char devnull[DEVNULMAX+1];
HackerLabATTKit01 16:1bf12f0bb4b9 100 if ((gprmcstr[0] == '$') &&
HackerLabATTKit01 16:1bf12f0bb4b9 101 (gprmcstr[1] == 'G') &&
HackerLabATTKit01 16:1bf12f0bb4b9 102 (gprmcstr[2] == 'P') &&
HackerLabATTKit01 16:1bf12f0bb4b9 103 (gprmcstr[3] == 'R') &&
HackerLabATTKit01 16:1bf12f0bb4b9 104 (gprmcstr[4] == 'M') &&
HackerLabATTKit01 16:1bf12f0bb4b9 105 (gprmcstr[5] == 'C') &&
HackerLabATTKit01 16:1bf12f0bb4b9 106 (gprmcstr[6] == ',')) {
HackerLabATTKit01 16:1bf12f0bb4b9 107 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->time,pos,TIMEMAX);
HackerLabATTKit01 19:cbacec32ae4b 108 if (gprmcstr[pos] != ',') pos = parseStringToGPRMCStructEntry(gprmcstr,devnull,pos,DEVNULMAX); // to get rid of time decimal, needed for some gps modules
HackerLabATTKit01 16:1bf12f0bb4b9 109 if (gprmcstr[pos] != ',') {gprmstruct->status = gprmcstr[pos];pos++;}
HackerLabATTKit01 16:1bf12f0bb4b9 110 else gprmstruct->status = '\0';
HackerLabATTKit01 16:1bf12f0bb4b9 111 pos++;
HackerLabATTKit01 16:1bf12f0bb4b9 112
HackerLabATTKit01 16:1bf12f0bb4b9 113 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->latitude,pos,LATMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 114 moveDecimalLeft(gprmstruct->latitude,2);
HackerLabATTKit01 16:1bf12f0bb4b9 115 gprmstruct->dlatitude = charStrToDouble(gprmstruct->latitude);
HackerLabATTKit01 16:1bf12f0bb4b9 116 if (gprmcstr[pos] != ',') {gprmstruct->latdir = gprmcstr[pos];pos++;}
HackerLabATTKit01 16:1bf12f0bb4b9 117 else gprmstruct->latdir = '\0';
HackerLabATTKit01 16:1bf12f0bb4b9 118 if(gprmstruct->latdir == 'S') {
HackerLabATTKit01 16:1bf12f0bb4b9 119 negateCharStrNumber(gprmstruct->latitude, LATMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 120 gprmstruct->dlatitude *= -1;
HackerLabATTKit01 16:1bf12f0bb4b9 121 }
HackerLabATTKit01 16:1bf12f0bb4b9 122 pos++;
HackerLabATTKit01 16:1bf12f0bb4b9 123
HackerLabATTKit01 16:1bf12f0bb4b9 124 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->longitude,pos,LONGMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 125 moveDecimalLeft(gprmstruct->longitude,2);
HackerLabATTKit01 16:1bf12f0bb4b9 126 gprmstruct->dlongitude = charStrToDouble(gprmstruct->longitude);
HackerLabATTKit01 16:1bf12f0bb4b9 127 if (gprmcstr[pos] != ',') {gprmstruct->longdir = gprmcstr[pos];pos++;}
HackerLabATTKit01 16:1bf12f0bb4b9 128 else gprmstruct->longdir = '\0';
HackerLabATTKit01 16:1bf12f0bb4b9 129 if(gprmstruct->longdir == 'W') {
HackerLabATTKit01 16:1bf12f0bb4b9 130 negateCharStrNumber(gprmstruct->longitude, LONGMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 131 gprmstruct->dlongitude *= -1;
HackerLabATTKit01 16:1bf12f0bb4b9 132 }
HackerLabATTKit01 16:1bf12f0bb4b9 133 pos++;
HackerLabATTKit01 16:1bf12f0bb4b9 134
HackerLabATTKit01 16:1bf12f0bb4b9 135 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->speed,pos,SPEEDMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 136 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->trackangle,pos,TRACKMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 137 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->date,pos,DATEMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 138 pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->magvar,pos,MAGVARMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 139 if (gprmcstr[pos] != ',') {gprmstruct->magvardir = gprmcstr[pos];pos++;}
HackerLabATTKit01 16:1bf12f0bb4b9 140 else gprmstruct->magvardir = '\0';
HackerLabATTKit01 16:1bf12f0bb4b9 141 pos++;
HackerLabATTKit01 16:1bf12f0bb4b9 142 //pos = parseStringToGPRMCStructEntry(gprmcstr,gprmstruct->checksum,pos,CHECKSUMMAX);
HackerLabATTKit01 16:1bf12f0bb4b9 143 if (gprmstruct->status == 'A') return 1;
HackerLabATTKit01 16:1bf12f0bb4b9 144 else return 0;
HackerLabATTKit01 16:1bf12f0bb4b9 145 }
HackerLabATTKit01 16:1bf12f0bb4b9 146 else return -1;
HackerLabATTKit01 16:1bf12f0bb4b9 147 }
HackerLabATTKit01 16:1bf12f0bb4b9 148
HackerLabATTKit01 16:1bf12f0bb4b9 149 void printGPRMCSentence(GPRMCSentence* gprmcstruct, Serial *serial) {
HackerLabATTKit01 16:1bf12f0bb4b9 150 serial->printf("Time: %s" CRLF2,gprmcstruct->time);
HackerLabATTKit01 16:1bf12f0bb4b9 151 serial->printf("Status: %c" CRLF2,gprmcstruct->status);
HackerLabATTKit01 16:1bf12f0bb4b9 152 serial->printf("Lat: %s" CRLF2,gprmcstruct->latitude);
HackerLabATTKit01 16:1bf12f0bb4b9 153 serial->printf("LatDir: %c" CRLF2,gprmcstruct->latdir);
HackerLabATTKit01 16:1bf12f0bb4b9 154 serial->printf("Long: %s" CRLF2,gprmcstruct->longitude);
HackerLabATTKit01 16:1bf12f0bb4b9 155 serial->printf("LongDir: %c" CRLF2,gprmcstruct->longdir);
HackerLabATTKit01 16:1bf12f0bb4b9 156 serial->printf("Speed: %s" CRLF2,gprmcstruct->speed);
HackerLabATTKit01 16:1bf12f0bb4b9 157 serial->printf("Angle: %s" CRLF2,gprmcstruct->trackangle);
HackerLabATTKit01 16:1bf12f0bb4b9 158 serial->printf("Date: %s" CRLF2,gprmcstruct->date);
HackerLabATTKit01 16:1bf12f0bb4b9 159 serial->printf("MagVar: %s" CRLF2,gprmcstruct->magvar);
HackerLabATTKit01 16:1bf12f0bb4b9 160 serial->printf("MagDir: %c" CRLF2,gprmcstruct->magvardir);
HackerLabATTKit01 16:1bf12f0bb4b9 161 }