GPS Module GTS-4E-60 library , (NMEA protocol) , can be easily imported into other GPS modules after a few minor changes
gts4E60.cpp@0:b876c6606429, 2015-01-03 (annotated)
- Committer:
- igbt6
- Date:
- Sat Jan 03 11:54:41 2015 +0000
- Revision:
- 0:b876c6606429
Version 0.01 of library for GPS module FIBOCOM GTS-4E-60 (NMEA protocol) released
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
igbt6 | 0:b876c6606429 | 1 | |
igbt6 | 0:b876c6606429 | 2 | #include "gts4E60.h" |
igbt6 | 0:b876c6606429 | 3 | #include <string.h> |
igbt6 | 0:b876c6606429 | 4 | |
igbt6 | 0:b876c6606429 | 5 | |
igbt6 | 0:b876c6606429 | 6 | |
igbt6 | 0:b876c6606429 | 7 | GTS4E60::GTS4E60(PinName tx, PinName rx) : mGpsSerial(tx,rx) |
igbt6 | 0:b876c6606429 | 8 | { |
igbt6 | 0:b876c6606429 | 9 | mGpsSerial.baud(GTS4E60_SERIAL_DEFAULT_BAUD ); |
igbt6 | 0:b876c6606429 | 10 | init(); |
igbt6 | 0:b876c6606429 | 11 | } |
igbt6 | 0:b876c6606429 | 12 | |
igbt6 | 0:b876c6606429 | 13 | int GTS4E60::write(const char* data) |
igbt6 | 0:b876c6606429 | 14 | { |
igbt6 | 0:b876c6606429 | 15 | return mGpsSerial.printf(data); |
igbt6 | 0:b876c6606429 | 16 | } |
igbt6 | 0:b876c6606429 | 17 | |
igbt6 | 0:b876c6606429 | 18 | //private methods |
igbt6 | 0:b876c6606429 | 19 | |
igbt6 | 0:b876c6606429 | 20 | float GTS4E60::nmeaToDecimal(float deg_coord, char nsew) |
igbt6 | 0:b876c6606429 | 21 | { |
igbt6 | 0:b876c6606429 | 22 | int degree = (int)(deg_coord/100.0f); |
igbt6 | 0:b876c6606429 | 23 | float minutes = deg_coord - degree*100; |
igbt6 | 0:b876c6606429 | 24 | float dec_deg = minutes / 60.0f; |
igbt6 | 0:b876c6606429 | 25 | float decimal = degree + dec_deg; |
igbt6 | 0:b876c6606429 | 26 | if (nsew == 'S' || nsew == 'W') { |
igbt6 | 0:b876c6606429 | 27 | decimal *= -1; // return negative value |
igbt6 | 0:b876c6606429 | 28 | } |
igbt6 | 0:b876c6606429 | 29 | return decimal; |
igbt6 | 0:b876c6606429 | 30 | |
igbt6 | 0:b876c6606429 | 31 | //using trunc |
igbt6 | 0:b876c6606429 | 32 | /* |
igbt6 | 0:b876c6606429 | 33 | if(ns =='S') { |
igbt6 | 0:b876c6606429 | 34 | latitude *= -1.0; |
igbt6 | 0:b876c6606429 | 35 | } |
igbt6 | 0:b876c6606429 | 36 | if(ew =='W') { |
igbt6 | 0:b876c6606429 | 37 | longitude *= -1.0; |
igbt6 | 0:b876c6606429 | 38 | } |
igbt6 | 0:b876c6606429 | 39 | float degrees = trunc(latitude / 100.0f); |
igbt6 | 0:b876c6606429 | 40 | float minutes = latitude - (degrees * 100.0f); |
igbt6 | 0:b876c6606429 | 41 | latitude = degrees + minutes / 60.0f; |
igbt6 | 0:b876c6606429 | 42 | degrees = trunc(longitude / 100.0f); |
igbt6 | 0:b876c6606429 | 43 | minutes = longitude - (degrees * 100.0f); |
igbt6 | 0:b876c6606429 | 44 | longitude = degrees + minutes / 60.0f; |
igbt6 | 0:b876c6606429 | 45 | */ |
igbt6 | 0:b876c6606429 | 46 | |
igbt6 | 0:b876c6606429 | 47 | } |
igbt6 | 0:b876c6606429 | 48 | |
igbt6 | 0:b876c6606429 | 49 | float GTS4E60::trunc(float v) |
igbt6 | 0:b876c6606429 | 50 | { |
igbt6 | 0:b876c6606429 | 51 | if(v < 0.0) { |
igbt6 | 0:b876c6606429 | 52 | v*= -1.0; |
igbt6 | 0:b876c6606429 | 53 | v = floor(v); |
igbt6 | 0:b876c6606429 | 54 | v*=-1.0; |
igbt6 | 0:b876c6606429 | 55 | } else { |
igbt6 | 0:b876c6606429 | 56 | v = floor(v); |
igbt6 | 0:b876c6606429 | 57 | } |
igbt6 | 0:b876c6606429 | 58 | return v; |
igbt6 | 0:b876c6606429 | 59 | } |
igbt6 | 0:b876c6606429 | 60 | |
igbt6 | 0:b876c6606429 | 61 | |
igbt6 | 0:b876c6606429 | 62 | void GTS4E60::readData() |
igbt6 | 0:b876c6606429 | 63 | { |
igbt6 | 0:b876c6606429 | 64 | while(mGpsSerial.getc() != '$'); //wait for the correct NMEA protocol message |
igbt6 | 0:b876c6606429 | 65 | for(int i=0; i<GTS4E60_NMEA_BUF_SIZE; i++) { |
igbt6 | 0:b876c6606429 | 66 | mNmeaData[i] = mGpsSerial.getc(); |
igbt6 | 0:b876c6606429 | 67 | if(mNmeaData[i] == '\r') { |
igbt6 | 0:b876c6606429 | 68 | mNmeaData[i] = 0; |
igbt6 | 0:b876c6606429 | 69 | return; |
igbt6 | 0:b876c6606429 | 70 | } |
igbt6 | 0:b876c6606429 | 71 | } |
igbt6 | 0:b876c6606429 | 72 | error("overflowed message limit"); |
igbt6 | 0:b876c6606429 | 73 | } |
igbt6 | 0:b876c6606429 | 74 | |
igbt6 | 0:b876c6606429 | 75 | void GTS4E60::readData(uint8_t nmeaSentence) |
igbt6 | 0:b876c6606429 | 76 | { |
igbt6 | 0:b876c6606429 | 77 | if(nmeaSentence>=NR_OF_SUPPORTED_NMEA_SENTENCES)return; |
igbt6 | 0:b876c6606429 | 78 | int counter =0; |
igbt6 | 0:b876c6606429 | 79 | while(counter<GTS4E60_NMEA_BUF_SIZE) { |
igbt6 | 0:b876c6606429 | 80 | while(mGpsSerial.getc() != '$'); //wait for the correct NMEA protocol message |
igbt6 | 0:b876c6606429 | 81 | counter++; |
igbt6 | 0:b876c6606429 | 82 | char buf[6]; |
igbt6 | 0:b876c6606429 | 83 | for(int i =0; i<5; i++) { |
igbt6 | 0:b876c6606429 | 84 | buf[i]=mGpsSerial.getc(); |
igbt6 | 0:b876c6606429 | 85 | } |
igbt6 | 0:b876c6606429 | 86 | buf[5]='\0'; |
igbt6 | 0:b876c6606429 | 87 | if(strcmp(buf,nmeaSentencesString[nmeaSentence])==0) { |
igbt6 | 0:b876c6606429 | 88 | strcpy(mNmeaData,buf); |
igbt6 | 0:b876c6606429 | 89 | } else continue; |
igbt6 | 0:b876c6606429 | 90 | for(int i=5; i<GTS4E60_NMEA_BUF_SIZE; i++) { |
igbt6 | 0:b876c6606429 | 91 | mNmeaData[i] = mGpsSerial.getc(); |
igbt6 | 0:b876c6606429 | 92 | if(mNmeaData[i] == '\r') { |
igbt6 | 0:b876c6606429 | 93 | mNmeaData[i] = 0; |
igbt6 | 0:b876c6606429 | 94 | return; |
igbt6 | 0:b876c6606429 | 95 | } |
igbt6 | 0:b876c6606429 | 96 | } |
igbt6 | 0:b876c6606429 | 97 | } |
igbt6 | 0:b876c6606429 | 98 | error("overflowed message limit"); |
igbt6 | 0:b876c6606429 | 99 | |
igbt6 | 0:b876c6606429 | 100 | } |
igbt6 | 0:b876c6606429 | 101 | |
igbt6 | 0:b876c6606429 | 102 | //public methods |
igbt6 | 0:b876c6606429 | 103 | |
igbt6 | 0:b876c6606429 | 104 | void GTS4E60::init() |
igbt6 | 0:b876c6606429 | 105 | { |
igbt6 | 0:b876c6606429 | 106 | memset(mNmeaData,0,GTS4E60_NMEA_BUF_SIZE); |
igbt6 | 0:b876c6606429 | 107 | //GPGAA |
igbt6 | 0:b876c6606429 | 108 | mFixType= 0; |
igbt6 | 0:b876c6606429 | 109 | mSatellites = 0; |
igbt6 | 0:b876c6606429 | 110 | mHdop= 0; |
igbt6 | 0:b876c6606429 | 111 | mAltitude= 0.0; |
igbt6 | 0:b876c6606429 | 112 | mUnits= ' '; |
igbt6 | 0:b876c6606429 | 113 | |
igbt6 | 0:b876c6606429 | 114 | // RMC |
igbt6 | 0:b876c6606429 | 115 | mLongitude= 0.0; |
igbt6 | 0:b876c6606429 | 116 | mLatitude = 0.0; |
igbt6 | 0:b876c6606429 | 117 | NS=' '; |
igbt6 | 0:b876c6606429 | 118 | EW=' '; |
igbt6 | 0:b876c6606429 | 119 | mDataStatus= 'V'; |
igbt6 | 0:b876c6606429 | 120 | |
igbt6 | 0:b876c6606429 | 121 | //GSV |
igbt6 | 0:b876c6606429 | 122 | mNumberOfMsgs=0; |
igbt6 | 0:b876c6606429 | 123 | mMsgNumber=0; |
igbt6 | 0:b876c6606429 | 124 | mSatellitesInView=0; |
igbt6 | 0:b876c6606429 | 125 | wait(1); |
igbt6 | 0:b876c6606429 | 126 | } |
igbt6 | 0:b876c6606429 | 127 | |
igbt6 | 0:b876c6606429 | 128 | |
igbt6 | 0:b876c6606429 | 129 | int GTS4E60::isDataAvailable() |
igbt6 | 0:b876c6606429 | 130 | { |
igbt6 | 0:b876c6606429 | 131 | |
igbt6 | 0:b876c6606429 | 132 | return mGpsSerial.readable(); |
igbt6 | 0:b876c6606429 | 133 | } |
igbt6 | 0:b876c6606429 | 134 | |
igbt6 | 0:b876c6606429 | 135 | uint8_t GTS4E60::parseData(uint8_t param) |
igbt6 | 0:b876c6606429 | 136 | { |
igbt6 | 0:b876c6606429 | 137 | uint8_t retVal=ERROR; |
igbt6 | 0:b876c6606429 | 138 | if(param==NULL) |
igbt6 | 0:b876c6606429 | 139 | readData(); |
igbt6 | 0:b876c6606429 | 140 | else |
igbt6 | 0:b876c6606429 | 141 | readData(param); |
igbt6 | 0:b876c6606429 | 142 | // Check if there is a GPGGA snetence |
igbt6 | 0:b876c6606429 | 143 | if(sscanf(mNmeaData, "GPGGA, %2d%2d%f, %*f, %*c, %*f, %*c, %d, %d, %*f, %f", &mUtcTime.hours, &mUtcTime.minutes, &mUtcTime.seconds, &mFixType, &mSatellites, &mAltitude) >=1) { |
igbt6 | 0:b876c6606429 | 144 | retVal = GGA; |
igbt6 | 0:b876c6606429 | 145 | if(mFixType == 0) { |
igbt6 | 0:b876c6606429 | 146 | mFix = "Invalid or not available"; |
igbt6 | 0:b876c6606429 | 147 | return NO_FIX_FOUND; |
igbt6 | 0:b876c6606429 | 148 | } |
igbt6 | 0:b876c6606429 | 149 | if(mSatellites==0) { |
igbt6 | 0:b876c6606429 | 150 | return NO_SATELLITES; |
igbt6 | 0:b876c6606429 | 151 | } |
igbt6 | 0:b876c6606429 | 152 | } |
igbt6 | 0:b876c6606429 | 153 | //if there is a GPGSA sentence - not used here :) |
igbt6 | 0:b876c6606429 | 154 | /* |
igbt6 | 0:b876c6606429 | 155 | else if(sscanf(mNmeaData, "GPGSA, %c, %c, %d ....", &mMode1, &mMode2, &mSatelitesUsed....) >=1){ |
igbt6 | 0:b876c6606429 | 156 | retVal= GSA; |
igbt6 | 0:b876c6606429 | 157 | } |
igbt6 | 0:b876c6606429 | 158 | */ |
igbt6 | 0:b876c6606429 | 159 | |
igbt6 | 0:b876c6606429 | 160 | //if there is a GPRMC sentence |
igbt6 | 0:b876c6606429 | 161 | else if(sscanf(mNmeaData, "GPRMC, %2d%2d%f, %c, %f, %c, %f, %c, %f, %f, %2d%2d%2d", &mUtcTime.hours, &mUtcTime.minutes, &mUtcTime.seconds, &mDataStatus, &mLatitude, &NS, &mLongitude, &EW, &mSpeedKn, &mHeading, &mDate.day, &mDate.month, &mDate.year) >=1) { |
igbt6 | 0:b876c6606429 | 162 | retVal = RMC; |
igbt6 | 0:b876c6606429 | 163 | if(mDataStatus=='V') |
igbt6 | 0:b876c6606429 | 164 | return INVALID_STATUS; |
igbt6 | 0:b876c6606429 | 165 | |
igbt6 | 0:b876c6606429 | 166 | mDate.year += 2000; |
igbt6 | 0:b876c6606429 | 167 | mLatitude= nmeaToDecimal(mLatitude,NS); |
igbt6 | 0:b876c6606429 | 168 | mLongitude= nmeaToDecimal(mLongitude,EW); |
igbt6 | 0:b876c6606429 | 169 | |
igbt6 | 0:b876c6606429 | 170 | if(mFixType == 1) { |
igbt6 | 0:b876c6606429 | 171 | mFix = "Positive"; |
igbt6 | 0:b876c6606429 | 172 | } |
igbt6 | 0:b876c6606429 | 173 | if(mFixType == 2) { |
igbt6 | 0:b876c6606429 | 174 | mFix = "Differential"; |
igbt6 | 0:b876c6606429 | 175 | } |
igbt6 | 0:b876c6606429 | 176 | if(mHeading > 0.00 && mHeading < 45.00) { |
igbt6 | 0:b876c6606429 | 177 | mCardinal = "NNE"; |
igbt6 | 0:b876c6606429 | 178 | } else if(mHeading == 45.00) { |
igbt6 | 0:b876c6606429 | 179 | mCardinal = "NE"; |
igbt6 | 0:b876c6606429 | 180 | } else if(mHeading > 45.00 && mHeading < 90.00) { |
igbt6 | 0:b876c6606429 | 181 | mCardinal = "ENE"; |
igbt6 | 0:b876c6606429 | 182 | } else if(mHeading == 90.00) { |
igbt6 | 0:b876c6606429 | 183 | mCardinal = "E"; |
igbt6 | 0:b876c6606429 | 184 | } else if(mHeading > 90.00 && mHeading < 135.00) { |
igbt6 | 0:b876c6606429 | 185 | mCardinal = "ESE"; |
igbt6 | 0:b876c6606429 | 186 | } else if(mHeading == 135.00) { |
igbt6 | 0:b876c6606429 | 187 | mCardinal = "SE"; |
igbt6 | 0:b876c6606429 | 188 | } else if(mHeading > 135.00 && mHeading < 180.00) { |
igbt6 | 0:b876c6606429 | 189 | mCardinal = "SSE"; |
igbt6 | 0:b876c6606429 | 190 | } else if(mHeading == 180.00) { |
igbt6 | 0:b876c6606429 | 191 | mCardinal = "S"; |
igbt6 | 0:b876c6606429 | 192 | } else if(mHeading > 180.00 && mHeading < 225.00) { |
igbt6 | 0:b876c6606429 | 193 | mCardinal = "SSW"; |
igbt6 | 0:b876c6606429 | 194 | } else if(mHeading == 225.00) { |
igbt6 | 0:b876c6606429 | 195 | mCardinal = "SW"; |
igbt6 | 0:b876c6606429 | 196 | } else if(mHeading > 225.00 && mHeading < 270.00) { |
igbt6 | 0:b876c6606429 | 197 | mCardinal = "WSW"; |
igbt6 | 0:b876c6606429 | 198 | } else if(mHeading == 270.00) { |
igbt6 | 0:b876c6606429 | 199 | mCardinal = "W"; |
igbt6 | 0:b876c6606429 | 200 | } else if(mHeading > 270.00 && mHeading < 315.00) { |
igbt6 | 0:b876c6606429 | 201 | mCardinal = "WNW"; |
igbt6 | 0:b876c6606429 | 202 | } else if(mHeading == 315.00) { |
igbt6 | 0:b876c6606429 | 203 | mCardinal = "NW"; |
igbt6 | 0:b876c6606429 | 204 | } else if(mHeading > 315.00 && mHeading < 360.00) { |
igbt6 | 0:b876c6606429 | 205 | mCardinal = "NNW"; |
igbt6 | 0:b876c6606429 | 206 | } else if(mHeading == 360.00 || mHeading == 0.00) { |
igbt6 | 0:b876c6606429 | 207 | mCardinal = "N"; |
igbt6 | 0:b876c6606429 | 208 | } |
igbt6 | 0:b876c6606429 | 209 | mSpeedKm = mSpeedKn*1.852; |
igbt6 | 0:b876c6606429 | 210 | |
igbt6 | 0:b876c6606429 | 211 | } |
igbt6 | 0:b876c6606429 | 212 | |
igbt6 | 0:b876c6606429 | 213 | //if there is a GPGSV sentence |
igbt6 | 0:b876c6606429 | 214 | else if(sscanf(mNmeaData, "GPGSV, %d, %d, %d", &mNumberOfMsgs, &mMsgNumber , &mSatellitesInView) >=1) { |
igbt6 | 0:b876c6606429 | 215 | retVal=GSV; |
igbt6 | 0:b876c6606429 | 216 | } |
igbt6 | 0:b876c6606429 | 217 | return retVal; |
igbt6 | 0:b876c6606429 | 218 | } |
igbt6 | 0:b876c6606429 | 219 | |
igbt6 | 0:b876c6606429 | 220 | |
igbt6 | 0:b876c6606429 | 221 | |
igbt6 | 0:b876c6606429 | 222 | |
igbt6 | 0:b876c6606429 | 223 | |
igbt6 | 0:b876c6606429 | 224 | //getter methods |
igbt6 | 0:b876c6606429 | 225 | UTC_Time GTS4E60:: getTime() |
igbt6 | 0:b876c6606429 | 226 | { |
igbt6 | 0:b876c6606429 | 227 | return mUtcTime; |
igbt6 | 0:b876c6606429 | 228 | } |
igbt6 | 0:b876c6606429 | 229 | |
igbt6 | 0:b876c6606429 | 230 | Date GTS4E60:: getDate() |
igbt6 | 0:b876c6606429 | 231 | { |
igbt6 | 0:b876c6606429 | 232 | return mDate; |
igbt6 | 0:b876c6606429 | 233 | } |
igbt6 | 0:b876c6606429 | 234 | |
igbt6 | 0:b876c6606429 | 235 | float GTS4E60:: getLongitude() |
igbt6 | 0:b876c6606429 | 236 | { |
igbt6 | 0:b876c6606429 | 237 | return mLongitude; |
igbt6 | 0:b876c6606429 | 238 | } |
igbt6 | 0:b876c6606429 | 239 | |
igbt6 | 0:b876c6606429 | 240 | float GTS4E60::getLatitude() |
igbt6 | 0:b876c6606429 | 241 | { |
igbt6 | 0:b876c6606429 | 242 | return mLatitude; |
igbt6 | 0:b876c6606429 | 243 | } |
igbt6 | 0:b876c6606429 | 244 | |
igbt6 | 0:b876c6606429 | 245 | float GTS4E60::getAltitude() |
igbt6 | 0:b876c6606429 | 246 | { |
igbt6 | 0:b876c6606429 | 247 | return mAltitude; |
igbt6 | 0:b876c6606429 | 248 | } |
igbt6 | 0:b876c6606429 | 249 | |
igbt6 | 0:b876c6606429 | 250 | float GTS4E60::getSpeedKn() |
igbt6 | 0:b876c6606429 | 251 | { |
igbt6 | 0:b876c6606429 | 252 | return mSpeedKn; |
igbt6 | 0:b876c6606429 | 253 | } |
igbt6 | 0:b876c6606429 | 254 | |
igbt6 | 0:b876c6606429 | 255 | float GTS4E60::getSpeedKm() |
igbt6 | 0:b876c6606429 | 256 | { |
igbt6 | 0:b876c6606429 | 257 | return mSpeedKm; |
igbt6 | 0:b876c6606429 | 258 | } |
igbt6 | 0:b876c6606429 | 259 | |
igbt6 | 0:b876c6606429 | 260 | int GTS4E60::getSatelites() |
igbt6 | 0:b876c6606429 | 261 | { |
igbt6 | 0:b876c6606429 | 262 | return mSatellites; |
igbt6 | 0:b876c6606429 | 263 | } |
igbt6 | 0:b876c6606429 | 264 | |
igbt6 | 0:b876c6606429 | 265 | //float GTS4E60::getCourseT() {} |
igbt6 | 0:b876c6606429 | 266 | //float GTS4E60::getCourseM() {} |
igbt6 | 0:b876c6606429 | 267 | |
igbt6 | 0:b876c6606429 | 268 | int GTS4E60::getFixType() |
igbt6 | 0:b876c6606429 | 269 | { |
igbt6 | 0:b876c6606429 | 270 | return mFixType; |
igbt6 | 0:b876c6606429 | 271 | } |
igbt6 | 0:b876c6606429 | 272 | |
igbt6 | 0:b876c6606429 | 273 | int GTS4E60::getSatellites() |
igbt6 | 0:b876c6606429 | 274 | { |
igbt6 | 0:b876c6606429 | 275 | return mSatellites; |
igbt6 | 0:b876c6606429 | 276 | } |
igbt6 | 0:b876c6606429 | 277 | |
igbt6 | 0:b876c6606429 | 278 | int GTS4E60:: getStatus() |
igbt6 | 0:b876c6606429 | 279 | { |
igbt6 | 0:b876c6606429 | 280 | return mDataStatus; |
igbt6 | 0:b876c6606429 | 281 | } |
igbt6 | 0:b876c6606429 | 282 | |
igbt6 | 0:b876c6606429 | 283 | char GTS4E60:: getNS() |
igbt6 | 0:b876c6606429 | 284 | { |
igbt6 | 0:b876c6606429 | 285 | return NS; |
igbt6 | 0:b876c6606429 | 286 | } |
igbt6 | 0:b876c6606429 | 287 | char GTS4E60:: getEW() |
igbt6 | 0:b876c6606429 | 288 | { |
igbt6 | 0:b876c6606429 | 289 | return EW; |
igbt6 | 0:b876c6606429 | 290 | } |
igbt6 | 0:b876c6606429 | 291 | |
igbt6 | 0:b876c6606429 | 292 | float GTS4E60:: getHeading() |
igbt6 | 0:b876c6606429 | 293 | { |
igbt6 | 0:b876c6606429 | 294 | return mHeading; |
igbt6 | 0:b876c6606429 | 295 | } |
igbt6 | 0:b876c6606429 | 296 | |
igbt6 | 0:b876c6606429 | 297 |