void buildAndCheckSentence(unsigned char characterIn) { // Full specification for NMEA0138 specifies a maximum sentence length // of 255 characters. We're going to ignore this for half the length as // we shouldn't get anything that big. // This contains the function's state of whether // it is currently building a sentence. // 0 - Awaiting start character ($) // 1 - Building sentence // 2 - Building first checksum character // 3 - Building second checksum character //printf("char: %c\r\n",characterIn); // We start recording a new sentence if we see a dollarsign. // The sentenceIndex is hard-set to 1 so that multiple dollar-signs // keep you at the beginning. if (characterIn == '$') { //printf("start character at least"); sentence[0] = characterIn; sentenceIndex = 1; sentenceState = 1; } else if (sentenceState == 1) { // Record every character that comes in now that we're building a sentence. // Only stop if we run out of room or an asterisk is found. sentence[sentenceIndex++] = characterIn; if (characterIn == '*') { sentenceState = 2; } else if (sentenceIndex > 127) { // If we've filled up the buffer, ignore the entire message as we can't store it all sentenceState = 0; sentenceIndex = 0; } } else if (sentenceState == 2) { // Record the first ASCII-hex character of the checksum byte. checksum = hex2char(characterIn) << 4; sentenceState = 3; } else if (sentenceState == 3) { // Record the second ASCII-hex character of the checksum byte. checksum |= hex2char(characterIn); // Now that we've compiled a complete GPS sentence, let's check the checksum and parse it. // This code currently only supports RMC and GGA messages. if (checksum == getChecksum(sentence, sentenceIndex)) { if (sentence[3] == 'R' && sentence[4] == 'M' && sentence[5] == 'C') { parseRMC(sentence); } else if (sentence[3] == 'G' && sentence[4] == 'G' && sentence[5] == 'A') { parseGGA(sentence); } } // We clear all state variables here regardless of success. sentenceIndex = 0; sentenceState = 0; } }
uint8_t GPS::parse(const char* nmea, const uint32_t now) { //Serial.print("P: "); //Serial.println(nmea); if (*nmea != '$') { return PARSED_ERROR; } if (strstr(nmea, "$GPGGA") == nmea) { if (strlen(nmea) < 65) return PARSED_UNKNOWN; // No fix return parseGGA(nmea, now); } else if (strstr(nmea, "$GPRMC") == nmea) { if (strlen(nmea) < 65) return PARSED_UNKNOWN; // No fix return parseRMC(nmea, now); } else if (strstr(nmea, "$PMTK001") == nmea) { return PARSED_ACK; } return PARSED_UNKNOWN; }
bool GPS::parse(char *field) { if (strcmp(field, "$GPGGA") == 0) { currentSentence = SENTENCE_GGA; currentField = FIELD_TIME; return true; } else if (strcmp(field, "$GPRMC") == 0) { currentSentence = SENTENCE_RMC; currentField = FIELD_TIME; return true; } if (currentSentence == SENTENCE_GGA) return parseGGA(field); if (currentSentence == SENTENCE_RMC) { bool b = parseRMC(field); if (fix && haveFirstLocation == false) { if (currentLatitude > 1.0) lastLatitude = currentLatitude; if (currentLongitude > 1.0) lastLongitude = currentLongitude; if (lastLatitude > 1.0 && lastLongitude > 1.0) { haveFirstLocation = true; } } return b; } return false; }