Introduction

Smablo GPS Shield is based on Titan X1 module with embedded antena can perform high quality GNSS tracking with low power consumption and compact size. Thanks to it, you can easly track position of people or things which makes it perfect choice for IoT projects. Smablo GPS Shield can output GGA, GSA, GSV, RMC, VTG NMEA sentences and works with both GPS and GLONASS navigational systems.

Applications

Smablo GPS Shield can be used in variety of projects whenever you need to track position. Typical applications:

  • Car tracking
  • Animal tracking
  • Assets tracking
  • Fitness
  • Drones navigation
  • Etc.

Getting started

To get started with Smablo GPS Shield you will need:

Take Smablo Development Board from your Smablo Development Kit and place CPU and Smablo GPS Shield on the described connectors like in the pictures and video below:

{.force-inline} {.force-inline} {.force-inline}

When you’ve done connecting Shields you can connect Smablo Development board to your computer with USB cable.

Example programs

To show you how to interact with Smablo GPS Shield open Visual Studio Code and from your Smablo SDK example directory and open gps like it was shown at the video below.

gps

To compile and program the Shield press F5 button and hit the run button on the top menu of Visual Studio Code. To see the output of the gps example open RTT Viewer. Example shows decoded NMEA sentences.

Smablo GPS Shield after using it for the first time will need some time to download all off the data needed.

Minimal code

Minimal example code is the same code that you can find in the Example code chapter and will show you how to use Smablo GPS Shield , drv_gtop_gps.h and app_gps_parser.h drivers. The Smablo GPS project was split into more files to make it easier to read. The gps_demo.c and gps_demo.h are containing the main initialization and configuration functions. The gps_evt_to_string.h and gps_evt_to_string.c are containing the helper functions to convert enum into strings for further use use in gps_parser_handler() function located in gps_parser_handler.c file. Remember that you can always check the functions and types by clicking F12 button when on them.

Firstly lets have a look for the gps_demo.c file and all of the configuration functions needed for proper work of the Smablo GPS Shield

//1
#include "nrf_log.h"
#include "drv_gtop_gps.h"
#include "app_gps_parser.h"
#include "gps_demo.h"
#include "gps_parser_handlers.h"

//2
//GlobalTop I2C GPS driver instance
static gtop_gps_instance_t gps_instance=SM_GPS_INSTANCE;

//GPS parser library instance
static app_gps_parser_instance_t gps_parser_instance;

//5
//GlobalTop I2C GPS driver data ready handler
static void gtop_gps_data_handler(char* nmea_sentence, uint16_t nmea_len)
{
    //pass NMEA sentence to app_gps_parser
    app_gps_parser_parse(&gps_parser_instance, nmea_sentence);
}

//main demo entry point
void gps_demo_main(void)
{
//3
    //initialize app_gps_parser library, events will be propagated to gps_parser_handler()
    app_gps_parser_init(&gps_parser_instance, gps_parser_handler);

    //initialize GlobalTop I2C GPS driver, data will be passed to gtop_gps_data_handler()
    gtop_gps_init(&gps_instance, gtop_gps_data_handler);

//4
    //set NMEA sentence frequency
    //here you can select which NMEA statements will be emitted and how often
    //this is the default module configuration
    gtop_gps_sentence_freq_cfg_t sentence_freq_cfg=
    {

        .gll_freq=GTOP_GPS_SENTENCE_FREQ_1,                 ///< GPGLL interval - Geographic Position - Latitude longitude
        .rmc_freq=GTOP_GPS_SENTENCE_FREQ_1,                 ///< GPRMC interval - Recommended Minimum Specific GNSS Sentence
        .vtg_freq=GTOP_GPS_SENTENCE_FREQ_1,                 ///< GPVTG interval - Course over Ground and Ground Speed
        .gga_freq=GTOP_GPS_SENTENCE_FREQ_1,                 ///< GPGGA interval - GPS Fix Data
        .gsa_freq=GTOP_GPS_SENTENCE_FREQ_1,                 ///< GPGSA interval - GNSS DOPS and Active Satellites
        .gsv_freq=GTOP_GPS_SENTENCE_FREQ_5,                 ///< GPGSV interval - GNSS Satellites in View
        .zda_freq=GTOP_GPS_SENTENCE_FREQ_1,                 ///< GPZDA interval � Time & Date
        .pmtk_mchn_freq=GTOP_GPS_SENTENCE_FREQ_DISABLED     ///< PMTKCHN interval � GPS channel status

    };
    gtop_gps_set_sentence_freq(&gps_instance, &sentence_freq_cfg);

}

In point 1 we need to include all the libraries that we will need to work with.

  • #include "nrf_log.h" that help us debug the programs and let us show sentencies and data on screen with use of RTT Viewer.
  • drv_gtop_gps.h is driver that holds all of the Smablo GPS Shield initialization and configuration functions.
  • app_gps_parser.h is Smablo library that helps to parse data from NMEA sentencies.
  • gps_demo.h is header file of our GPS demo example.
  • gps_parser_handlers.h is our handler function. Parsed and decoded NMEA sentencies data are for futher action.

In point 2 we are making instances of both Smablo GPS Shield and Smablo app_gps_parser. SM_GPS_INSTANCE macro was created for gtop_gps_instance_t instance. This macro holds all of the Smablo GPS Shield default settings and values and it is recomended to use it for creatin an instance of it.

In point 3 we need to initialize Smablo GPS Shield with driver instance and the parser instance. We need to do this only once. For app_gps_parser_init(&gps_parser_instance, gps_parser_handler) as a second parameter we need to also give created ealier app_gps_parser event handler which is located in the gps_parser_handlers.c. This handler depending on which event was selected in sentence_freq_cfg structure is printing all of the events data on screen. You can always change action taken for each event by modifying gps_parser_handler function. For gtop_gps_init(&gps_instance, gtop_gps_data_handler) as a second parameter we we need to also create a handler that will run every time GPS data from the shield are ready to process in this example called gtop_gps_data_handler.

In point 4 we are configurating which of the NMEA data we want from the shield and how frequently. We can set GLL, RMC, VTG, GGA, GSA, GSV, ZDA and pmtk channel with gtop_gps_sentence_freq_t type enum


///Allowed NMEA sentence output frequencies
typedef enum
{
    GTOP_GPS_SENTENCE_FREQ_DISABLED=0,  ///< Sentence output disabled
    GTOP_GPS_SENTENCE_FREQ_1,           ///< Output sentence every update interval
    GTOP_GPS_SENTENCE_FREQ_2,           ///< Output sentence every 2 update intervals
    GTOP_GPS_SENTENCE_FREQ_3,           ///< Output sentence every 3 update intervals
    GTOP_GPS_SENTENCE_FREQ_4,           ///< Output sentence every 4 update intervals
    GTOP_GPS_SENTENCE_FREQ_5,           ///< Output sentence every 5 update intervals

} gtop_gps_sentence_freq_t;

we can disable or select all of sentences and their frequences or use GTOP_GPS_SENTENCE_FREQ_CFG_DEFAULT which sets the default values to all of the sentencies. You can find them in the drv_gtp_gps.h file by clicking F12 button on the types or functions of drv_gtp_gps.h driver. Next we need to use gtop_gps_set_sentence_freq() to send our configuration to the Smablo GPS Shield. In this example we are showing all of the NMEA sentecies.

In point 5 we have our gtop_gps_data_handler() that will be executed every time that GPS Shield will have data ready for us to process. Every time sentences that we set in sentence_freq_cfg structure are ready to process this handler will execute with NMEA sentence in nmea_sentence variable. Inside handler function we are using app_gps_parser_parse(&gps_parser_instance, nmea_sentence) function to pass the sentence to parser. After parser is done processing data it will call gps_parser_handler function located in gps_parser_handlers.c file. Parser handler function depending on the NMEA Sentence will print on the screen data of the NMEA sentence.

How do I?

In these chapter we will show you some common things you can do with the GPS Shield.

Send arbitrary PMTK commands to the GPS

This example shows how to send pmtk commands to the Smablo GPS Shield. PMTK commands are proprietary data transfer protocol for GNSS. It enables configuring the parameters of the GNSS chipset, aiding assistance position information and receive notifications from the GNSS chip.

//1
#include "nrf_log.h"
#include "drv_gtop_gps.h"
#include "gps_demo.h"

//GlobalTop I2C GPS driver instance
static gtop_gps_instance_t gps_instance=SM_GPS_INSTANCE;

//3
//GlobalTop I2C GPS driver data ready handler
static void gtop_gps_data_handler(char* nmea_sentence, uint16_t nmea_len)
{

    //log PMTK statements
    if(memcmp(nmea_sentence, "$PMTK", 5)==0)
    {
        NRF_LOG_RAW_DEBUG("%s\r\n",nrf_log_push(nmea_sentence));
    }

}

//2
//main demo entry point
void gps_demo_main(void)
{
    //initialize GlobalTop I2C GPS driver, data will be passed to gtop_gps_data_handler()
    gtop_gps_init(&gps_instance, gtop_gps_data_handler);

    //this demoes how to send arbitrary PMTK commands to the GPS

    //send request to output firmware version information into PMTK stream
    gtop_gps_send_pmtk_blocking(&gps_instance, 605, "", 0);

    //send request to output current NMEA sentence output frequencies 
    gtop_gps_send_pmtk_blocking(&gps_instance, 414, "", 0);

}

In point 1 we are including all necessary libraries and drivers. For this example we need nrf_log.h library that will let us print values and text on screen with help of NRF_LOG and RTT Viewer, drv_gtop_gps.h driver to use Smablo GPS Shield dedicated functions. Next we need to create an instance of Smablo GPS Shield just like in Minimal code chapter example.

In point 2 in main entry point function we need to initialize Smablo GPS Shield with instance we created and handler function that will be executed every time Smablo GPS Shield will have data to process. Next it is shown how to send PMTK commands to the Smablo GPS Shield. Everytime we want to change the configurations of the Smablo GPS Shield we can use PMTK commands. These commands can be found in here. To send PMTK commands Smablo developed special function gtop_gps_send_pmtk_blocking() that can be found in drv_gtop_gps.h driver after clicking F12 button in Visual Studio Code. This function takes 4 parameters:

  • p_instance to work on
  • pmtk_type type of PMTK
  • pmtk_payload PMTK data field
  • pmtk_payload_len PMTK data length

In this example we are sending request for firmware release version with gtop_gps_send_pmtk_blocking(&gps_instance, 605, "", 0); and request to output current NMEA sentences frequences gtop_gps_send_pmtk_blocking(&gps_instance, 414, "", 0);.

In point 3 handler function output our requests and the RTT Viewer window should look like this:

Those are our requests that we send to the shield:

And those are PMTK received outputs:

As you can see Smablo GPS Shield returned two sentencies, the first one is the firmware version of the device and the second one is current NMEA Sentences frequences, the data is all 0 becouse we didn't set any. At the and af both we have CRC code that helps to check if all the data was send correct.

drv_gtop_gps.h" driver reference

To use this driver you need to include it to your project with #include statement. It is also important that before using any of the driver functions create instance of the module:

//GlobalTop I2C GPS driver instance
static gtop_gps_instance_t gps_instance=SM_GPS_INSTANCE;

The example of usage if instance was showan in Minimal code snippet.

gtop_gps_init

Prototype:

void gtop_gps_init(gtop_gps_instance_t* const p_instance, gtop_gps_data_callback new_data_callback);

Function is used to initialize Smablo GPS Shiled, function set the module in the default settings which instance. Function takes 2 parameters:

  • p_instance which is pointer to instance type gtop_gps_instance_t that you need to create ealier. When creating the instance it is convienient and recommended to use SM_GPS_INSTANCE macro that holds all the defaul module values.
  • new_data_callback type gtop_gps_data_callback which is GPS handler function that will be executed every time that module will send output.

The example use of the function was shown in Minimal code snippet.

gtop_gps_reset_blocking

Prototype:

void gtop_gps_reset_blocking(gtop_gps_instance_t* const p_instance, gtop_gps_reset_t reset_type);

Function send reset command to the Smablo GPS Shield in blockin manner. Function takes 2 parameters:

  • p_instance to work on
  • reset_type which is reset type that we want to sent to the Shield. There are 4 types of reset that we can send to the shield and they are all avaiable in gtop_gps_reset_t after pressing F12 button when on type.

    ///Reset operation type
    typedef enum
    {
        GTOP_GPS_RESET_HOT,         ///< Hot Restart: Use all available data in the NV Store.
        GTOP_GPS_RESET_WARM,        ///< Warm Restart: Don't use Ephemeris at re-start
        GTOP_GPS_RESET_COLD,        ///< Cold Restart: Don't use Time, Position, Almanacs and Ephemeris data at re-start
        GTOP_GPS_RESET_FULL_COLD    ///< Full Cold Restart: It's essentially a Cold Restart, but additionally clear system/user configurations at re-start. That is, reset the receiver to the factory status.
    
    } gtop_gps_reset_t;
    • GTOP_GPS_RESET_HOT is a hot restart that will use all available data in the NV Store.
    • GTOP_GPS_RESET_WARM is a warm restart that won't use Ephemeris during the restart .
    • GTOP_GPS_RESET_COLD is a cold restart that won't use Time, Position, Almanacs and Ephemeris data at re-start.
    • GTOP_GPS_RESET_FULL_COLD is a full cold restart and will additionally clear system/user configurations at re-start. It will reset shield receiver to the factory status.
//1
#include "nrf_log.h"
#include "drv_gtop_gps.h"
#include "gps_demo.h"

//GlobalTop I2C GPS driver instance
static gtop_gps_instance_t gps_instance=SM_GPS_INSTANCE;

//3
//GlobalTop I2C GPS driver data ready handler
static void gtop_gps_data_handler(char* nmea_sentence, uint16_t nmea_len)
{

    //log PMTK statements
    if(memcmp(nmea_sentence, "$PMTK", 5)==0)
    {
        NRF_LOG_RAW_DEBUG("%s\r\n",nrf_log_push(nmea_sentence));
    }

}

//2
//main demo entry point
void gps_demo_main(void)
{
    //initialize GlobalTop I2C GPS driver, data will be passed to gtop_gps_data_handler()
    gtop_gps_init(&gps_instance, gtop_gps_data_handler);

    //enable line below to perform GPS reset to factory settings, this is not normally needed
    gtop_gps_reset_blocking(&gps_instance, GTOP_GPS_RESET_FULL_COLD);

}

In point 1 like in previous examples we are including all necessary libraries and drivers and creating instance of GPS Shield.

In point 2 we are initializating the Smablo GPS Shield and then performing full cold restart on module with gtop_gps_reset_blocking() function and GTOP_GPS_RESET_FULL_COLD parameter. After this function execute the shield will reset to the default status.

In point 3 handler function output PMTK requests in RTT Viewer.

gtop_gps_send_pmtk_blocking

Prototype:

void gtop_gps_send_pmtk_blocking(gtop_gps_instance_t* const p_instance, uint16_t pmtk_type, const char* const pmtk_payload, uint8_t pmtk_payload_len);

Function send arbitrary PMTK data to the Smablo GPS Shield in blocking manner. The example use of the function was shown in Send arbitrary PMTK commands to the GPS

gtop_gps_send_pmtk_blocking

Prototype:

void gtop_gps_set_sentence_freq(gtop_gps_instance_t* const p_instance, const gtop_gps_sentence_freq_cfg_t* const p_sentence_freq_cfg);

Function sets the NMEA sentences frequencies with use of gtop_gps_sentence_freq_cfg_t structure. Function takes 2 parameters:

  • p_instance instance to work on
  • p_sentence_freq_cfg pointer to gtop_gps_sentence_freq_cfg_t type structure

    ///NMEA sentence frequency configuration struct
    typedef struct
    {
        gtop_gps_sentence_freq_t gll_freq;          ///< GPGLL interval - Geographic Position - Latitude longitude
        gtop_gps_sentence_freq_t rmc_freq;          ///< GPRMC interval - Recommended Minimum Specific GNSS Sentence
        gtop_gps_sentence_freq_t vtg_freq;          ///< GPVTG interval - Course over Ground and Ground Speed
        gtop_gps_sentence_freq_t gga_freq;          ///< GPGGA interval - GPS Fix Data
        gtop_gps_sentence_freq_t gsa_freq;          ///< GPGSA interval - GNSS DOPS and Active Satellites
        gtop_gps_sentence_freq_t gsv_freq;          ///< GPGSV interval - GNSS Satellites in View
        gtop_gps_sentence_freq_t zda_freq;          ///< GPZDA interval - Time & Date
        gtop_gps_sentence_freq_t pmtk_mchn_freq;    ///< PMTKCHN interval - GPS channel status
    
    } gtop_gps_sentence_freq_cfg_t;

    that holds all of the NMEA sentences that we can set the frequency for. We can set the frequencies using gtop_gps_sentence_freq_t:

    ///Allowed NMEA sentence output frequencies
    typedef enum
    {
        GTOP_GPS_SENTENCE_FREQ_DISABLED=0,  ///< Sentence output disabled
        GTOP_GPS_SENTENCE_FREQ_1,           ///< Output sentence every update interval
        GTOP_GPS_SENTENCE_FREQ_2,           ///< Output sentence every 2 update intervals
        GTOP_GPS_SENTENCE_FREQ_3,           ///< Output sentence every 3 update intervals
        GTOP_GPS_SENTENCE_FREQ_4,           ///< Output sentence every 4 update intervals
        GTOP_GPS_SENTENCE_FREQ_5,           ///< Output sentence every 5 update intervals
    
    } gtop_gps_sentence_freq_t;

    To set the default frequencies you can also use GTOP_GPS_SENTENCE_FREQ_CFG_DEFAULT macro:

    ///Default NMEA sentence frequencies in GTop GPS firmware
    #define GTOP_GPS_SENTENCE_FREQ_CFG_DEFAULT { \
    .gll_freq=GTOP_GPS_SENTENCE_FREQ_1, \
    .rmc_freq=GTOP_GPS_SENTENCE_FREQ_1, \
    .vtg_freq=GTOP_GPS_SENTENCE_FREQ_1, \
    .gga_freq=GTOP_GPS_SENTENCE_FREQ_1, \
    .gsa_freq=GTOP_GPS_SENTENCE_FREQ_1, \
    .gsv_freq=GTOP_GPS_SENTENCE_FREQ_5, \
    .zda_freq=GTOP_GPS_SENTENCE_FREQ_DISABLED, \
    .pmtk_mchn_freq=GTOP_GPS_SENTENCE_FREQ_DISABLED \
    }

    Example use of this function can be found Minimal code chapter.

gtop_gps_set_powersaving_mode

Prototype:

void gtop_gps_set_powersaving_mode(gtop_gps_instance_t* const p_instance, gtop_gps_power_mode_t power_mode);

Function is used to enter power saving mode, this should be done AFTER gps gets a 3D fix. Function takes 2 parameters:

  • p_instance instance to work on
  • power_mode type gtop_gps_power_mode_t that can activate or disactivate power saving mode:
  • ///Power saving mode configuration
    typedef enum
    {
        GTOP_GPS_POWERSAVE_DISABLE=0,       ///< Disable power saving mode
        GTOP_GPS_POWERSAVE_ALWAYSLOCATE     ///< Enable AlwaysLocate(R) power saving mode
    
    } gtop_gps_power_mode_t;

    In GTOP_GPS_POWERSAVE_ALWAYSLOCATE mode Smablo GPS can adaptively adjust the on/off time to achieve balance between positioning accuracy and power consumption according to the environmental and motion conditions. Thanks to this feature the average power consumption of the shield is lower but still it can position the module. It is importatnt to use it always AFTER GPS gets a 3D fix. In GTOP_GPS_POWERSAVE_DISABLE we are disabling AlwaysLocate(R) feature and device is bact to normal consumption mode.

    The example code snippet below briefly shows how to use the function. Remember that before usage of the function GPS module should get a 3D fix so in your program you should make sure before you use this function.

    #include "nrf_log.h"
    #include "drv_gtop_gps.h"
    #include "gps_demo.h"
    
    //GlobalTop I2C GPS driver instance
    static gtop_gps_instance_t gps_instance=SM_GPS_INSTANCE;
    
    //GlobalTop I2C GPS driver data ready handler
    static void gtop_gps_data_handler(char* nmea_sentence, uint16_t nmea_len)
    {
    
        //log PMTK statements
        if(memcmp(nmea_sentence, "$PMTK", 5)==0)
        {
            NRF_LOG_RAW_DEBUG("%s\r\n",nrf_log_push(nmea_sentence));
        }
    }
    
    //main demo entry point
    void gps_demo_main(void)
    {
    
        //initialize GlobalTop I2C GPS driver, data will be passed to gtop_gps_data_handler()
        gtop_gps_init(&gps_instance, gtop_gps_data_handler);
    
        //enter power saving mode, this should be done AFTER gps gets a 3D fix so line below is for reference only
        gtop_gps_set_powersaving_mode(&gps_instance, GTOP_GPS_POWERSAVE_ALWAYSLOCATE);
    

gtop_gps_wakeup

Prototype:

void gtop_gps_wakeup(gtop_gps_instance_t* const p_instance);

Function wake GPS in semi non-blocking mode, this is required if application has GPS power management enabled and we need to send some commands to the GPS. After this call returns there's ~2 second window during which GPS will respond to commands. Temporary disabling power management is recommended if longer active period is required. Function as a parameter takes only p_instance which is pointer to the createed ealier instance.

app_gps_parser.h library reference

To use this libbrary you need to include it to your project with #include statement. It is also important that before using any of the library functions create instance of the module:

//GPS parser library instance
static app_gps_parser_instance_t gps_parser_instance;

The example of usage if instance was showan in Minimal code snippet.

app_gps_parser_init

Prototype:

void app_gps_parser_init(app_gps_parser_instance_t* const p_instance, app_gps_handler_t event_handler);
//initialize app_gps_parser library, 

Function is used for initializing app_gps_parser library and need to be used only once before using other function in code. Function takes two parameters:

  • p_instance type app_gps_parser_instance_t instance that you need create ealier.
  • event_handler type app_gps_handler_t is app_gps_parser() function event handler, decoded NMEA sentences go here encapsulated in app_gps_parser_event_t struct.

The example of usage if instance was showan in Minimal code snippet.

app_gps_parser_init

Prototype:

void app_gps_parser_parse(const app_gps_parser_instance_t* const p_instance, const char* line);

Function is used to parse NMEA sentencies sended from the shield. After parsing function calls event_handler function that was added to the app_gps_parser_init() as a secoun parameter. Function takes two parameters:

  • p_instance type app_gps_parser_instance_t instance that you need create ealier.
  • line that is a NMEA sentence that we want to parse.

The example of usage if instance was showan in Minimal code snippet.