Got lost this morning due to my bus driver getting himself lost. He dropped me off in an unfamiliar part of town and there I was, lost. Fortunately for me I had my handy dandy GPS and within a couple of minutes my fear was turn to joy. Yes, I wasn't going to be late to work today and no I wasn't going to have to beg for directions. GPS modules are great. They have revolutionized mapping and directional questions. What becomes unclear is how they differentiate from one another. Here at MikroElektronika we produce several units and although they look similar, their internal makeup is varied wildly. Let's dive into the models and dissect the internals to determine what purpose one would be more fitting for.
How Does GPS Work
Easiest explanation of how the technology works is by the way of the word triangulation. 24 satellites orbit the earth at a mild 7000mi ( 11265km ) per hour. These satellites are transmitters and broadcast a weak 50 watt signal. Now that may sound like alot, but when you consider it is transmitting from 12,000 mi ( 19312 km ) away and over a broad area, the signal is spread very thin. Each transmission contains information about the ID of the satellite, status information, date, time, and position data relating to where the satellite should be at that time. If you have multiple satellites reporting to you, with some simple math you can calculate their paths relative to your receiver. Therefore position. Change in position can give you speed. Although I'd love to bore you to tears with ephemeris data and such, I'll let you find that information for yourself. Suffice to say, it works and it's awesome.
Incoming Data
Data transmitted comes in the form of encoded messages. The format of this data is primarily made up from the NMEA definitions. Each complete line of transmission is called a sentence and multiple sentence come across a transmit. Some of the sentences are:
- AAM - Waypoint Arrival Alarm
- ALM - Almanac data
- APA - Auto Pilot A sentence
- APB - Auto Pilot B sentence
- BOD - Bearing Origin to Destination
- BWC - Bearing using Great Circle route
- DTM - Datum being used.
- GGA - Fix information
- GLL - Lat/Lon data
- GRS - GPS Range Residuals
- GSA - Overall Satellite data
- GST - GPS Pseudorange Noise Statistics
- GSV - Detailed Satellite data
- MSK - send control for a beacon receiver
- MSS - Beacon receiver status information.
- RMA - recommended Loran data
- RMB - recommended navigation data for gps
- RMC - recommended minimum data for gps
- RTE - route message
- TRF - Transit Fix Data
- STN - Multiple Data ID
- VBW - dual Ground / Water Spped
- VTG - Vector track an Speed over the Ground
- WCV - Waypoint closure velocity (Velocity Made Good)
- WPL - Waypoint Location information
- XTC - cross track error
- XTE - measured cross track error
- ZTG - Zulu (UTC) time and time to go (to destination)
- ZDA - Date and Time
- HCHDG - Compass output
- PSLIB - Remote Control for a DGPS receiver
Each one of these sentences have specific information and are related to a unique form of location information. What this means is that you could pick a GPS that has support for several sentences that are related to marine navigation but your application will never see water. It could be the opposite as well. You chose the least expensive GPS module you could find for your marine application but unfortunately, that GPS may not support marine specifics.
Here is some good news. Most of your GPS modules today support the majority of these standards. In fact, if they claim a NMEA 2.0 compatibility then you will have a broad selection of the most common sentences.
MikroE. GPS Modules
With such a selection, how to choose? This is where your application will answer this. For those that need compact with integrated antennas, your choices are GPS 3, GNSS, and Nano. If space isn't the issue then you have some additional choices. Other variables that come into question is sentence support, sensitivity, and power efficiency.
Sentence Support
GPS Model | AAM | ALM | APA | APB | BOD | BWC | DTM | GGA | GLL | GRS | GSA | GST | GSV | MSK | MSS | RMA | RMB | RMC | RTE | TRF | STN | VBW | VTG | WCV | WPL | XTC | XTE | ZTG | ZDA |
GPS | X | X | X | X | X | X | X | X | X | ||||||||||||||||||||
GPS L10 | X | X | X | X | X | X | X | ||||||||||||||||||||||
GPS 2 | X | X | X | X | X | X | X | ||||||||||||||||||||||
GPS 3 | X | X | X | X | X | X | |||||||||||||||||||||||
GNSS | X | X | X | X | X | X | |||||||||||||||||||||||
Nano | X | X | X | X | X | X | X |
Sensitivity
This measurement will determine if your GPS will work when partially covered, in remote areas, or even indoors. The lower the number the lower the signal can go in strength before it is received. Low sensitivity numbers mean a lower requirements for reception.
Model | Tracking | Reacquisition | Cold Start |
GPS | -162 dBm | -160 dBm | -148 dBm |
GPS L10 | -162 dBm | -160 dBm | -145 dBm |
GPS 2 | -163 dBm | -160 dBm | -148 dBm |
GPS 3 | -165 dBm | -160 dBm | -148 dBm |
GNSS | -165 dBm | -160 dBm | -148 dBm |
Nano | -163 dBm | -162 dBm | -148 dBm |
Acquisition Time
Not only does your application depend on how, but when will the GPS receive it's first location fix. The lower the time the faster it will start to report accurate location. However, sometimes this comes at a cost of power. Choosing a low fix time means your receiver will be on for less time which turns into quicker results.
Model | Cold Start | Warm Start | Hot Start |
GPS | <26s | <26s | <1s |
GPS L10 | <35s | <35s | <1s |
GPS 2 | <35s | <35s | <1s |
GPS 3 | <15s | <5s | <1s |
GNSS | <15s | <5s | <1s |
Nano | <35s | <32s | <1s |
Power
When building a portable application or potentially on off-grid project, power becomes a concern. Each model has both a Acquisition power requirement, and active tracking requirement but can also include several power saving modes. Units that have an adaptive mode will use an internal algorithm to switch the power on and off at regular intervals in order to save power. Others have a standby mode that allows for quick wake-up and a warm acquisition of position.
Model | Acquisition | Tracking | Standby | Adaptive |
GPS | 47mA | 41mA | 12mA | |
GPS L10 | 52mA | 38mA | 2mA | |
GPS 2 | 40mA | 36mA | 17uA | 10mA |
GPS 3 | 25mA | 20mA | 1mA | 3mA |
GNSS | 25mA | 22mA | 1mA | 3mA |
Nano | 43mA | 40mA | 90uA | 6mA |
Great, I have a GPS, but how to I get anything useful out of it?
You might be happy to learn that all the parsing of the complex sentences has already been done for you. All you need to do is get the data from the GPS to our GPS Parser library and it will do the rest. You can download already packed version of parser from Libstock.
https://github.com/MikroElektronika/GPS_Parser
Here's how it works. As characters are coming from the GPS, put them in the parser. The parser will detect when a complete sentence has been provided and parse it into it's respective elements.
It is preferable to have this happen within an interrupt to insure no characters are dropped during transmission.
void UART3_RX_ISR() iv IVT_INT_USART3 ics ICS_AUTO { if( RXNE_USART3_SR_bit ) { char tmp = USART3_DR; gps_put( tmp ); } }
gps_put( char ) is the function called in the ISR that places the character in the parser buffer. It would be inefficient to do the parsing in the ISR. That and it is poor coding to have too much code happening in the ISR itself. To do the processing of the strings, a worker function is needed.
void main() { system_init(); while( 1 ) { gps_parse(); } }
gps_parse() is the working engine that will, when a sentence is received, will parse the sentence into respective parts.
What kind of information can you extract from the parser depends on what the module supports. The good news is that almost all GPS GNSS modules on the market support the basic sentences which are GGA, RMC, GSA, GSV, GLL, VTG. These are the universal structures will give an application most if not all the information needed for location, speed, direction, time, and navigation.
location_t* gps_current_lon( void );
location_t* gps_current_lat( void );
TimeStruct*gps_current_time( void );
Want to know when the last time the GPS was given its last fix?
utc_time_t* gps_current_fix( void );
Need to know how good quality of the last fix was?
fix_t gps_gga_fix_quality( void );
What about satellite count? That one is found in the GGA sentence.
uint8_t gps_gga_satcount( void );
Need some more complex. How about the dilution of precision in the horizontal component? That's found in the GSA sentence.
float gps_gsa_horizontal_dilution( void );
The point is that inside the parser there are MANY types of information you can gain from the parser. The next question is efficiency. How big is this code if you are parsing everything? Maybe I don't need everything. Ok, solution is found in the gps_config.h file.
#ifndef _GPS_CONFIG_H #define _GPS_CONFIG_H #define UBLOX_6 //#define QUECTEL_L10 //#define QUECTEL_L30 //#define QUECTEL_L80 //#define HORNET_NANO /* Universal sentences automatically supported GGA,RMC,GSA,GSV,GLL,VTG */ #if defined( UBLOX_6 ) #define DTM #define GBS #define GPQ #define GRS #define GST #define THS #define TXT #endif #if defined( QUECTEL_L10 ) #define ZDA #define TXT #endif #if defined( QUECTEL_L30 ) #define ZDA #endif #if defined( QUECTEL_L80 ) #define TXT #endif #if defined( HORNET_NANO ) #define MSS #endif #endif
You can comment out the models you are not using or even leave all of them uncommitted to just provide the basics. Re-compile and now your code is smaller in size.
How about a full example:
Example
#include "scheduler.h" #include "gps_parser.h" #define MSG( TXT ) UART1_Write_Text( TXT ) sbit STATUS_LED at GPIOB_ODR.B0; sbit RX_LED at GPIOB_ODR.B1; sbit POWER at GPIOA_ODR.B0; sbit RESET at GPIOC_ODR.B2; sbit WAKEUP at GPIOA_ODR.B4; static void check_gps() { char text[80]; location_t *me; me = gps_current_lat(); sprintf( text, "LatituderntDegrees: %drntMinutes: %4frntDirection %drn", me->degrees, me->minutes, me->azmuth ); MSG( text ); me = gps_current_lon(); sprintf( text, "LongituderntDegrees: %drntMinutes: %4frntDirection %drn", me->degrees, me->minutes, me->azmuth ); MSG( text ); sprintf( text, "Speed:rnt%frn", gps_rmc_speed() ); MSG( text ); sprintf( text, "Num of sats in view:rnt%drn", gps_gga_satcount() ); MSG( text ); sprintf( text, "Magnetic var:rnt%frn", gps_vtg_mag() ); MSG( text ); sprintf( text, "Tracking:rnt%frn", gps_rmc_track() ); MSG( text ); sprintf( text, "Altitude:rnt%frn", gps_gga_altitude() ); MSG( text ); } //Timer2 Prescaler :575; Preload = 62499; Actual Interrupt Time = 500 ms void init_timer2() { RCC_APB1ENR.TIM2EN = 1; TIM2_CR1.CEN = 0; TIM2_PSC = 575; TIM2_ARR = 62499; TIM2_DIER.UIE = 1; TIM2_CR1.CEN = 1; } void gps_initialize() { RESET = 1; Delay_ms( 300 ); RESET = 0; POWER = 0; Delay_ms( 100 ); POWER = 1; Delay_ms( 2000 ); POWER = 0; Delay_ms( 100 ); } void system_init() { GPIO_Digital_Output( &GPIOA_BASE, _GPIO_PINMASK_0 ); GPIO_Digital_Output( &GPIOB_BASE, _GPIO_PINMASK_0 | _GPIO_PINMASK_1 ); GPIO_Digital_Output( &GPIOC_BASE, _GPIO_PINMASK_2 ); GPIO_Digital_Input( &GPIOA_BASE, _GPIO_PINMASK_4 ); UART1_Init_Advanced( 115200, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART1_PA9_10 ); Delay_ms( 100 ); RXNEIE_USART1_CR1_bit = 1; UART2_Init_Advanced( 9600, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART2_PD56 ); Delay_ms( 100 ); RXNEIE_USART2_CR1_bit = 1; UART3_Init_Advanced( 9600, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART3_PD89 ); Delay_ms( 100 ); init_timer2(); task_scheduler_init( 500 ); gps_initialize(); NVIC_IntEnable( IVT_INT_USART1 ); NVIC_IntEnable( IVT_INT_USART2 ); NVIC_IntEnable(IVT_INT_TIM2); EnableInterrupts(); } void main() { system_init(); task_add( check_gps, SCH_SECONDS_5 ); task_add( heartbeat, SCH_SECONDS_1 ); task_scheduler_start(); while( 1 ) { gps_parse(); task_dispatch(); } } void UART2_RX_ISR() iv IVT_INT_USART2 ics ICS_AUTO { if( RXNE_USART2_SR_bit ) { char tmp = USART2_DR; gps_put( tmp ); } } void Timer2_interrupt() iv IVT_INT_TIM2 { TIM2_SR.UIF = 0; task_scheduler_clock(); }
Note
The GPS parser does require the Time library in the MikroC. IDE / Compiler. It is installed by default in all new installations, but you will have to select Time in the Library Manager.
Summary
Getting information from the GPS is a matter of slicing and dicing the sentences into parts. The parser does a good job of this and is a valuable tool for those of you wondering out into application land and need some "guidance". Some units have custom or unique sentences supported by their brand or model. These sentences would have to be added to the parser, but since the code is open source, have at it. Just make sure you do a pull request so others can benefit from your great work.
References
GPS Information - http://gpsinformation.net 2016
Garmin / How GPS Works - http://www.garmin.com 2016