Interfacing the NEO-6M GPS module to a PIC
I recently purchased a NEO-6M GPS module made by u-blox from eBay. The module is manufactured by u-blox and a datasheet is downloadable on the company website. It looks like the following, with connection header for UART output and antenna:
Since my computer does not have a dedicated serial port, I connected the module’s serial output pins to a cheap USB to TTL that uses the Prolific PL-2303HXA chipset and converted it into a USB GPS module:
NMEA output
Using Tera-Term Web 3.1 to communicate with the module at 9600bps, 8 data bit, 1 stop bit and no parity I was quickly able to see that the module is indeed returning NMEA data:
The next task is to find an NMEA viewer to make sense of the returned data. For this purpose I use the NMEA Monitor application, although Visual GPS is also a good alternative. With clear view of the sky, the GPS module is able to acquire a fix in less than a minute:
That’s it, I have made a USB GPS module for less than $10! However, to do something more useful with this, I decided to attempt to interface it to the PIC24 microcontroller. If the GPS module is mounted on an RC helicopter, for example, I can program the microcontroller to read the current GPS position and transmit it remotely via RF for other processing purposes.
Interfacing with PIC24
Within hours I was able to port the Arduino-based NMEA parser library from Adafruit to Microchip C30, ready to be tested with my PIC24. The ported library contains the following exported functions:
// internal functions
void GPS_common_init(void);
char *GPS_lastNMEA(void);
void GPS_pause(boolean b);
boolean is_GPS_paused();
boolean GPS_parse(char *);
char GPS_read(void);
boolean GPS_newNMEAreceived(void);
// get GPS information
GPS_DATE_INFO GPS_getDateInfo();
GPS_SIGNAL_INFO GPS_getSignalInfo();
GPS_LOCATION_INFO GPS_getLocationInfo();
Among these functions, of note is the GPS_read() function which updates the internal buffer whenever a byte is received from the GPS module. Once the internal buffer is updated, other GPS functions will be able to parse the NMEA data and return the associated information. To ensure timeline update of position, GPS_read() should preferably be called from a UART data receive interrupt. This is done on the PIC24 using the following code:
// set up UART 2 receive interrupt
IPC7bits.U2RXIP0 = 1;
IPC7bits.U2RXIP1 = 1;
IPC7bits.U2RXIP2 = 1;
IEC1bits.U2RXIE = 1;
IFS1bits.U2RXIF = 0;
// UART Receive Interrupt
void __attribute__((interrupt, no_auto_psv, shadow)) _U2RXInterrupt(void) {
if (U2STAbits.OERR == 1) {
U2STAbits.OERR = 0;
} else {
GPS_read();
}
IFS1bits.U2RXIF = 0;
}
GPS signal information, location and UTC time can be retrieved using the following code snippet:
if (GPS_newNMEAreceived())
{
char *nmea = GPS_lastNMEA();
boolean isOK = GPS_parse(nmea);
if (isOK)
{
GPS_SIGNAL_INFO info = GPS_getSignalInfo();
if (info.fix)
{
if (currentMode == MODE_GPS_LOCATION_INFO)
{
GPS_LOCATION_INFO loc = GPS_getLocationInfo();
GPS_DATE_INFO date = GPS_getDateInfo();
...
}
}
}
}
Since GPS only works outdoor with clear view of the sky, to test this indoor during development, I used the .NET Framework SerialPort control to write a simple program that will output a fixed set of NMEA data to a serial port on the PC connected to the micro-controller. The PIC would parse the received NMEA data as if it comes from the GPS module. The test application can be downloaded here.
Simple test board
Using a Nokia 5110 LCD module, I made a portable GPS receiver that is able to display the current GPS coordinates and UTC time:
The completed circuit, with a PIC24FJ64GA002, a Nokia 5110 LCD and the GPS module consumes 80mA-100mA during operation, with approximately 80% of the power being consumed by the GPS module. A 9V battery will therefore not last long with this circuit. To make it into a permanent and portable solution will probably require batteries with more capacity, for example, Lipo batteries used in RC helicopters.
The completed MPLAB 8 project for the GPS receiver can be found here.
Hi, Why did you choose the PIC24? Any reason a PIC16 family device couldn't be used?
Hi Paul,
I select PIC24 firstly because I had them available in my toolkit and have used them for many other projects. You may be able to use some devices from the PIC16 family to parse the NMEA messages using the same code. Just make sure that your device has enough RAM to hold the NMEA buffer. If you look at the adagps.c file in the source code, there are 2 declarations to buffer the NMEA messages received from the GPS module via UART before enough data is received and ready to be parsed: line1[MAXLINELENGTH]; and line2[MAXLINELENGTH] with MAXLINELENGTH defined as 120. This implies at least 240 bytes of RAM must be available to store the NMEA buffer. Taking into account the RAM required by other variables, I suggest using a PIC with at least 512 bytes of RAM. So if you want to use a PIC16, select a high end device with more RAM and the same code would still work.
Hi,
Actually i am testing the module while inside my room i am not getting single data on Hyper terminal or Tera term web 3.1 Do i need to be under open sky to check the communication between GPS module and my laptop using Prolific PL2303 driver. Please be advised….do i need to be under open sky to test the module with pc communication ? how to connect to PL2303 ? 3.3v or 5V ?
Thanks
Hi Patel,
Even without clear view of the sky the module should still return NMEA data and you will still be able to see the data from a terminal program.The only difference is the data that is received – without valid satellite signal the module won't be able to acquire a GPS fix and the data would contain mostly stuff like 99, 99 (first screenshot in the article). With a valid GPS fix (when you have clear view of the sky), the NMEA data would be more meaningful and identify your location.
If you aren't receiving any data at all in Hyper Terminal or Tera term – please check the connection settings. In particular the UART communication should be 9600bps, 8 data bit, 1 stop bit and no parity. Make sure that the driver for the USB to TTL chipset is correctly installed on your computer. The PL2303 should work well with both 3.3V or 5V so that shouldn't be an issue.
Do we need to set any parameter on NEO-6M GPS module ? or everything is default ? ok ? i am using USART of NEO-6m Modulee..i bought from ebay.com for around 14 USD.
Hi,
Sorry for late reply. The default UART connection settings is 9600bps 8N1 and that should be sufficient to get you going and retrieve GPS data without any need to send any commands to the module. Some advanced configurations commands are described in the datasheet (http://ec-mobile.ru/user_files/File/u-blox/NEO-6_DataSheet_(GPS.G6-HW-09005).pdf).
Let me know if you can get it working
I really like the specs of the GPS on this one,, I liked
can you tell me about code of interface GPS with PIC18F458 microcontroller using serial communication port ??
I need the full code about it