GPSParser.cpp

Committer:
slisgrinder
Date:
2012-03-28
Revision:
3:d01d7593384d
Parent:
2:6f49c74ab3b9

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;
}