Here is a configuration arrangement where a CP2102 USB converter is used for communication to the PC running MiniGPS, as well as a 3.3 V power supply to the GPS.
The MiniGPS software has been used to configure the $GPRMC NMEA 0183 sentence at a baud rate of 9600, with an update rate of 5 Hz, and WAAS enabled ( I am currently using an older 5 Hz LS20031 version, soon to be replaced by the 10 Hz one).
Here is the format of the output sentence:
$GPRMC,180846.600,A,4659.9999,N,07059.9999,W,6.00,45.00,050210,,,D*77
where the 6 numbers to be extracted are highlighted. The latitude and longitude are each read as 2 integer values to avoid rounding errors here, followed by the SOG and COG floating point values.
WARNING: the onboard battery will keep the configuration up to several weeks if the GPS is not powered during this time, and will then revert to the default configuration with a 57600 baud rate. After a winter season on the dry, the configuration step has to be repeated.
Once configured, here is how the GPS is interfaced to the microcontroller, using a logic level converter to step up the NMEA output from 3.3 to 5 V. This is a good illustration of the kind of punishment you deserve when you mix 3.3 V sensors with 5 V microprocessors.
Here is the part of the code used by the Olimex microprocessor to parse the NMEA data from the GPS.
unsigned static char buf0[500];
volatile unsigned char temprec0;
volatile unsigned char idx0 = 0;
volatile unsigned char temprec0;
volatile unsigned char idx0 = 0;
typedef union
{
unsigned char messageBuf[36];
struct
{
double heading; // magnetic heading from gyrocompass
double heel; // heel angle from gryrocompass
double pitch; // pitch angle from gyrocompass
double rot; // rate of turn from gyrocompass
double cog; // COG from GPS
double sog; // SOG from GPS
int long1; // longitude (1st part) from GPS
int long2; // longitude (2nd part) from GPS
int lat1; // latitude (1st part) from GPS
int lat2; // latitude (2nd part) from GPS
double speed2; // boat speed from port transducer
};
} package;
volatile package pack;{
unsigned char messageBuf[36];
struct
{
double heading; // magnetic heading from gyrocompass
double heel; // heel angle from gryrocompass
double pitch; // pitch angle from gyrocompass
double rot; // rate of turn from gyrocompass
double cog; // COG from GPS
double sog; // SOG from GPS
int long1; // longitude (1st part) from GPS
int long2; // longitude (2nd part) from GPS
int lat1; // latitude (1st part) from GPS
int lat2; // latitude (2nd part) from GPS
double speed2; // boat speed from port transducer
};
} package;
/* This interrupt routine is called each time a new character
is received from the GPS NMEA stream. When the end of
a NMEA sentence is detected (by the '\n' character), the
complete sentence accumulated in the 'buf0[]' buffer is deciphered,
the desired numbers are extracted and put in the 'pack' repository,
that is used for the I2C transfer to the main controller.
*/
ISR(USART0_RX_vect)
{
temprec0 = UDR0;
if(temprec0 != '\n')
{
buf0[idx0++] = temprec0;
}
else
{
buf0[idx0] = '\0';
idx0 = 0;
if(buf0[0] == '$')
{
// $GPRMC,180846.600,A,4659.9999,N,07059.9999,W,6.00,45.00,050210,,,D*77
sscanf(&(buf0[20]), "%d", &pack.lat1);
sscanf(&(buf0[25]), "%d", &pack.lat2);
sscanf(&(buf0[33]), "%d", &pack.long1);
sscanf(&(buf0[38]), "%d", &pack.long2);
sscanf(&(buf0[45]), "%lf,%lf", &pack.sog, &pack.cog);
}
}
}
int main(void)
{ ...
/* USART0 */
/* Set baud rate : 9600 @ 16MHz */
UBRR0L = (unsigned char)(103);
/* Enable receiver and interrupt on received characters */
UCSR0B = _BV(RXEN) | _BV(RXCIE);
idx0 = 0;
{ ...
/* USART0 */
/* Set baud rate : 9600 @ 16MHz */
UBRR0L = (unsigned char)(103);
/* Enable receiver and interrupt on received characters */
UCSR0B = _BV(RXEN) | _BV(RXCIE);
idx0 = 0;
...
}
}