File content as of revision 3:d01d7593384d:
#include "GPSParser.h"
GPSParser::GPSParser (PinName tx, PinName rx, int baud, int num_sentence, MODSERIAL &pc, PwmOut &indicator)
:
GLL (0),
RMC (0),
VTG (1),
GGA (1),
GSA (0),
GSV (0),
GRS (0),
GST (0),
MALM (0),
MEPH (0),
MDGP (0),
MDBG (0),
ZDA (0),
MCHN (0),
num_sentences (num_sentence),
baudrate (baud),
ctr (0),
gps (tx, rx),
pc (pc),
indicator (indicator)
{
pc.printf ("Initializing GPS...\r\n");
gps.baud (baudrate);
// BEGIN CONFIGURATION OF GPS use http://www.hhhh.org/wiml/proj/nmeaxor.html for checksum calculations...
gps.printf ("$PMTK313,1*2E\r\n"); //enable SBAS satellite searching
gps.printf ("$PMTK301,2*2E\r\n"); //set DGPS mode to WAAS
gps.printf ("$PMTK314,%d,%d,%d,%d,%d,%d,%d,%d,0,0,0,0,0,%d,%d,%d,%d,%d,%d*28\r\n", GLL, RMC, VTG, GGA, GSA, GSV, GRS, GST, MALM, MEPH, MDGP, MDBG, ZDA, MCHN); //enable NMEA output sentences and frequencies
// END CONFIGURATION OF GPS
wait (0.1);
gps.rxBufferFlush ();
gps.attach (this, &GPSParser::ready_buffer);
}
void GPSParser::process_readings ()
{
char buff [num_sentences][128];
//gps.attach (this, &GPSParserCpp::ready_buffer);
for (int i = 0; i < num_sentences; i++)
{
for (int k = 0; k < 128; k++)
{
buff [i][k] = gps.getc();
if (buff [i][k] == ',' && buff [i][k - 1] == ',') // if the current and last character read were both ',' then assign the next buff position ',' and the current buff position a '0' and increment k by one.
{
buff [i][k + 1] = buff [i][k];
buff [i][k] = '0';
k++;
}
if (buff [i][k] == '*' && buff [i][k - 1] == ',') // if the current character is '*' and last character read were both ',' then assign the next buff position '*' and the current buff position a '0' and increment k by one.
{
buff [i][k + 1] = buff [i][k];
buff [i][k] = '0';
k++;
}
//pc.putc (buff [i][k]);
if (buff [i][k] == '\n')
{
k++;
buff [i][k] = '\0';
break;
}
}
}
for (int i = 0; i < num_sentences; i++)
{
if (!sscanf (buff [i], "$GPGGA,%2d%2d%2d.%3d,%f,%c,%f,%c,%d,%d,%f,%f,M,%f,M,%f,%X*%hX\r\n", &readings.hours, &readings.minutes, &readings.seconds, &readings.m_seconds, &readings.latitude, &readings.ns, &readings.longitude, &readings.ew, &readings.fix, &readings.sats_used, &readings.HDOP, &readings.altitude, &readings.geoidal_sep, &readings.AODC, &readings.DGPS_ID, &readings.checksum_gga))
sscanf (buff [i + 1], "$GPGGA,%2d%2d%2d.%3d,%f,%c,%f,%c,%d,%d,%f,%f,M,%f,M,%f,%X*%hX\r\n", &readings.hours, &readings.minutes, &readings.seconds, &readings.m_seconds, &readings.latitude, &readings.ns, &readings.longitude, &readings.ew, &readings.fix, &readings.sats_used, &readings.HDOP, &readings.altitude, &readings.geoidal_sep, &readings.AODC, &readings.DGPS_ID, &readings.checksum_gga);
if(!sscanf (buff [i], "$GPVTG,%f,T,%f,M,%f,N,%f,K,%c*%hX\r\n", &readings.heading, &readings.mag_heading, &readings.speed_knots, &readings.speed_kph, &readings.mode, &readings.checksum_vtg))
sscanf (buff [i + 1], "$GPVTG,%f,T,%f,M,%f,N,%f,K,%c*%hX\r\n", &readings.heading, &readings.mag_heading, &readings.speed_knots, &readings.speed_kph, &readings.mode, &readings.checksum_vtg);
pc.printf ("%s", buff [i]);
}
if (readings.ns == 'S')
readings.latitude *= -1.0f;
if (readings.ew == 'W')
readings.longitude *= -1.0f;
readings.lat_deg = (int)(readings.latitude / 100);
readings.lat_min = readings.latitude - (readings.lat_deg * 100.0f);
readings.deg_latitude = readings.lat_deg + readings.lat_min / 60.0f;
readings.long_deg = (int)(readings.longitude /100);
readings.long_min = readings.longitude - (readings.long_deg * 100.0f);
readings.deg_longitude = readings.long_deg + readings.long_min / 60.0f;
gps.rxBufferFlush ();
}
void GPSParser::ready_buffer(MODSERIAL_IRQ_INFO *q)
{
indicator = 1;
MODSERIAL *serial = q->serial;
if (serial->rxGetLastChar() == '\n')
ctr++;
if (ctr == num_sentences)
{
process_readings ();
ctr = 0;
}
indicator = 0;
}