Introduction
With today’s mobile and IoT applications, users have come to expect realtime location tracking, the ability to watch the location of a vehicle or person on a live-updating map, with smooth, up-to-the-millisecond accuracy.
It’s a defining feature driving the rise of ride share apps like Uber and Lyft, and the functionality has found its way into manufacturing, delivery and freight, and consumer connected car. It’s safe to say that location tracking is becoming more accessible, and more powerful.
Tutorial Overview
Bicycle tracker utilizes the LinkIt ONE development board's GNSS features to acquire the position of a bike in real time. The data is then uploaded to the EON real-time dashboard over a GPRS connection using the PubNub LinkIt ONE library support. The EON real-time dashboard provides a visualization of the data on a map.
By the end of this tutorial you'll have a fully functioning IoT prototype, which gathers GPS data, then transmits the data through a GPRS connection to enable control and visualization using cloud services on a PC.
This tutorial guides you through:
- Building the prototype, with details of the hardware requirements and how to put them together to create the Bike Tracker.
- Creating the software to provide the interfaces with the GNSS receiver on the LinkIt ONE development board to collect the data and implement data communications to send that data to the EON dashboard.
- Creating publish and subscribe channels using the PubNub API and PubNub LinkIt ONE library to communicate the data with the PubNub Data Stream Network, using the GPRS features of the LinkIt ONE development board.
- Sending your Bike Tracker location data to the EON real-time dashboard for real-time visualization.
At the end of the tutorial there are details on where to go for additional information on the LinkIt ONE development board and how to create software for it.
Before You Start
If you haven't built a LinkIt ONE project before, this section describes the steps you need to follow before commencing this project.
The project requires user accounts for PubNub and Mapbox.
Install the development software
Full details on downloading and installing the Arduino IDE and LinkIt ONE SDK then configuring the IDE and upgrading the board firmware are provided in the LinkIt ONE quick start guide. Complete this before you continue if you haven't already set up your development environment.
Building the Bike Tracker hardware
This section describes the hardware and electronics needed to build Bike Tracker and provides details on how to put them together.
What you need
To build the Bike Tracker hardware, in addition to a LinkIt ONE development board, you need the following components:
Putting the components together
This section provides step-by-step instructions on putting the Bike Tracker hardware together.
Step 1 – Antennas
Attach the GPS+GLONASS and GSM antennas to their corresponding pins on the LinkIt ONE development board as follows:
Step 2 – SIM card
Insert the SIM card supporting GSM/GPRS communication with a network provider operating in the 850/900/1800/1900 MHz frequency range and classified as Class 12, as shown below.
Step 3 – Power source
The power source in this tutorial is a polymer lithium-ion battery, one is included in the LinkIt ONE development board kit. Attach the battery source to the Li-Battery (3.7~4.2V) socket, as shown in the figure below.
Create your Bike Tracker's Software
Your Bike Tracker needs an Arduino Sketch to share data from an onboard GNSS receiver. This section describes the software required as follows:
- Overview of the Arduino sketch.
- Creating a new PubNub app.
- Configuring your device and its GPRS settings.
- Styling your own map on Mapbox.
- Overview of the JavaScript code to output data on Mapbox maps using the EON real-time dashboard and PubNub library support.
PubNub LinkIt ONE Development Cycle
To create PubNub apps for data streaming, you should first register for a PubNub account. The Bike Tracker tutorial follows the general steps for application development with PubNub, which you can follow in the PubNub Quick Start Guide.
Create a new PubNub App for the Bike Tracker
A PubNub app serves as an interface between your device and the network. Once you've registered your PubNub account a default project is created, as shown below.
The Publish Key and Subscribe Key define the app and will be used in your Arduino sketch to communicate the data from the board to the PubNub Data Stream Network.
Overview of the Arduino Sketch
To create the device that will track your bike and pass the data to PubNub, an Arduino sketch is implemented, verified and uploaded to the LinkIt ONE development board. The source code is provided in a GitHub repository.
The content of a sketch is as follows:
- Definitions of header files.
- Definitions of variables.
- A
setup()
function that initializes resources, such as the GPRS module. - A
loop()
function that continuously listens to and processes events from hardware and software modules such as those for GPS and GPRS. Theloop()
function runs forever — until the device is shutdown.
Start your Arduino project
Before you can write the code for your sketch you need to create it, which is achieved as follows:
1) Open Arduino IDE and by default a new sketch is created and displayed.
2) Create a folder named BikeTracker
in your documents folder and on the File menu click Save As navigate to the selected folder, name the sketch BikeTracker.ino
and save it.
Add the header files for the supporting libraries
The first part of you code adds the libraries required to the BikeTracker.ino
Arduino sketch.
GNSS and GPRS features libraries
The libraries that provide GNSS and GPRS support are part of LinkIt ONE API and are added as follows:
//import all the necessary files for GPRS connectivity
#include "LGPRS\LGPRS.h"
#include "LGPRS\LGPRSClient.h"
#include <LGPS\LGPS.h>
More details about these libraries can be found in the LinkIt ONE API guide.
Serial Peripheral Interface (SPI) communication
The SPI communication header file, from the Arduino SPI library.
#include <SPI.h>
PubNub LinkIt ONE library
The real-time streaming of GPS data is implemented with PubNub LinkIt ONE library support using GPRS connectivity. The library, along with a GPRS connectivity and data transfer example, is provided in the PubNub LinkIt ONE library GitHub repository. In this project the library is used to transfer the parsed location data to PubNub.
From the PubNub LinkIt ONE library, add the PubNub.h
and PubNub.cpp
files to the same directory as your BikeTracker.ino
project. And modify the content of the PubNub.h
header file so it includes the LGPRS library support for GPRS communication, as shown below.
#define PubNub_GPRS
#elif defined(PubNub_GPRS)
#include "LGPRSClient.h"
#define PubNub_BASE_CLIENT LGPRSClient
#else
#error PubNub_BASE_CLIENT set to an invalid value!
#endif
Then include the library header in your project.
Custom libraries
Next you add two custom libraries that offer features to parse the GPS latitude and longitude data to an appropriate String
format to pass the PubNub. These are the GPSWaypoint
and GPSFunctions
classes originally developed for, and are described in detail in the Car Tracker Tutorial.
#include "GPSWaypoint.h"
#include "GPS_functions.h"
Define the variables
Next the static variables used in the sketch are defined.
1) ledPin
to match the GPIO pin 13 to alert the user, by blinking the on board LED, whenever there is a publish
or subscribe
event triggered.
2) PubNub publish and subscribe keys. These keys are associated with your PubNub app created earlier, see Create a new PubNub App for the Bike Tracker.
char pubkey[] = "demo"; // provide the pubkey associated with your PubNub account.
char subkey[] = "demo";// provide the subkey associated with your PubNub account.
char channel[] = "bike-map";
Initiate the setup() function
Now the setup()
function can be defined, to start the various services that will be used by the sketch.
1) Initiate Serial communication with a baud rate of 9600 and print a message "Serial setup"
to the serial output.
void setup()
{
Serial.begin(9600);
Serial.println("Serial setup");
2) Establish communication over GPRS in a while
loop, by calling the attachGPRS
method of the LGPRS class. Replace the three parameters of the attachGPRS
method with your network provider's information for the access point name, username and password. Allow one second of waiting time before reconnecting to GPRS in the while loop by calling the delay(1000)
function. Once it's connected, send the "LGPRS setup"
message to the serial output.
//Connect to the GRPS network in order to send/receive PubNub messages
Serial.println("Attach to GPRS network with correct APN settings from your mobile network provider");
//attachGPRS(const char *apn, const char *username, const char *password);
while (!LGPRS.attachGPRS("everywhere", "eesecure", "secure"))
{
Serial.println(" . ");
delay(1000);
}
Serial.println("LGPRS setup");
3) Begin communication with PubNub using the publish (pubkey)
and subscribe (subkey)
keys defined earlier.
PubNub.begin(pubkey, subkey);
Serial.println("PubNub setup");
}
4) Start GPS signal reception by calling the powerOn()
method of the LGPS class.
Add the loop function
The loop()
function is executed continuously providing formatted GPS coordinates such as latitude and longitude and communication with PubNub. The function call hierarchy is provided in the figure below:
1) Acquire GPS data.
The GPS data is acquired and formatted using the custom build functions described in the Car Tracker Tutorial.
Serial.println("Getting GPS Data");
//Aquire GPS position
char GPS_formatted[] = "GPS fixed";
gpsPosition = new GPSWaypoint();
gpsSentenceInfoStruct gpsDataStruct;
getGPSData(gpsDataStruct, GPS_formatted, gpsPosition);
Serial.println(" GPS Data aquired");
2) Create a data string upload_GPS
as a combination of latitude and longitude to upload the location information to PubNub.
char* buffer_latitude = new char[30];
sprintf(buffer_latitude, "%2.6f", gpsPosition->latitude);
char* buffer_longitude = new char[30];
sprintf(buffer_longitude, "%2.6f", gpsPosition->longitude);
String upload_GPS = "[{\"latlng\":[" + String(buffer_latitude) + "," + String(buffer_longitude)+ "], \"data\":\"hello1\"}]";
const char* upload_char = upload_GPS.c_str();
3) Provide continuous communication to PubNub by:
a) Publishing a message over the GPRS connection.
Define a client object of LGPRSClient class and printout a message "publishing a message"
to the serial output. The client object is then assigned to the PubNub published message.
LGPRSClient *client;
Serial.println("publishing a message");
client = PubNub.publish(channel, upload_char, 60);
If the GPRS client is not available printout the "publishing error"
message to the serial output, then wait for a second (1000 ms) by calling the delay(1000)
function before trying to connect again.
if (!client) {
Serial.println("publishing error");
delay(1000);
return;
}
b) Call the connected()
method of client
object in a while loop
, read the message and print it out to the serial output.
while (client->connected()) {
while (client->connected() && !client->available()); // wait
char c = client->read();
Serial.print(c);
}
c) Stop the publication of messages on PubNub over the GPRS connection by calling the stop()
method of the client
object, then blink the LED as a confirmation with the flash(true)
function.
client->stop();
Serial.println();
flash(true);
This complete the code needed in your sketch.
Run your Application
With the code complete, you can now upload the sketch to your board. Once this is completed, you can monitor the serial output in Arduino and will see something similar to the following:
You can also view the published messages on the PubNub App Debug console.
1) In the Quick Links menu of your PubNub app, click Debug Console.
2) Specify the Channel, Publish Key and Subscribe Key information.
3) Click Subscribe and you'll see the data communication in the messages console, as shown below.
Congratulations, you now have a device that tracks your bike by publishing GPS data using LinkIt ONE GPRS support for the PubNub LinkIt ONE Library.
Creating your Bike Tracker Map
For the tracker to be a practical tool you will want to display the GPS data on a map. An option for doing this is Mapbox.
To start you will need to create a Mapbox account. Once this is done, the Bike Tracker tutorial follows the general steps of application development on the Mapbox.
Create a new Mapbox project for the Bike Tracker
The Mapbox project enables you to styling your map, using a style provided by Mapbox or a custom one you create. For this project use one of the styles provided by Mapbox.
1) Click New Project to create your map.
2) Select a style for the map.
3) Navigate to Project from the top menu, then Settings to name your project
4) Click Save to save your changes.
Obtaining your project's API access token and a Map ID
Each Mapbox project is identified by an API access token and a Map ID, which you can find in your project details:
These identifiers will be used to specify the Mapbox map and display the GPS location gathered from the Bike Tracker on the EON dashboard.
EON real-time dashboard mapping
The location data acquired by the LinkIt ONE development board and communicated to the PubNub Global Data Stream Network can now be visualized using your Mapbox map from the data on the EON real-time dashboard. To achieve this you need some JavaScript code to establish the data communication and connectivity with the data published on PubNub.
The detailed description of the EON maps and examples could be found at the EON Maps GitHub Repository.
To create your bike tracking map:
1) Clone the EON Maps GitHub Repository to your local file system.
2) Navigate to examples
folder located in the eon-map folder of the cloned repository.
3) Create and save an HTML file in the examples
folder.
4) Add the content for the CSS and JavaScript supporting files from Mapbox (mapbox.css
and mapbox.js
) and PubNub (pubnub.min.js
and pubnub-mapbox.js
) as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>EON Maps</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position:absolute;
top:0;
bottom:0;
width:100%;
}
</style>
<link href="../lib/mapbox.css" rel="stylesheet" />
<script src="../lib/mapbox.js"></script>
<script src="../bower_components/pubnub/web/pubnub.min.js"></script>
<script src="../pubnub-mapbox.js"></script>
</head>
<body>
<div id='map'></div>
<script>
5) Provide the subscribe key of your PubNub account and define the data communication channel for the Bike Tracker. The channel name should match the one defined in the Arduino Sketch, see Define the variables.
var pubnub = PUBNUB({ subscribe_key: 'demo', ssl: true });
var channel = 'bike-map';
6) Define the EON map function. Provide the name of your project (id)
, API access token (mb_token)
and map ID (mb_id)
matching your Bike Tracker map created in Mapbox, see Create a new Mapbox Project for the Bike Tracker.
eon.map({
pubnub: pubnub,
id: 'map',
mb_token: 'mapbox api token',
mb_id: 'mapbox map id,
channel: channel,
7) Add formatting to the map and provide a personalized icon URL for the bike.
options: {
zoomAnimation: false,
},
marker: function (latlng, data) {
var marker = new L.Marker(latlng, {
icon: L.icon({
iconUrl: 'https://d30y9cdsu7xlg0.cloudfront.net/png/15274-200.png',
iconSize: [24, 24]
})
});
var popup = '';
if (data) {
popup = 'Courier ' + data + '';
}
else {
var popup = 'No data available';
}
marker.bindPopup(popup);
return marker;
}
});
var point = {
latlng: [37.370375, -97.756138]
};
</script>
</body>
</html>
8) Open the saved HTML file in your browser and enjoy the real-time tracking of your bike ride.
Conclusion
In this tutorial you have implemented a real-time bike tracker mapping application using the LinkIt ONE development board, PubNub Global Data Stream Network, Mapbox maps, EON real-time dashboard and Arduino programming environment.
For more information on MediaTek LinkIt ONE development and prototyping board refer to LinkIt ONE developer's guide. For more information on the PubNub LinkIt ONE library refer to here.
Comments
Please log in or sign up to comment.