Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MTK3339 by
Revision 1:1427f72611a4, committed 2015-07-13
- Comitter:
- den90
- Date:
- Mon Jul 13 10:03:49 2015 +0000
- Parent:
- 0:bd0fe2412980
- Commit message:
- Dennis
Changed in this revision
| MTK3339.cpp | Show annotated file Show diff for this revision Revisions of this file |
| MTK3339.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/MTK3339.cpp Thu Nov 07 11:46:53 2013 +0000
+++ b/MTK3339.cpp Mon Jul 13 10:03:49 2015 +0000
@@ -3,8 +3,9 @@
#include "MTK3339.h"
-MTK3339::MTK3339(PinName tx, PinName rx) : _serial(tx, rx) {
- _serial.baud(9600);
+MTK3339::MTK3339(PinName tx, PinName rx) : _serial(tx, rx)
+{
+ _serial.baud(9600);
_state = StateStart;
_sentenceMask = 0;
@@ -13,72 +14,78 @@
memset(&vtg, 0, sizeof(VtgType));
}
-void MTK3339::start(void (*fptr)(void), int mask) {
+void MTK3339::start(void (*fptr)(void), int mask)
+{
if (fptr && mask) {
_dataCallback.attach(fptr);
_sentenceMask = mask;
_serial.attach(this, &MTK3339::uartIrq, Serial::RxIrq);
- }
+ }
}
-void MTK3339::stop() {
+void MTK3339::stop()
+{
_dataCallback.attach(NULL);
_sentenceMask = 0;
_serial.attach(NULL);
}
-
-MTK3339::NmeaSentence MTK3339::getAvailableDataType() {
+
+MTK3339::NmeaSentence MTK3339::getAvailableDataType()
+{
return _availDataType;
}
-double MTK3339::getLatitudeAsDegrees() {
+double MTK3339::getLatitudeAsDegrees()
+{
if(gga.fix == 0 || gga.nsIndicator == 0) return 0;
-
+
double l = gga.latitude;
char ns = gga.nsIndicator;
-
+
// convert from ddmm.mmmm to degrees only
// 60 minutes is 1 degree
-
+
int deg = (int)(l / 100);
l = (l - deg*100.0) / 60.0;
l = deg + l;
if (ns == 'S') l = -l;
-
+
return l;
}
-double MTK3339::getLongitudeAsDegrees() {
+double MTK3339::getLongitudeAsDegrees()
+{
if(gga.fix == 0 || gga.ewIndicator == 0) return 0;
-
+
double l = gga.longitude;
char ew = gga.ewIndicator;
-
+
// convert from ddmm.mmmm to degrees only
// 60 minutes is 1 degree
-
+
int deg = (int)(l / 100);
l = (l - deg*100) / 60;
l = deg + l;
if (ew == 'W') l = -l;
-
+
return l;
}
-void MTK3339::parseGGA(char* data, int dataLen) {
+void MTK3339::parseGGA(char* data, int dataLen)
+{
//http://aprs.gids.nl/nmea/#gga
-
+
double tm = 0;
-
+
memset(&gga, 0, sizeof(GgaType));
-
+
char* p = data;
- int pos = 0;
-
+ int pos = 0;
+
p = strchr(p, ',');
while (p != NULL && *p != 0) {
p++;
-
+
switch(pos) {
case 0: // time: hhmmss.sss
tm = strtod(p, NULL);
@@ -97,94 +104,96 @@
break;
case 3: // longitude: dddmm.mmmm
gga.longitude = strtod(p, NULL);
- break;
+ break;
case 4: // E/W indicator (east or west)
if (*p == 'E' || *p == 'W') {
gga.ewIndicator = *p;
}
- break;
+ break;
case 5: // position indicator (1=no fix, 2=GPS fix, 3=Differential)
gga.fix = strtol(p, NULL, 10);
- break;
+ break;
case 6: // num satellites
gga.satellites = strtol(p, NULL, 10);
- break;
+ break;
case 7: // hdop
gga.hdop = strtod(p, NULL);
- break;
+ break;
case 8: // altitude
gga.altitude = strtod(p, NULL);
- break;
+ break;
case 9: // units
// ignore units
- break;
+ break;
case 10: // geoidal separation
gga.geoidal = strtod(p, NULL);
- break;
+ break;
}
pos++;
-
- p = strchr(p, ',');
+
+ p = strchr(p, ',');
}
-
+
}
-void MTK3339::parseVTG(char* data, int dataLen) {
-
-
+void MTK3339::parseVTG(char* data, int dataLen)
+{
+
+
char* p = data;
- int pos = 0;
-
+ int pos = 0;
+
memset(&vtg, 0, sizeof(VtgType));
-
+
p = strchr(p, ',');
while (p != NULL && *p != 0) {
p++;
-
+
switch(pos) {
case 0: // course in degrees
vtg.course = strtod(p, NULL);
break;
- case 1: // Reference (T)
+ case 1: // Reference (T)
break;
case 2: // course magnetic (need customization)
break;
case 3: // reference (M)
- break;
+ break;
case 4: // speed in knots
vtg.speedKnots = strtod(p, NULL);
- break;
+ break;
case 5: // units (N)
- break;
+ break;
case 6: // speed in Km/h
vtg.speedKmHour = strtod(p, NULL);
- break;
- case 7: // units (K)
- break;
+ break;
+ case 7: // units (K)
+ break;
case 8: // mode
if (*p == 'A' || *p == 'D' || *p == 'E') {
vtg.mode = *p;
}
-
- break;
-
+
+ break;
+
}
pos++;
-
- p = strchr(p, ',');
+
+ p = strchr(p, ',');
}
}
-void MTK3339::parseData(char* data, int len) {
+void MTK3339::parseData(char* data, int len)
+{
do {
-
- // verify checksum
+
+ // verify checksum
if (len < 3 || (len > 3 && data[len-3] != '*')) {
// invalid data
break;
- }
+ }
int sum = strtol(&data[len-2], NULL, 16);
for(int i = 1; i < len-3; i++) {
sum ^= data[i];
@@ -192,58 +201,56 @@
if (sum != 0) {
// invalid checksum
break;
- }
-
-
- if (strncmp("$GPGGA", data, 6) == 0 && (_sentenceMask & NmeaGga) != 0) {
+ }
+
+
+ if (strncmp("$GPGGA", data, 6) == 0 && (_sentenceMask & NmeaGga) != 0) {
parseGGA(data, len);
_availDataType = NmeaGga;
_dataCallback.call();
_availDataType = NmeaInvalid;
- }
- else if (strncmp("$GPVTG", data, 6) == 0 && (_sentenceMask & NmeaVtg) != 0) {
+ } else if (strncmp("$GPVTG", data, 6) == 0 && (_sentenceMask & NmeaVtg) != 0) {
parseVTG(data, len);
_availDataType = NmeaVtg;
_dataCallback.call();
_availDataType = NmeaInvalid;
- }
+ }
-
+
} while(0);
}
-void MTK3339::uartIrq() {
+void MTK3339::uartIrq()
+{
char d = 0;
-
+
while(_serial.readable()) {
d = _serial.getc();
-
+
switch(_state) {
- case StateStart:
- if (d == '$') {
- _buf[0] = '$';
- _bufPos = 1;
- _state = StateData;
- }
- break;
- case StateData:
- if (_bufPos >= MTK3339_BUF_SZ) {
- // error
- _state = StateStart;
- }
- else if (d == '\r') {
-
- _buf[_bufPos] = 0;
-
- parseData(_buf, _bufPos);
-
- _state = StateStart;
- }
- else {
- _buf[_bufPos++] = d;
- }
-
- break;
+ case StateStart:
+ if (d == '$') {
+ _buf[0] = '$';
+ _bufPos = 1;
+ _state = StateData;
+ }
+ break;
+ case StateData:
+ if (_bufPos >= MTK3339_BUF_SZ) {
+ // error
+ _state = StateStart;
+ } else if (d == '\r') {
+
+ _buf[_bufPos] = 0;
+
+ parseData(_buf, _bufPos);
+
+ _state = StateStart;
+ } else {
+ _buf[_bufPos++] = d;
+ }
+
+ break;
}
}
}
--- a/MTK3339.h Thu Nov 07 11:46:53 2013 +0000
+++ b/MTK3339.h Mon Jul 13 10:03:49 2015 +0000
@@ -1,10 +1,11 @@
#ifndef MTK3339_H
#define MTK3339_H
-/**
+/**
* An interface to the MTK3339 GPS module.
*/
-class MTK3339 {
+class MTK3339
+{
public:
@@ -16,7 +17,7 @@
// NmeaRmc = 0x08,
NmeaVtg = 0x10
};
-
+
struct GgaType {
/** UTC time - hours */
int hours;
@@ -26,24 +27,24 @@
int seconds;
/** UTC time - milliseconds */
int milliseconds;
-
+
/** The latitude in ddmm.mmmm format (d = degrees, m = minutes) */
- double latitude;
+ double latitude;
/** The longitude in dddmm.mmmm format */
double longitude;
/** North / South indicator */
char nsIndicator;
/** East / West indicator */
- char ewIndicator;
-
- /**
- * Position indicator:
+ char ewIndicator;
+
+ /**
+ * Position indicator:
* 0 = Fix not available
* 1 = GPS fix
* 2 = Differential GPS fix
*/
- int fix;
-
+ int fix;
+
/** Number of used satellites */
int satellites;
/** Horizontal Dilution of Precision */
@@ -51,9 +52,9 @@
/** antenna altitude above/below mean sea-level */
double altitude;
/** geoidal separation */
- double geoidal;
+ double geoidal;
};
-
+
struct VtgType {
/** heading in degrees */
double course;
@@ -61,7 +62,7 @@
double speedKnots;
/** Speed in kilometer per hour */
double speedKmHour;
- /**
+ /**
* Mode
* A = Autonomous mode
* D = Differential mode
@@ -70,69 +71,70 @@
char mode;
};
- /**
+ /**
* Create an interface to the MTK3339 GPS module
*
* @param tx UART TX line pin
* @param rx UART RX line pin
*/
MTK3339(PinName tx, PinName rx);
-
- /**
+
+ /**
* Start to read data from the GPS module.
- *
- * @param fptr A pointer to a void function that will be called when there
- * is data available.
- * @param mask specifies which sentence types (NmeaSentence) that are of
- * interest. The callback function will only be called for messages
+ *
+ * @param fptr A pointer to a void function that will be called when there
+ * is data available.
+ * @param mask specifies which sentence types (NmeaSentence) that are of
+ * interest. The callback function will only be called for messages
* specified in this mask.
- */
+ */
void start(void (*fptr)(void), int mask);
- /**
+ /**
* Start to read data from the GPS module.
- *
+ *
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
- * @param mask specifies which sentence types (NmeaSentence) that are of
- * interest. The member function will only be called for messages
+ * @param mask specifies which sentence types (NmeaSentence) that are of
+ * interest. The member function will only be called for messages
* specified in this mask.
- */
+ */
template<typename T>
void start(T* tptr, void (T::*mptr)(void), int mask) {
if((mptr != NULL) && (tptr != NULL) && mask) {
_dataCallback.attach(tptr, mptr);
_sentenceMask = mask;
- _serial.attach(this, &MTK3339::uartIrq, Serial::RxIrq);
+ _serial.attach(this, &MTK3339::uartIrq, Serial::RxIrq);
}
- }
-
- /**
+ }
+
+ /**
* Stop to read data from GPS module
*/
void stop();
-
- /**
+
+ /**
* Get the type of the data reported in available data callback.
* This method will only return a valid type when called within the
- * callback.
- */
+ * callback.
+ */
NmeaSentence getAvailableDataType();
/**
* Get latitude in degrees (decimal format)
- */
+ */
double getLatitudeAsDegrees();
+
/**
* Get longitude in degrees (decimal format)
- */
+ */
double getLongitudeAsDegrees();
/**
* Time, position and fix related data
*/
GgaType gga;
-
+
/**
* Course and speed information relative to ground
*/
@@ -144,24 +146,24 @@
enum PrivConstants {
MTK3339_BUF_SZ = 255
};
-
+
enum DataState {
StateStart = 0,
StateData
};
-
+
FunctionPointer _dataCallback;
char _buf[MTK3339_BUF_SZ];
int _bufPos;
DataState _state;
int _sentenceMask;
NmeaSentence _availDataType;
-
+
Serial _serial;
-
+
void parseGGA(char* data, int dataLen);
- void parseVTG(char* data, int dataLen);
+ void parseVTG(char* data, int dataLen);
void parseData(char* data, int len);
void uartIrq();
