Slightly modified version of the SerialGPS library (https://os.mbed.com/teams/components/code/SerialGPS/) to support the BufferedSerial class
Diff: SerialGPS.cpp
- Revision:
- 3:ebd79e3acf14
- Parent:
- 2:e7f24389167b
- Child:
- 4:2c76f1ec13a9
--- a/SerialGPS.cpp Tue Feb 16 16:48:14 2021 +0100 +++ b/SerialGPS.cpp Tue Mar 02 18:27:46 2021 +0100 @@ -28,56 +28,96 @@ _gps_p(new BufferedSerial(tx, rx, baud)), _gps(*_gps_p) { - longitude = 0.0; - latitude = 0.0; + this->_gps_p->set_baud(baud); + this->_UTCtime = 0.0; + this->_lat = 0.0; + this->_lon = 0.0; + this->_lock = 0; + this->_fix = false; +} + +SerialGPS::SerialGPS(BufferedSerial* serial) + : + _gps_p(serial), + _gps(*_gps_p) +{ + this->_UTCtime = 0.0; + this->_lat = 0.0; + this->_lon = 0.0; + this->_lock = 0; + this->_fix = false; } -int SerialGPS::sample() +bool SerialGPS::fix() +{ + return this->_fix; +} + +float SerialGPS::get_lat() { - char ns, ew, unit; - int lock; + return this->_lat; +} + +float SerialGPS::get_lon() +{ + return this->_lon; +} - while(1) - { +void SerialGPS::send_command(const char* cmd) +{ + this->_gps_p->write(cmd, sizeof(cmd)); +} + +void SerialGPS::read() +{ getline(); - // Check if it is a GPGGA msg (matches both locked and non-locked msg) - if(sscanf(msg, "GPGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f", &time, &latitude, &ns, &longitude, &ew, &lock, &sats, &hdop, &alt, &unit, &geoid) >= 1) - { - if(!lock) + //printf("NMEA sentence: %s\n", this->_nmea); + + // GPRMC sentence: UTC time, status, lat, N/S, lon, E/W, speed, course, date + if(sscanf(this->_nmea, "GPRMC,%f,%c,%f,%c,%f,%c", &this->_UTCtime, &this->_status, &this->_lat, &this->_NS, &this->_lon, &this->_EW) > 0) + { + if(this->_status != 'A') + { + this->_fix = false; + } + else { - time = 0.0; - longitude = 0.0; - latitude = 0.0; - sats = 0; - hdop = 0.0; - alt = 0.0; - geoid = 0.0; - - return 0; - } + set_vals(); + } + } + // GPGGA sentence: UTC time, lat, N/S, lon, E/W, fix indicator + else if(sscanf(this->_nmea, "GPGGA,%f,%f,%c,%f,%c,%d", &this->_UTCtime, &this->_lat, &this->_NS, &this->_lon, &this->_EW, &this->_lock) > 0) + { + if(!this->_lock) + { + this->_fix = false; + } else { - //GPGGA format according http://aprs.gids.nl/nmea/#gga - // time (float), lat (f), (N/S) (c), long (f), (E/W) (c), fix (d), sats (d), - // hdop (float), altitude (float), M, geoid (float), M, , , - //GPGGA,092010.000,5210.9546,N,00008.8913,E,1,07,1.3,9.7,M,47.0,M,,0000*5D - - if(ns == 'S') { latitude *= -1.0; } - if(ew == 'W') { longitude *= -1.0; } - - float degrees = trunc(latitude / 100.0f); - float minutes = latitude - (degrees * 100.0f); - - latitude = degrees + minutes / 60.0f; - degrees = trunc(longitude / 100.0f * 0.01f); - minutes = longitude - (degrees * 100.0f); - longitude = degrees + minutes / 60.0f; - - return 1; + set_vals(); } } - } + // GPGLL sentence: lat, N/S, lo, E/W, UTC time, status + else if(sscanf(this->_nmea, "GPGLL,%f,%c,%f,%c,%f,%c", &this->_lat, &this->_NS, &this->_lon, &this->_EW, &this->_UTCtime, &this->_status) > 0) + { + if(this->_status != 'A') + { + this->_fix = false; + } + else + { + set_vals(); + } + } + else + { + //printf("No NMEA sentence found"); + this->_fix = false; + } + + // Clear the NMEA buffer + strcpy(this->_nmea, ""); } float SerialGPS::trunc(float v) @@ -95,29 +135,51 @@ return v; } +void SerialGPS::set_vals() +{ + if(this->_NS == 'S') { this->_lat *= -1.0; } + if(this->_EW == 'W') { this->_lon *= -1.0; } + + float degrees = trunc(_lat / 100.0f); + float minutes = this->_lat *= -1.0; + + this->_lat = degrees + minutes / 60.0f; + degrees = trunc(this->_lon / 100.0f * 0.01f); + minutes = this->_lon - (degrees * 100.0f); + this->_lon = degrees + minutes / 60.0f; + this->_fix = true; +} + void SerialGPS::getline() { char ch; - int idx = 0; + int idx = -1; + + if(!this->_gps_p->readable()) + { + return; + } - while(1) + // Wait for start of sentence + while(read_char() != '$'); + + // Read from serial one char at a time until max length or read terminal + while(idx++ <= MAX_LINELENGTH) { - _gps.read(&ch, 1); - if(ch != '$') + ch = read_char(); + + if(ch == '\r') { - while(idx++ < 256) - { - if(ch == '\r') - { - msg[idx] = 0; - return; - } + break; + } + + this->_nmea[idx] = ch; + } +} - msg[idx] = ch; - } - } - } - fprintf(stderr, "\r\nGPS: Overflowed message limit\r\n"); - return; - //error("Overflowed message limit"); +char SerialGPS::read_char() +{ + char ch; + _gps_p->read(&ch, 1); + return ch; } \ No newline at end of file