Copyright: | Copyright 2008 Dean Hall. All rights reserved. |
---|---|
Author: | Dean Hall |
Revision: | 1 |
Date: | 2008/03/23 U |
I am using the hacked EverMore GPS module which has a SiRFstarIII chip in it. So I found information on the SiRF NMEA Command set to configure the GPS module.
Every configuration command below needs the proper checksum embedded in the configuration sentence in order for the SiRF module to accept the command. The checksum is the XOR of every character after '$' and before '*' (not including the '$' and '*' boundaries).
Here is a Python function to calculate the XOR checksum of an NMEA string:
def calc_checksum(s): index1 = s.find('$') index2 = s.rfind('*') assert index1 >= 0 and index2 >= 0 sum = 0 for c in s[index1 + 1 : index2]: sum = sum ^ ord(c) return hex(sum)
The output of this function is a string showing the hexadecimal value of the checksum. Strip off the prefix "0x" and use the remaining two characters as the checksum for the input sentence. For example, use:
>>> calc_checksum("$PSRF100,1,19200,8,1,0*") '0x38'
To complete the NMEA command sentence:
"$PSRF100,1,19200,8,1,0*38\r\n"
The first and easiest thing to do is to configure the baud rate. I only have one UART on my MMB103 board and I need to share it with the Zigbee RF module for telemetry. The UART will receive the NMEA stream from the GPS module and send the telemetry stream out through Zigbee. For best operation, I need the TX and RX to work at the same speed.
First I find which baud rates are common to both the GPS and the Zigbee modules. Then I pick the fastest baud rate that has the smallest error. For my system, this turns out to be 19200 baud.
The sentence to configure the GPS module to 19200 is easy to figure out, but then the checksum must be calculated (as seen above) in order for the SiRF module to accept the sentence. Here is the sentence I use to configure the module to 19200 baud 8-N-1:
"$PSRF100,1,19200,8,1,0*38\r\n"
The factory default of my SiRFstarIII module is to output the GPRMC, GPVTG and GPGGA sentences at 1 Hz and the GPGSA and GPGSV sentences at 0.2 Hz. Since I only parse the GPRMC and GPGGA sentences to get the data I need, all those other sentences are useless to me and only serve to create more UART interrupts than I need. In fact, I only use 31% of the default NMEA data stream, so trimming this down will reduce the CPU load on my controller.
One command serves to configure one NMEA sentence type. So I use these four commands to turn off the output rate of the four sentence types that I am not using:
"$PSRF103,1,0,0,1*25\r\n" "$PSRF103,2,0,0,1*26\r\n" "$PSRF103,3,0,0,1*27\r\n" "$PSRF103,5,0,0,1*21\r\n"
This section is very platform-specific. The GPS module is connected to my ATmega103-based MMB103 board. The module's TX pin is connected to the ATmega103's UART RX pin, but the module's RX pin is connected to an arbitrary pin so that I can connect the Zigbee radio to the UART RX pin. I use a soft-uart routine to send commands to the GPS module. I use the avr-gcc compiler and avrlibc.
The configuration commands only need to be sent during system initialization. The following code keeps the command string stored in program (Flash) memory and sends the commands out character-by-character via the soft uart:
return_t gps_init(void) { PGM_P pstr_config_P = PSTR("$PSRF100,1,19200,8,1,0*38\r\n" /** Sets baud */ "$PSRF103,1,0,0,1*25\r\n" /** Disables GPGLL */ "$PSRF103,2,0,0,1*26\r\n" /** Disables GPGSA */ "$PSRF103,3,0,0,1*27\r\n" /** Disables GPGSV */ "$PSRF103,5,0,0,1*21\r\n" /** Disables GPVTG */ ); uint8_t i; soft_uart_init(); /* Write the configuration sentences to the module */ for (i = 0; i < strlen_P(pstr_config_P); i++) { soft_uart_putchar(pgm_read_byte(pstr_config_P + i)); } return RETURN_OK; }
By issuing command sentences out a soft uart pin to the SiRFstarIII GPS module, I am able to configure the module to output only the data I want at a speed optimal to my system. This makes sure the MMB103 receives the NMEA stream quickly without overloading the UART receive interrupt.