GPS Module GTS-4E-60 library , (NMEA protocol) , can be easily imported into other GPS modules after a few minor changes
Revision 0:b876c6606429, committed 2015-01-03
- Comitter:
- igbt6
- Date:
- Sat Jan 03 11:54:41 2015 +0000
- Commit message:
- Version 0.01 of library for GPS module FIBOCOM GTS-4E-60 (NMEA protocol) released
Changed in this revision
gts4E60.cpp | Show annotated file Show diff for this revision Revisions of this file |
gts4E60.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r b876c6606429 gts4E60.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gts4E60.cpp Sat Jan 03 11:54:41 2015 +0000 @@ -0,0 +1,297 @@ + +#include "gts4E60.h" +#include <string.h> + + + +GTS4E60::GTS4E60(PinName tx, PinName rx) : mGpsSerial(tx,rx) +{ + mGpsSerial.baud(GTS4E60_SERIAL_DEFAULT_BAUD ); + init(); +} + +int GTS4E60::write(const char* data) +{ + return mGpsSerial.printf(data); +} + +//private methods + +float GTS4E60::nmeaToDecimal(float deg_coord, char nsew) +{ + int degree = (int)(deg_coord/100.0f); + float minutes = deg_coord - degree*100; + float dec_deg = minutes / 60.0f; + float decimal = degree + dec_deg; + if (nsew == 'S' || nsew == 'W') { + decimal *= -1; // return negative value + } + return decimal; + + //using trunc + /* + 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); + minutes = longitude - (degrees * 100.0f); + longitude = degrees + minutes / 60.0f; + */ + +} + +float GTS4E60::trunc(float v) +{ + if(v < 0.0) { + v*= -1.0; + v = floor(v); + v*=-1.0; + } else { + v = floor(v); + } + return v; +} + + +void GTS4E60::readData() +{ + while(mGpsSerial.getc() != '$'); //wait for the correct NMEA protocol message + for(int i=0; i<GTS4E60_NMEA_BUF_SIZE; i++) { + mNmeaData[i] = mGpsSerial.getc(); + if(mNmeaData[i] == '\r') { + mNmeaData[i] = 0; + return; + } + } + error("overflowed message limit"); +} + +void GTS4E60::readData(uint8_t nmeaSentence) +{ + if(nmeaSentence>=NR_OF_SUPPORTED_NMEA_SENTENCES)return; + int counter =0; + while(counter<GTS4E60_NMEA_BUF_SIZE) { + while(mGpsSerial.getc() != '$'); //wait for the correct NMEA protocol message + counter++; + char buf[6]; + for(int i =0; i<5; i++) { + buf[i]=mGpsSerial.getc(); + } + buf[5]='\0'; + if(strcmp(buf,nmeaSentencesString[nmeaSentence])==0) { + strcpy(mNmeaData,buf); + } else continue; + for(int i=5; i<GTS4E60_NMEA_BUF_SIZE; i++) { + mNmeaData[i] = mGpsSerial.getc(); + if(mNmeaData[i] == '\r') { + mNmeaData[i] = 0; + return; + } + } + } + error("overflowed message limit"); + +} + +//public methods + +void GTS4E60::init() +{ + memset(mNmeaData,0,GTS4E60_NMEA_BUF_SIZE); + //GPGAA + mFixType= 0; + mSatellites = 0; + mHdop= 0; + mAltitude= 0.0; + mUnits= ' '; + + // RMC + mLongitude= 0.0; + mLatitude = 0.0; + NS=' '; + EW=' '; + mDataStatus= 'V'; + + //GSV + mNumberOfMsgs=0; + mMsgNumber=0; + mSatellitesInView=0; + wait(1); +} + + +int GTS4E60::isDataAvailable() +{ + + return mGpsSerial.readable(); +} + +uint8_t GTS4E60::parseData(uint8_t param) +{ + uint8_t retVal=ERROR; + if(param==NULL) + readData(); + else + readData(param); + // Check if there is a GPGGA snetence + 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) { + retVal = GGA; + if(mFixType == 0) { + mFix = "Invalid or not available"; + return NO_FIX_FOUND; + } + if(mSatellites==0) { + return NO_SATELLITES; + } + } + //if there is a GPGSA sentence - not used here :) + /* + else if(sscanf(mNmeaData, "GPGSA, %c, %c, %d ....", &mMode1, &mMode2, &mSatelitesUsed....) >=1){ + retVal= GSA; + } + */ + + //if there is a GPRMC sentence + 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) { + retVal = RMC; + if(mDataStatus=='V') + return INVALID_STATUS; + + mDate.year += 2000; + mLatitude= nmeaToDecimal(mLatitude,NS); + mLongitude= nmeaToDecimal(mLongitude,EW); + + if(mFixType == 1) { + mFix = "Positive"; + } + if(mFixType == 2) { + mFix = "Differential"; + } + if(mHeading > 0.00 && mHeading < 45.00) { + mCardinal = "NNE"; + } else if(mHeading == 45.00) { + mCardinal = "NE"; + } else if(mHeading > 45.00 && mHeading < 90.00) { + mCardinal = "ENE"; + } else if(mHeading == 90.00) { + mCardinal = "E"; + } else if(mHeading > 90.00 && mHeading < 135.00) { + mCardinal = "ESE"; + } else if(mHeading == 135.00) { + mCardinal = "SE"; + } else if(mHeading > 135.00 && mHeading < 180.00) { + mCardinal = "SSE"; + } else if(mHeading == 180.00) { + mCardinal = "S"; + } else if(mHeading > 180.00 && mHeading < 225.00) { + mCardinal = "SSW"; + } else if(mHeading == 225.00) { + mCardinal = "SW"; + } else if(mHeading > 225.00 && mHeading < 270.00) { + mCardinal = "WSW"; + } else if(mHeading == 270.00) { + mCardinal = "W"; + } else if(mHeading > 270.00 && mHeading < 315.00) { + mCardinal = "WNW"; + } else if(mHeading == 315.00) { + mCardinal = "NW"; + } else if(mHeading > 315.00 && mHeading < 360.00) { + mCardinal = "NNW"; + } else if(mHeading == 360.00 || mHeading == 0.00) { + mCardinal = "N"; + } + mSpeedKm = mSpeedKn*1.852; + + } + + //if there is a GPGSV sentence + else if(sscanf(mNmeaData, "GPGSV, %d, %d, %d", &mNumberOfMsgs, &mMsgNumber , &mSatellitesInView) >=1) { + retVal=GSV; + } + return retVal; +} + + + + + +//getter methods +UTC_Time GTS4E60:: getTime() +{ + return mUtcTime; +} + +Date GTS4E60:: getDate() +{ + return mDate; +} + +float GTS4E60:: getLongitude() +{ + return mLongitude; +} + +float GTS4E60::getLatitude() +{ + return mLatitude; +} + +float GTS4E60::getAltitude() +{ + return mAltitude; +} + +float GTS4E60::getSpeedKn() +{ + return mSpeedKn; +} + +float GTS4E60::getSpeedKm() +{ + return mSpeedKm; +} + +int GTS4E60::getSatelites() +{ + return mSatellites; +} + +//float GTS4E60::getCourseT() {} +//float GTS4E60::getCourseM() {} + +int GTS4E60::getFixType() +{ + return mFixType; +} + +int GTS4E60::getSatellites() +{ + return mSatellites; +} + +int GTS4E60:: getStatus() +{ + return mDataStatus; +} + +char GTS4E60:: getNS() +{ + return NS; +} +char GTS4E60:: getEW() +{ + return EW; +} + +float GTS4E60:: getHeading() +{ + return mHeading; +} + +
diff -r 000000000000 -r b876c6606429 gts4E60.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gts4E60.h Sat Jan 03 11:54:41 2015 +0000 @@ -0,0 +1,222 @@ +/* + @file gts4E60.h + + @brief GTS-4E-60 GPS Module (FIBOCOM) module Library + Easy to change for other module + + @Author lukasz uszko(luszko@op.pl) + + Tested on FRDM-KL46Z and FRDM-KL25Z + + Copyright (c) 2014 lukasz uszko + Released under the MIT License (see http://mbed.org/license/mit) + + Nice tutorial about degree formats and ways of computing them: + http://home.online.no/~sigurdhu/Deg_formats.htm + + NMEA protocol reference manual: + https://www.sparkfun.com/datasheets/GPS/NMEA%20Reference%20Manual1.pdf + + Documentation regarding GTS-4E-60 GPS Module might be found here: + http://www.fibocom.com/product/2-1-3-2.html +*/ + +//DEMO - HOW TO USE: +/* +---------------------------------------- DEMO: 1 version ---------------------------------------- +#include "mbed.h" +#include "gt4E60.h" +int main() +{ + GTS4E60 gps(GPS_PIN_TX,GPS_PIN_RX); + Serial debug(USBTX, USBRX); + debug.baud(115200); + while(1) { + if(gps->isDataAvailable()) { + if(gps->parseData()) { + struct UTC_Time utcTime= gps->getTime(); + struct Date date= gps->getDate(); + debug.printf("GPS_UTC_TIME: %02d:%02d:%02.3f\r\n",utcTime.hours, utcTime.minutes, utcTime.seconds); + debug.printf("GPS_DATE: %02d.%02d.%02d\r\n", date.day, date.month, date.year); + debug.printf("GPS_DATA: fixtype: %d, satelites: %d, altitude: %f, speed: %f, heading: %f\r\n",gps->getFixType(), gps->getSatellites(), gps->getAltitude(), gps->getSpeedKm(), gps->getHeading()); + debug.printf("GPS_DATA: status: %c, latitude: %f, ns :%c, longitude: %f, ew: %c\r\n",gps->getStatus(), gps->getLatitude(), gps->getNS(), gps->getLongitude(), gps->getEW()); + } else { + debug.printf("NO GPS FIX FOUND\r\n"); + } + } + } + return 0; +} + +---------------------------------------- DEMO: 2 version error handling---------------------------------------- +#include "mbed.h" +#include "gt4E60.h" +int main() +{ + GTS4E60 gps(GPS_PIN_TX,GPS_PIN_RX); + Serial debug(USBTX, USBRX); + usbDebug.baud(115200); + while(1) { + if(gps->isDataAvailable()) { + uint8_t ret= gps->parseData(); + if(ret==ERROR) { + usbDebug.printf("ERROR INCORRECT DATA\r\n"); + } else if(ret==NO_FIX_FOUND) { + usbDebug.printf("NO GPS FIX FOUND\r\n"); + } else if(ret==NO_SATELLITES) { + usbDebug.printf("NO SATELLITES FOUND\r\n"); + } else if(ret==INVALID_STATUS) { + usbDebug.printf("STATUS INVALID\r\n"); + } else { + struct UTC_Time utcTime= gps->getTime(); + struct Date date= gps->getDate(); + usbDebug.printf("GPS_UTC_TIME: %02d:%02d:%02.3f\r\n",utcTime.hours, utcTime.minutes, utcTime.seconds); + usbDebug.printf("GPS_DATE: %02d.%02d.%02d\r\n", date.day, date.month, date.year); + usbDebug.printf("GPS_DATA: fixtype: %d, satelites: %d, altitude: %f, speed: %f, heading: %f\r\n",gps->getFixType(), gps->getSatellites(), gps->getAltitude(), gps->getSpeedKm(), gps->getHeading()); + usbDebug.printf("GPS_DATA: status: %c, latitude: %f, ns :%c, longitude: %f, ew: %c\r\n",gps->getStatus(), gps->getLatitude(), gps->getNS(), gps->getLongitude(), gps->getEW()); + } + } + } + return 0; +} +*/ +#ifndef __GTS4E60_H__ +#define __GTS4E60_H__ + +#include "mbed.h" +#include "BufferedSerial.h" +#include <string> + +#define GTS4E60_SERIAL_DEFAULT_BAUD 9600 +#define GTS4E60_SERIAL_TIMEOUT 10000 +#define GTS4E60_SERIAL_EOL "\r\n" +#define GTS4E60_NMEA_BUF_SIZE 512 + + +typedef enum { + //NMEA SENTENCES handled by the module: $GPGGA, $GPGSA, $GPRMC, $GPGSV + GGA = 0, + GSA = 1, + RMC = 2, + GSV = 3, + NR_OF_SUPPORTED_NMEA_SENTENCES, + //parseData() return paramteters + ERROR =5, + NO_FIX_FOUND= 6, + NO_SATELLITES= 7, + INVALID_STATUS= 8 +} GTS4E60_Utility; +static const char* nmeaSentencesString[NR_OF_SUPPORTED_NMEA_SENTENCES]= {"GPGGA","GPGSA","GPRMC","GPGSV"}; + + +//deafault serial port on FRDM KL46Z: +// UART2: +// RX-PTE17 +// TX-PTE16 + +//useful data structs +struct UTC_Time { + UTC_Time() { + hours =0; + minutes =0; + seconds=0; + } + int hours; + int minutes; + float seconds; +}; + + +struct Date { + Date() { + day =0; + month =0; + year =0; + } + int day; + int month; + int year; +}; + + + +class GTS4E60 +{ +public: + GTS4E60 (PinName tx, PinName rx); + int write(const char* data); //? + void init(); + uint8_t parseData(uint8_t param =NULL); + int isDataAvailable(); + inline int getDataFromRx() { + return mGpsSerial.getc(); + } + +//getters + UTC_Time getTime(); + Date getDate(); + float getLongitude(); + float getLatitude(); + float getAltitude(); + float getSpeedKn(); + float getSpeedKm(); + int getSatelites(); + float getCourseT(); + float getCourseM(); + int getFixType(); + int getSatellites(); + int getStatus(); + char getNS(); + char getEW(); + float getHeading(); + +// navigational functions - maybe in future + float calcCourseTo(float, float); + double calcDistToKm(float, float); + double calcDistToM(float, float); + + +private: + + float trunc ( float v); + float nmeaToDecimal(float deg_coord, char nsew); + void readData(); + void readData(uint8_t nmeaSentence); + Serial mGpsSerial; + char mNmeaData[GTS4E60_NMEA_BUF_SIZE]; + + // GGA - Global Positioning System Fixed Data + struct UTC_Time mUtcTime; // UTC time + int mFixType; // 0 = no fix; 1 = fix; 2=differential fix + int mSatellites; // number of satellites used + float mHdop; + float mAltitude; + char mUnits; + + //GSA + //not used here + + // RMC - Recommended Minimmum Specific GNS Data + char mDataStatus;// RMC data status A = Data Valid; V = Data Not valid; + float mLatitude; + float mLongitude; + char NS, EW; + float mSpeedKn; // speed in knots/hour + float mSpeedKm; // speed in kilometres/hour + float mHeading; // heading in degrees derived from previous & current location + struct Date mDate; + + //GSV - GNSS Satellites in View + int mNumberOfMsgs; + int mMsgNumber; + int mSatellitesInView; + + //useful variables + string mFix; + string mCardinal; + +}; + + + +#endif // __GTS4E60_H__