fixedpointnum gpsstringtoangle(char *string) { // takes a gps string and converts it to a fixedpointnum angle // "4807.123" means 48 degrees, 7.123 minutes, south // how many digits are there before the decimal point? int index=0; while (string[index]>='0' && string[index]<='9') ++index; // convert the minutes part. Use two digits before the decimal and 7 digits after fixedpointnum minutes=0; char *ptr=&string[index]-2; for (int count=0;count<10;++count) { if (*ptr=='.') { ++ptr; } else { minutes*=10; if (*ptr) minutes+=(*ptr++) - '0'; } } string[index-2]='\0'; fixedpointnum degrees=lib_fp_stringtolong(string); return((degrees<<(FIXEDPOINTSHIFT+LATLONGEXTRASHIFT))+(lib_fp_multiply(minutes,117281L)>>8)); // 29318L is (2^16 * 2^6 * 2^16 * 2^6)/(60 * 10^7) }
char readgps() { while (lib_serial_numcharsavailable(GPS_SERIAL_PORT)) { char c=lib_serial_getchar(GPS_SERIAL_PORT); if (c=='$') // start of a new message { gpsparameternumber=0; gpsdataindex=0; gpschecksum=0; gpsframetype=0; } else { if (c==',' || c=='*') { // we just finished loading a parameter, interpret it gpsdata[gpsdataindex]='\0'; if (gpsparameternumber == 0) { //frame identification if (gpsdata[0] == 'G' && gpsdata[1] == 'P' && gpsdata[2] == 'G' && gpsdata[3] == 'G' && gpsdata[4] == 'A') gpsframetype=FRAME_GGA; else if (gpsdata[0] == 'G' && gpsdata[1] == 'P' && gpsdata[2] == 'R' && gpsdata[3] == 'M' && gpsdata[4] == 'C') gpsframetype = FRAME_RMC; } else if (gpsframetype == FRAME_GGA) { if (gpsparameternumber == 2) { gpslatitudedegrees = gpsstringtoangle(gpsdata); } else if (gpsparameternumber == 3) { if ( gpsdata[0] == 'S') gpslatitudedegrees=-gpslatitudedegrees; } else if (gpsparameternumber == 4) { gpslongitudedegrees = gpsstringtoangle(gpsdata); } else if (gpsparameternumber == 5) { if ( gpsdata[0] == 'W') gpslongitudedegrees=-gpslongitudedegrees; } else if (gpsparameternumber == 6) { gpsfix = gpsdata[0]-'0'; } else if (gpsparameternumber == 7) { global.gps_num_satelites = lib_fp_stringtolong(gpsdata); } else if (gpsparameternumber == 9) { global.gps_current_altitude = lib_fp_stringtofixedpointnum(gpsdata); } } else if (gpsframetype == FRAME_RMC) { if (gpsparameternumber == 7) { // 1 knot = 0.514444444 m / s global.gps_current_speed=lib_fp_multiply(lib_fp_stringtofixedpointnum(gpsdata),33715L); // 33715L is .514444444 * 2^16 } else if (gpsparameternumber == 8) { // GPS_ground_course = grab_fields(gpsdata,1); } //ground course deg*10 } ++gpsparameternumber; gpsdataindex = 0; // get read for the next parameter if (c == '*') gpsfinalchecksum=gpschecksum; } else if (c == '\r' || c == '\n') { // end of the message unsigned char checksum = hextochar(gpsdata[0]); checksum <<= 4; checksum += hextochar(gpsdata[1]); if (checksum != gpsfinalchecksum || gpsframetype!=FRAME_GGA || !gpsfix) return(0); gpsframetype=0; // so we don't check again global.gps_current_latitude=gpslatitudedegrees; global.gps_current_longitude=gpslongitudedegrees; return(1); // we got a good frame } else if (gpsdataindex<GPSDATASIZE) { gpsdata[gpsdataindex++]=c; } gpschecksum^=c; } } return(0); // no complete data yet }