Slightly modified version of the SerialGPS library (https://os.mbed.com/teams/components/code/SerialGPS/) to support the BufferedSerial class

Committer:
runesla
Date:
Tue Mar 02 18:27:46 2021 +0100
Revision:
3:ebd79e3acf14
Parent:
2:e7f24389167b
Child:
4:2c76f1ec13a9
simple parsing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
runesla 0:1a8299deb917 1 /* mbed GPS Module Library
runesla 0:1a8299deb917 2 * Copyright (c) 2008-2010, sford
runesla 0:1a8299deb917 3 * Copyright (c) 2013, B.Adryan
runesla 0:1a8299deb917 4 *
runesla 0:1a8299deb917 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
runesla 0:1a8299deb917 6 * of this software and associated documentation files (the "Software"), to deal
runesla 0:1a8299deb917 7 * in the Software without restriction, including without limitation the rights
runesla 0:1a8299deb917 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
runesla 0:1a8299deb917 9 * copies of the Software, and to permit persons to whom the Software is
runesla 0:1a8299deb917 10 * furnished to do so, subject to the following conditions:
runesla 0:1a8299deb917 11 *
runesla 0:1a8299deb917 12 * The above copyright notice and this permission notice shall be included in
runesla 0:1a8299deb917 13 * all copies or substantial portions of the Software.
runesla 0:1a8299deb917 14 *
runesla 0:1a8299deb917 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
runesla 0:1a8299deb917 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
runesla 0:1a8299deb917 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
runesla 0:1a8299deb917 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
runesla 0:1a8299deb917 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
runesla 0:1a8299deb917 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
runesla 0:1a8299deb917 21 * THE SOFTWARE.
runesla 0:1a8299deb917 22 */
runesla 0:1a8299deb917 23
runesla 0:1a8299deb917 24 #include "SerialGPS.h"
runesla 0:1a8299deb917 25
runesla 1:214714f54773 26 SerialGPS::SerialGPS(PinName tx, PinName rx, int baud)
runesla 1:214714f54773 27 :
runesla 2:e7f24389167b 28 _gps_p(new BufferedSerial(tx, rx, baud)),
runesla 1:214714f54773 29 _gps(*_gps_p)
runesla 1:214714f54773 30 {
runesla 3:ebd79e3acf14 31 this->_gps_p->set_baud(baud);
runesla 3:ebd79e3acf14 32 this->_UTCtime = 0.0;
runesla 3:ebd79e3acf14 33 this->_lat = 0.0;
runesla 3:ebd79e3acf14 34 this->_lon = 0.0;
runesla 3:ebd79e3acf14 35 this->_lock = 0;
runesla 3:ebd79e3acf14 36 this->_fix = false;
runesla 3:ebd79e3acf14 37 }
runesla 3:ebd79e3acf14 38
runesla 3:ebd79e3acf14 39 SerialGPS::SerialGPS(BufferedSerial* serial)
runesla 3:ebd79e3acf14 40 :
runesla 3:ebd79e3acf14 41 _gps_p(serial),
runesla 3:ebd79e3acf14 42 _gps(*_gps_p)
runesla 3:ebd79e3acf14 43 {
runesla 3:ebd79e3acf14 44 this->_UTCtime = 0.0;
runesla 3:ebd79e3acf14 45 this->_lat = 0.0;
runesla 3:ebd79e3acf14 46 this->_lon = 0.0;
runesla 3:ebd79e3acf14 47 this->_lock = 0;
runesla 3:ebd79e3acf14 48 this->_fix = false;
runesla 0:1a8299deb917 49 }
runesla 0:1a8299deb917 50
runesla 3:ebd79e3acf14 51 bool SerialGPS::fix()
runesla 3:ebd79e3acf14 52 {
runesla 3:ebd79e3acf14 53 return this->_fix;
runesla 3:ebd79e3acf14 54 }
runesla 3:ebd79e3acf14 55
runesla 3:ebd79e3acf14 56 float SerialGPS::get_lat()
runesla 1:214714f54773 57 {
runesla 3:ebd79e3acf14 58 return this->_lat;
runesla 3:ebd79e3acf14 59 }
runesla 3:ebd79e3acf14 60
runesla 3:ebd79e3acf14 61 float SerialGPS::get_lon()
runesla 3:ebd79e3acf14 62 {
runesla 3:ebd79e3acf14 63 return this->_lon;
runesla 3:ebd79e3acf14 64 }
runesla 0:1a8299deb917 65
runesla 3:ebd79e3acf14 66 void SerialGPS::send_command(const char* cmd)
runesla 3:ebd79e3acf14 67 {
runesla 3:ebd79e3acf14 68 this->_gps_p->write(cmd, sizeof(cmd));
runesla 3:ebd79e3acf14 69 }
runesla 3:ebd79e3acf14 70
runesla 3:ebd79e3acf14 71 void SerialGPS::read()
runesla 3:ebd79e3acf14 72 {
runesla 0:1a8299deb917 73 getline();
runesla 0:1a8299deb917 74
runesla 3:ebd79e3acf14 75 //printf("NMEA sentence: %s\n", this->_nmea);
runesla 3:ebd79e3acf14 76
runesla 3:ebd79e3acf14 77 // GPRMC sentence: UTC time, status, lat, N/S, lon, E/W, speed, course, date
runesla 3:ebd79e3acf14 78 if(sscanf(this->_nmea, "GPRMC,%f,%c,%f,%c,%f,%c", &this->_UTCtime, &this->_status, &this->_lat, &this->_NS, &this->_lon, &this->_EW) > 0)
runesla 3:ebd79e3acf14 79 {
runesla 3:ebd79e3acf14 80 if(this->_status != 'A')
runesla 3:ebd79e3acf14 81 {
runesla 3:ebd79e3acf14 82 this->_fix = false;
runesla 3:ebd79e3acf14 83 }
runesla 3:ebd79e3acf14 84 else
runesla 0:1a8299deb917 85 {
runesla 3:ebd79e3acf14 86 set_vals();
runesla 3:ebd79e3acf14 87 }
runesla 3:ebd79e3acf14 88 }
runesla 3:ebd79e3acf14 89 // GPGGA sentence: UTC time, lat, N/S, lon, E/W, fix indicator
runesla 3:ebd79e3acf14 90 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)
runesla 3:ebd79e3acf14 91 {
runesla 3:ebd79e3acf14 92 if(!this->_lock)
runesla 3:ebd79e3acf14 93 {
runesla 3:ebd79e3acf14 94 this->_fix = false;
runesla 3:ebd79e3acf14 95 }
runesla 0:1a8299deb917 96 else
runesla 0:1a8299deb917 97 {
runesla 3:ebd79e3acf14 98 set_vals();
runesla 0:1a8299deb917 99 }
runesla 0:1a8299deb917 100 }
runesla 3:ebd79e3acf14 101 // GPGLL sentence: lat, N/S, lo, E/W, UTC time, status
runesla 3:ebd79e3acf14 102 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)
runesla 3:ebd79e3acf14 103 {
runesla 3:ebd79e3acf14 104 if(this->_status != 'A')
runesla 3:ebd79e3acf14 105 {
runesla 3:ebd79e3acf14 106 this->_fix = false;
runesla 3:ebd79e3acf14 107 }
runesla 3:ebd79e3acf14 108 else
runesla 3:ebd79e3acf14 109 {
runesla 3:ebd79e3acf14 110 set_vals();
runesla 3:ebd79e3acf14 111 }
runesla 3:ebd79e3acf14 112 }
runesla 3:ebd79e3acf14 113 else
runesla 3:ebd79e3acf14 114 {
runesla 3:ebd79e3acf14 115 //printf("No NMEA sentence found");
runesla 3:ebd79e3acf14 116 this->_fix = false;
runesla 3:ebd79e3acf14 117 }
runesla 3:ebd79e3acf14 118
runesla 3:ebd79e3acf14 119 // Clear the NMEA buffer
runesla 3:ebd79e3acf14 120 strcpy(this->_nmea, "");
runesla 0:1a8299deb917 121 }
runesla 0:1a8299deb917 122
runesla 0:1a8299deb917 123 float SerialGPS::trunc(float v)
runesla 0:1a8299deb917 124 {
runesla 0:1a8299deb917 125 if(v < 0.0)
runesla 0:1a8299deb917 126 {
runesla 0:1a8299deb917 127 v*= -1.0;
runesla 0:1a8299deb917 128 v = floor(v);
runesla 0:1a8299deb917 129 v*=-1.0;
runesla 0:1a8299deb917 130 }
runesla 0:1a8299deb917 131 else
runesla 0:1a8299deb917 132 {
runesla 0:1a8299deb917 133 v = floor(v);
runesla 0:1a8299deb917 134 }
runesla 0:1a8299deb917 135 return v;
runesla 0:1a8299deb917 136 }
runesla 0:1a8299deb917 137
runesla 3:ebd79e3acf14 138 void SerialGPS::set_vals()
runesla 3:ebd79e3acf14 139 {
runesla 3:ebd79e3acf14 140 if(this->_NS == 'S') { this->_lat *= -1.0; }
runesla 3:ebd79e3acf14 141 if(this->_EW == 'W') { this->_lon *= -1.0; }
runesla 3:ebd79e3acf14 142
runesla 3:ebd79e3acf14 143 float degrees = trunc(_lat / 100.0f);
runesla 3:ebd79e3acf14 144 float minutes = this->_lat *= -1.0;
runesla 3:ebd79e3acf14 145
runesla 3:ebd79e3acf14 146 this->_lat = degrees + minutes / 60.0f;
runesla 3:ebd79e3acf14 147 degrees = trunc(this->_lon / 100.0f * 0.01f);
runesla 3:ebd79e3acf14 148 minutes = this->_lon - (degrees * 100.0f);
runesla 3:ebd79e3acf14 149 this->_lon = degrees + minutes / 60.0f;
runesla 3:ebd79e3acf14 150 this->_fix = true;
runesla 3:ebd79e3acf14 151 }
runesla 3:ebd79e3acf14 152
runesla 0:1a8299deb917 153 void SerialGPS::getline()
runesla 0:1a8299deb917 154 {
runesla 1:214714f54773 155 char ch;
runesla 3:ebd79e3acf14 156 int idx = -1;
runesla 3:ebd79e3acf14 157
runesla 3:ebd79e3acf14 158 if(!this->_gps_p->readable())
runesla 3:ebd79e3acf14 159 {
runesla 3:ebd79e3acf14 160 return;
runesla 3:ebd79e3acf14 161 }
runesla 0:1a8299deb917 162
runesla 3:ebd79e3acf14 163 // Wait for start of sentence
runesla 3:ebd79e3acf14 164 while(read_char() != '$');
runesla 3:ebd79e3acf14 165
runesla 3:ebd79e3acf14 166 // Read from serial one char at a time until max length or read terminal
runesla 3:ebd79e3acf14 167 while(idx++ <= MAX_LINELENGTH)
runesla 0:1a8299deb917 168 {
runesla 3:ebd79e3acf14 169 ch = read_char();
runesla 3:ebd79e3acf14 170
runesla 3:ebd79e3acf14 171 if(ch == '\r')
runesla 0:1a8299deb917 172 {
runesla 3:ebd79e3acf14 173 break;
runesla 3:ebd79e3acf14 174 }
runesla 3:ebd79e3acf14 175
runesla 3:ebd79e3acf14 176 this->_nmea[idx] = ch;
runesla 3:ebd79e3acf14 177 }
runesla 3:ebd79e3acf14 178 }
runesla 2:e7f24389167b 179
runesla 3:ebd79e3acf14 180 char SerialGPS::read_char()
runesla 3:ebd79e3acf14 181 {
runesla 3:ebd79e3acf14 182 char ch;
runesla 3:ebd79e3acf14 183 _gps_p->read(&ch, 1);
runesla 3:ebd79e3acf14 184 return ch;
runesla 0:1a8299deb917 185 }