Build a GPS live tracking system

  • 0

Build a GPS live tracking system

Category : IoT

GPS tracking systems are widely utilized in a multitude of applications such as fleet management, security, personal or merchandise remote monitoring.
In this tutorial we will show how to build and program a mobile GPS Tracking device that is capable of streaming location coordinates to an IoT cloud and enable a real-time map view from any location/device with a simple web-browser.

1. Hardware components

IMG_20170711_134936090 IMG_20170707_163651165 IMG_20170707_163658928_HDR IMG_20170711_191437023
<
>

For building the prototype we choose the following off-the-shelf components:

  • Raspberry Pi or any Linux embedded device
  • GPS Module or Dongle using standard NMEA protocol
  • 3G/4G Mobile broadband modem
  • Sim Card with data plan

2. Software components

The full code and build instructions are available on github.

2.1 IoT Cloud

PubNub cloud provides a realtime messaging API for building Mobile, Web, and IoT Applications. It has SDKs supporting a large set of platforms languages and Operating Systems.

To use PubNub, you should first register for an account, create an application and add a new Key set for our GPS data streaming. For more information you can consult the Quick Start guide.

After that you will get a pair of Keys one for publishing data to a channel and other one for subscribing to it.

2.2 Embedded Software

2.2.1 Broadband connection

Follow our previous guide on how to use Ofono to enable cellular modem connection.

2.2.2 GPS interfacing

GPS modules put out typically on the serial interface a series of strings of information called the National Marine Electronics Association (NMEA) protocol.

For our use case all we need is to fetch the position, speed and time. For that parsing the $GPRMC sentences is  enough. As parsing library we use minmea, a lightweight C library:

Parsing is restricted to only RMC sentences:

minmea_sentence_id(line, false) == MINMEA_SENTENCE_RMC

If input line is not empty pack it into a rmc frame :

struct minmea_sentence_rmc frame;
if (minmea_parse_rmc(&frame, line))

Get time, speed (m/s) and coordinates (latitude, longitude) :

minmea_gettime(&ts, &frame.date, &frame.time);

/*convert speed from knot to mps*/
speed = KNT2MPS*minmea_tofloat(&frame.speed);
                    
minmea_tocoord(&frame.latitude); 
minmea_tocoord(&frame.longitude);

Those parameters are then packed into a json array :

/*format json string*/
asprintf(&gps_json_string, gps_data, 
          minmea_tocoord(&frame.latitude), 
          minmea_tocoord(&frame.longitude), 
          speed, 
          time);

gps = json_tokener_parse(gps_json_string);

Here is an output example:

[ { "latlng": [ 47.648102, 18.327868 ], "speed": 20.011890, "time": "2017-07-03 17:36:42" } ]

2.2.3 Location publishing

PubNub C-SDK is used to used to publish the data on the cloud:

The connection initialization is done using the Publish/Subscribe keys:

struct pubnub_sync *sync = pubnub_sync_init();
struct pubnub *pubnb = pubnub_init(PUBKEY, SUBKEY, 
                                   &pubnub_sync_callbacks, sync);

Publishing the json GPS data:

pubnub_publish(p,CHANNEL,data,TMOUT,NULL,NULL);

*In our code, we choose to send data only if the target is moving (speed > Threshold)

Finally verify if data was correctly sent:

if (pubnub_sync_last_result(s) != PNR_OK)
    printf("pubnub publish error!\n");

2.3 Live View Web Interface

For tracking the device and display the position in real-time on a map, we will use Mapbox and Javascript powered EON Dashboard.

The full code can be found here.

To start you will need to create a MapBox account. Once this is done, you can either create a new map design or use an existing one for example Mapbox streets.

You will also get a Mapbox authentication token to be used to connect with your account.

The Javascript code will subscribe to the PuBNub corresponding channel, fetch the position and show it on the Map in real-time.

Initialize connection to PubNub:

var pn = new PubNub({
             //replace with your own sub-key
             subscribeKey: 'sub-c-xxxxxxxx-xxxxx-xxxxx-xxxxx-xxxxxxxxxx'            
             });

Define the EON map function by providing the API access token (mbToken), map ID (mbId) and the channel used to get GPS data from:

var map = eon.map({
        pubnub: pn,
        id: 'map',
        mbId: 'mapbox.streets',
        mbToken: 'pk.eyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        channels: ['gps-location'],

Function setView is added to set the initial position from the last know value:

message: function (data) {
            map.setView(data[0].latlng);
         },

Zoom option is set a focus on the position:

options: {
    zoomAnimation: true,
    zoom:16
 },

Finally a following position marker parses the latlng coordinates and show them on the map:

marker: function (latlng) {
          return (new L.Marker(latlng));
        }
 });

Conclusion

In this tutorial we have implemented a real-time GPS tracking system using a Raspberrypi connected to the Cloud. In future articles we will show how to extend this setup using OBD2 adapter and a Bluetooth connection to stream more data from the car to the cloud.


Leave a Reply