Car Tracker

Introduction

Car Tracker utilizes the LinkIt ONE development board’s GNSS features to acquire the position and the speed of a vehicle. The data is then uploaded to the MediaTek Cloud Sandbox (MCS) over a GPRS connection. MCS then provides a visualization of the data on a map. For more advanced metrics an accelerometer is also attached to the board, to collect data on the g-forces generated by the vehicle.

By the end of this tutorial you’ll have a fully functioning IoT prototype, which gathers GPS and accelerometer data, then transmits the data through a GPRS connection to enable control and visualization using a cloud service through a web interface or Android app.

This tutorial guides you through:

  • Building the prototype, with details of the hardware requirements and how to put them together to create the Car Tracker.
  • Adding your Car Tracker to the MCS, creating the data channels to collect the sensor data and obtaining the information to use in the software to send data to MCS.
  • Creating the software to provide the interfaces with the sensor to collect the data and implement data communications to send that data to the MCS.
  • Using the MCS to view that data collected on the Car Tracker, including using the MCS app on an Android smartphone or tablet (running Android v. 4.0 or above) to view data while away from your PC.

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.

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.

Activate your MediaTek Cloud Sandbox account

To make use of the MediaTek Cloud Sandbox register for a Labs account, it’s free, and activate your MCS account to prototype your own devices and applications. By registering on Labs you also gain access to the hardware reference designs and the ability to submit and respond to items in the forums.

An Android device

The application supports smartphones and tablets running Android v. 4.0 or above, with an active data connection (mobile network or Wi-Fi). In this particular scenario Android smartphone (Samsung Galaxy) is used.

Building the Car Tracker hardware

This section describes the hardware and electronics needed to build Car Tracker and provides details on how to put them together.

What you need

To build the Car Tracker hardware, in addition to a LinkIt ONE development board, you need the following components:

ComponentDescriptionSource
SensorADXL345 digital accelerometerGrove - 3-Axis Digital Accelerometer (±16g)
AntennasGSM/GPRS antenna covering 850/900/1800/1900 MHz frequency range and classified as Class 12.
GPS + GLONASS antenna.
LinkIt ONE Development Kit
CableMicro-USB cable 
PowerPolymer Li-ion 1000mAh batteryLinkIt ONE Development Kit

Schematics

The components of the Car Tracker are assembled according to the following schematic diagram:

Electronic circuit diagram of the Car Tracker

This image was created with Fritzing.

Putting the components together

This section provides step-by-step instructions on putting the Car Tracker hardware together. At the end you’ll have a Car Tracker similar to the one shown below: 

Hardware setup of the Car Tracker

Step 1 — Antennas

Attach the GPS+GLONASS, dual purpose Wi-Fi/Bluetooth and GSM antennas to their corresponding pins on the LinkIt ONE development board as follows:

Connecting the antennas

Step 2 — Accelerometer

Attach a digital accelerometer to the LinkIt ONE development board using the Grove - Universal 4 Pin buckled cable. The accelerometer is based on ADXL-345 and is connected to the Grove interface on the LinkIt ONE development board.

Step 3 — Power source

The power source in this tutorial is a polymer lithium-ion battery and 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.

Breadboard view of the Car Tracker

This image was created with Fritzing.

Setup the MCS

In this project you’ll be using MCS to collect and visualize the data recorded by the Car Tracker hardware. The setup is described in two parts: first creating a new Car Tracker prototype and then create a new device — the cloud space that will interact with your physical device — based on the Car Tracker prototype.

MCS development cycle

Activate a MCS account to prototype your own devices and applications. The Car Tracker tutorial follows the general steps of application development on the MCS.

Create a new prototype for the Car Tracker

A prototype serves as a blueprint for the actual hardware setup. The prototype consists of one or more data channels of type display, controller and hybrid. The data channels are defined with a Data channel name, Data channel id and data type as required parameters. The variety of data types and overall structure of the prototype in general is shown in the figure below.

General prototype content in MCS

The Car Tracker prototype in this tutorial has five data channels to display the vehicle location on a map based on GPS coordinates, speed of the car and the g-forces experienced by the car. This section describes how to create and configure a Car Tracker prototype with necessary data channels.

  1. Sign in to MCS with a pre-registered MediaTek Labs account to create and prototype your own devices and applications.Signing into the MCS
  2. Click Development from the navigation toolbar, and then under Prototype list click Create to create a new prototype, as shown below.
    Create a new prototype
  3. Provide information, to define a basic profile of this prototype.
    Define a Car Tracker prototype
    Save the information and proceed to the next step. 

    Fields marked by a red asterisk () are required fields.

  4. Click Detail to view the prototype information, as shown below.
    View or modify the Car Tracker prototype
  5. Click Exit to bypass initiation instructions, as shown below:
    Bypassing the data channel initiation instructions 

Add data channels

The required data channels are created at this stage.

  1. Click Add under Data channel toolbar, as shown below to provide data channels for the Car Tracker prototype.Add a data channel to the Car Tracker prototype
  2. Controller and Display are data channel types available to use. Create a Display data channel for GPS map location, speed and g-force data visualization on MCS by clicking Add. First, you’ll create the map location data channel.
    Data channel types
  3. Enter the information for Data channel nameData channel idDescription and Data type for position data channel and click Save, as shown in the figure below.GPS location data channel details

    The Data channel name and Data Channel id define the data channel and will be used in an Arduino sketch to communicate the data from the board to the MCS.

    Repeat steps 1 and 2 to create data channels for speed and g-forces on the X, Y and Z axes. The Data type is float and the unitTypes is miles/hour for the speed of the car. The g-force on the Z axis has a Data channel name Acceleration/Breaking and Data channel id zForce. The g-force on the X axis has a Data channel name Up/Down Force and Data channel idxForce. The g-force on the Y axis has a Data channel name Centrifugal Force and Data channel id yForce. The unitTypes of g-forces is Others. More details on the information you need to provide when setting up a data channel, please refer to Key concepts found in MCS documentation.

    You should now have a complete definition of the Car Tracker prototype, as shown below.


    Car Tracker prototype definition

 

Create a new device based on the Car Tracker prototype

Each prototype on MCS is defined on a specific hardware platform. The hardware platform assigned in this tutorial is the LinkIt ONE development board. The Car Tracker prototype is mapped to the actual device by taking the following steps.

  1. Click Development from the MCS toolbar, and then click Car Tracker Prototype detail.
  2. Click Create test device to configure a new device.
    Creating a test device for the Car Tracker prototype
  3. Provide Device name, as an example device name shown in the figure below, click OK to continue.
    Car Tracker test device configuration
  4. Click Go to detail, as shown in the figure below to view the device information.
    Confirmation on creating a device for the Car Tracker prototype
  5. It’s essential to store the DeviceID and DeviceKey values in a file or hardcode them in an Arduino sketch (see Overview of the Arduino Sketch) to enable API calls and device connectivity.
    Device details for the Car Tracker prototype

You have now created a new device in MCS matching the Car Tracker prototype with five display data channels for the position on the map, speed and g-forces. Next section describes the Car Tracker’s software implementation.

Create your Car Tracker’s software

Your Car Tracker needs an Arduino Sketch to share data from an onboard GPS receiver and an accelerometer sensor with MCS. This section describes the software required as follows:

  • Overview of the Arduino sketch.
  • Configuring device and GPRS settings.
  • Transmitting sensor data to the MCS.
  • Integrating with MediaTek Cloud Sandbox on a PC and a mobile device.

Overview of the Arduino Sketch

An Arduino sketch is implemented, verified and uploaded to the LinkIt ONE development board. The source code is provided in a GitHub repository. For the accelerometer operation download the ADXL-345 driver. The HTTP communication is supported by an HTTPClient driver. Add the downloaded libraries to the Arduino libraries folder.

Start your Arduino project

Create a new Arduino Sketch - software that will run on the LinkIt One development board.

  1. Open Arduino IDE and by default a new sketch is created and showed.
  2. Create a folder named CarTracker in your documents folder and on the File menu clickSave As navigate to the selected folder, name the sketch CarTracker.ino and save it.
    Empty project in Arduino IDE

Add the supporting libraries

Add the libraries to the CarTracker.ino Arduino sketch. The libraries that are part of LinkIt ONE API are listed below: 

#include <LGPS.h> 
#include <LFlash.h> 
#include <LSD.h> 
#include <LStorage.h> 
#include <LGPRS.h> 
#include <LGPRSClient.h> 

These provide support for GPS, GPRS, and data storage communication and their detailed description can be found in the LinkIt ONE API guide.

HTTP communication

The HTTP communication header file is from the HTTP library.

#include "HttpClient.h"

Wire communication

This library allows you to communicate with an I2C device

#include <Wire.h>

Accelerator communication

This library allows you to communicate with a digital accelerometer. 

#include "ADXL345.h"

Custom libraries

These libraries are custom defined and the detailed content will be described in sections The The GPSWaypoint class and The GPSFunctions class.

#include "GPSWaypoint.h"
#include "GPS_functions.h"

Add source code to the sketch CarTracker.ini

A sketch is a source code file representing the core controlling logic for the LinkIt ONE development board. It consists of the following:

  • setup() function that initializes resources, such as the GPRS module.
  • loop() function that continuously listens to and processes events from hardware sensors and software modules such as those for GPRS. The loop() function runs forever — until the device is shutdown.

Configure device settings

Once the libraries are included, provide the device ID and device key information. The device ID and device key were generated when the test device for Car Tracker prototype was created; see Create a new device based on the Car Tracker prototype. The device ID and device key are used to identify the Car Tracker hardware and they are defined as constant values in a CarTracker.ini where you can replace the quoted text with your device’s information.

#define DeviceID "DD1XLRmX"
#define DeviceKey "Xokkflue7CgSv2kj"

Initializing the communication

The setup() function is called only once at the beginning of the program and provides for initialization of the GPS, GPRS and digital accelerometer communication.

  1. Initiate serial communication by calling the begin() function of the Serial class. Provide the communication data rate in bits per second (baud) for serial data transmission. For the Car Tracker tutorial the baud rate is set to 115200. Then call the powerOn()function of the LGPS class to start the GPS communication and wait for three seconds (delay(3000)) for the connection to be established, as in the code below: 

    void setup()
    {
     /* add setup code here */
    
     Serial.begin(115200);
     LGPS.powerOn();
     Serial.println("LGPS Power on, and waiting ...");
     delay(3000);
  2. Set a timeout on the HTTP communication by calling the setHttpResponseTimeoutfunction of the HTTP class, as shown in the code below: 

    http.setHttpResponseTimeout(15);
  3. Configure the Access Point Name (APN) settings of your GPRS connectivity to connect to the remote network services over TCP by calling the attachGPRS() function of the LGPRS class in a while loop. The attachGPRS() function requires APN, username and password as input parameters provided by your network telecom operator. If the settings are not verified allow 500 ms wait time to continuously establish the GPRS connection using your telecom operator’s information. After successful initialization, a message "Success" is sent to the output of the serial port. Then the accelerometer is turned on by calling powerOn() function of the adxl class. 

    Serial.print("Connecting to GPRS:");
      while (!LGPRS.attachGPRS("apn", "username", "password"))
      {
       delay(500);
      }
      Serial.println("Success");
    
     adxl.powerOn();
    }

    The complete setup() function is shown below:

    void setup()
    {
      /* add setup code here */
    
      Serial.begin(115200);
      LGPS.powerOn();
      Serial.println("LGPS Power on, and waiting ...");
      delay(3000);
    
    
      http.setHttpResponseTimeout(15);
    
      Serial.print("Connecting to GPRS:");
      while (!LGPRS.attachGPRS("everywhere", "eesecure", "secure"))
      {
       delay(500);
      }
       Serial.println("Success");
    
     adxl.powerOn();
    }

Add a loop() function

  1. The loop function is executed continuously providing formatted GPS coordinates such as latitude and longitude, speed and extra g-force data. The function call hierarchy is provided in the figure below:

  2. The function getGPSData() is where you get the position data from. It is defined in the GPSFunctions class and the details are provided in The GPSFunctions class

    void loop()
    {
     Serial.print("Start");
     /* add main program code here */
     char GPS_formatted[] = "GPS fixed";
     Serial.print("Started");
     gpsPosition = new GPSWaypoint();
     gpsSentenceInfoStruct gpsDataStruct;
     // Get GPS data and upload location and speed
     getGPSData(gpsDataStruct, GPS_formatted, gpsPosition);
  3. Sending data to the MCS
    Upload the position and speed data to the device specified by its deviceID and deviceKey. Functions uploadData() and uploadAccelerations() use the formatted data to upload them to the Car Tracker. The first uploadData() function sends the formatted position data to the device. Then the second uploadData() function sends the car speed value to the device converting the floating point number into a string. 

    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 = String(buffer_latitude) + "," + String(buffer_longitude) + "," + "0" + "\n" + "latitude,," + buffer_latitude + "\n" + "longitude,," + buffer_longitude;
    uploadData(DeviceID, DeviceKey, "position", upload_GPS);
    uploadData(DeviceID, DeviceKey, "speed", String(gpsPosition->speed));
    // upload accelerations
    uploadAccelerations();
    }

     

    Make sure the DeviceIDs in the source code match to the ones defined in the MCS prototype, see Add data channels.

     

  4. uploadData() — while the HTTP connection is still established upload the string data in valueForKey to the device specified by the deviceID and deviceKey.
     

    Syntaxvoid uploadData(const char* deviceID, const char* deviceKey,const char* dataKey, String valueForKey)
    Parametersconst char* deviceID, const char* deviceKey,const char* dataKey, String valueForKey
    Return valuevoid


  5. uploadAccelerations() — uploads accelerations and g-forces on the X, Y and Z axes while the HTTP connection is still established.

    Syntaxvoid uploadAccelerations()
    Parametersvoid
    Return valuevoid

Add classes in Arduino

The project is based on several classes that provide the position estimation functionality of the LinkIt ONE development board.

  1. To add source and header files, click on the top right drop down menu then select New Tab, as shown below.
    Adding new source and header files
  2. Name the new file as GPS_functions.cpp.
  3. Repeat the same step and create GPS_functions.hGPSWaypoint.cpp and GPSWaypoint.h source and header files.

The GPSWaypoint class

The GPSWaypoint class is used to store information and pass it between the different functions.

  1. Define a class GPSWaypoint in a GPSWaypoint.h header file. The class contains public attributes for longitude, latitude and speed as floating numbers, north or south (char* n_or_s) and east or west (char* e_or_w) directions as character arrays and an indicator for the position fix (int has_fix) as an integer. Constructor and destructor methods are GPSWaypoint() and ~GPSWaypoint(), respectively. 

    class GPSWaypoint
    {
    public:
     float longitude;
     float latitude;
     char* n_or_s;
     char* e_or_w;
     float speed;
     int has_fix;
    
     GPSWaypoint();
     ~GPSWaypoint();
    };
  2. Provide a default constructor and destructor source code for the GPSWaypoint class in a GPSWaypoint.cpp file as follows.

    #include "GPSWaypoint.h"
    GPSWaypoint::GPSWaypoint()
    {
    }
    
    GPSWaypoint::~GPSWaypoint()
    {
    }	~GPSWaypoint();
    };

The GPSFunctions class

The ultimate goal of a GPS receiver is to provide position, velocity, and time information. The National Marine Electronics Association (NMEA) has developed a specification that defines the interface between various pieces of marine electronic equipment. The standard permits marine electronics to send information to computers and to other marine equipment. NMEA format is common for real time position estimation including the complete PVT (position, velocity, time) solution computed by the GPS receiver. The idea of NMEA is to send a line of data called a sentence that is totally self-contained and independent from other sentences. All NMEA sentences are sequences of ASCII symbols beginning with a '$' and ending with a carriage return/line feed sequence and can be no longer than 80 characters of visible text (plus the line terminators). The GPSFunctions class contains position and speed estimation functionality based on the NMEA specification. The focus of this class is to decode NMEA sentences including the GGA (Global Positioning System Fix Data), the RMC (Recommended Minimum sentence C) and the GSA (Satellite status) data.

  1. parseGPGGA() — This function decodes the received sentence according to the NMEA specification. It starts with an if statement that looks for a ‘$’ sign in a NMEA sentence. Once it’s found an integer variable tmp is declared and assigned to the location of the first comma in a string. This will define the time information. The position information - GPS latitude and longitude coordinates are found after the second comma in a NMEA sentence. Directions indicating north, south, east or west are found similarly. The data is then converted into an appropriate format by calling the convertCoords() function. 

    void parseGPGGA(const char* GPGGAstr, GPSWaypoint* wayPoint){
    
     if (GPGGAstr[0] == '$'){
      int tmp;
      tmp = getComma(1, GPGGAstr);
    
      //get lat/lon coordinates
      float latitudetmp;
      float longitudetmp;
      tmp = getComma(2, GPGGAstr);
      latitudetmp = getFloatNumber(&GPGGAstr[tmp]);
    
      tmp = getComma(3, GPGGAstr);
      //char* n_or_s = getCharString(&GPGGAstr[tmp]);
      Serial.print("Temp:");
      Serial.println(tmp);
      char n_or_s = GPGGAstr[tmp];
      Serial.print("North or South ");
      Serial.println(n_or_s);
    
      tmp = getComma(4, GPGGAstr);
      longitudetmp = getFloatNumber(&GPGGAstr[tmp]);
    
      tmp = getComma(5, GPGGAstr);
      char e_or_w = GPGGAstr[tmp];
      Serial.print("East or West ");
      Serial.println(e_or_w);
    
      // need to convert format
      convertCoords(latitudetmp, longitudetmp, &n_or_s, &e_or_w, wayPoint->latitude, wayPoint->longitude);
    
      //get lat/lon direction
      tmp = getComma(3, GPGGAstr);
    
      tmp = getComma(5, GPGGAstr);
    
    
      //get GPS fix quality
      tmp = getComma(6, GPGGAstr);
      wayPoint->has_fix = getIntNumber(&GPGGAstr[tmp]);
    
      //get satellites in view
      tmp = getComma(7, GPGGAstr);
    
     }
     else{
      Serial.println("No GPS data");
     }
    }
    Syntaxvoid parseGPGGA(const char* GPGGAstr, GPSWaypoint* wayPoint)
    Parametersconst char* GPGGAstr, GPSWaypoint* wayPoint
    Return valuevoid
  2. printGPGGA() — format the latitude and longitude data and send to the serial output when there is a position fix.

    Syntaxboolean printGPGGA(char* str, char* GPS_formatted, GPSWaypoint* wayPoint)
    Parameterschar* str, char* GPS_formatted, GPSWaypoint* wayPoint
    Return valueboolean
  3. nextToken() — copy content of the buf character array into src character array from a specified location.

    Syntaxconst char *nextToken(char* src, char* buf)
    Parameterschar* src, char* buf
    Return valueconst char*
  4. getGPSData() — acquire the current position of the vehicle. Because acquiring the position can take some time, the function will check if there is a fix on the position and if not, wait for half a second and try again. Once the position is determined, the data is read out and stored in a GPSWaypoint object.

    Syntaxvoid getGPSData(gpsSentenceInfoStruct &g_info, char* GPS_formatted, GPSWaypoint* positionData)
    ParametersgpsSentenceInfoStruct &g_info, char* GPS_formatted, GPSWaypoint* positionData
    Return valuevoid
    void getGPSData(gpsSentenceInfoStruct &g_info, char* GPS_formatted, GPSWaypoint* positionData)
    {
    
     boolean GPS_fix = false;
    
     int loopCounter = 0;
    
     while (!GPS_fix)
     {
      LGPS.getData(&g_info); //get the data from the GPS and store it in 'g_info'
      parseGPGGA((char*)g_info.GPGGA, positionData);
    
      if (positionData->has_fix > 0){
       GPS_fix = true;
      }
      else if (loopCounter == 10){
       GPS_fix = true;
      }
    
      if (GPS_fix){
       readSpeed((char*)g_info.GPVTG, positionData);
      }
      delay(500);
      loopCounter++;
    
     }
    
    }

    LGPS.getData() is the API call to acquire the current position. The position comes back in a gpsSentenceInfoStruct structure. Within this structure you find different types of NMEA sentences. A sentence is a comma delimited string with different types of information about the acquired position. For this tutorial you’ll use the GPGGA (Global Positioning System Fix Data) for the location and the GPVTG (Track Made Good and Ground Speed) for reading out the speed.

    Example of GPGGA NMEA sentence is shown below: 

    $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
    
     Where:
      GGA Global Positioning System Fix Data
      123519 Fix taken at 12:35:19 UTC
      4807.038,N Latitude 48 deg 07.038' N
      01131.000,E Longitude 11 deg 31.000' E
      1 Fix quality: 0 = invalid
                     1 = GPS fix (SPS)
                     2 = DGPS fix
                     3 = PPS fix
                     4 = Real Time Kinematic
                     5 = Float RTK
                     6 = estimated (dead reckoning) (2.3 feature)
                     7 = Manual input mode
                     8 = Simulation mode
      08 Number of satellites being tracked
      0.9 Horizontal dilution of position
      545.4,M Altitude, Meters, above mean sea level
      46.9,M Height of geoid (mean sea level) above WGS84
            ellipsoid
      (empty field) time in seconds since last DGPS update
      (empty field) DGPS station ID number
      *47 the checksum data, always begins with *
  5. convertCoords() — convert latitude and longitude from degrees, minutes and seconds to floating point numbers. The positive or negative sign indicates the direction.

    Syntaxvoid convertCoords(float latitude, float longitude, const char* n_or_s, const char* e_or_w, float &lat_return, float &lon_return)
    Parametersfloat latitude, float longitude, const char* n_or_s, const char* e_or_w, float &lat_return, float &lon_return
    Return valuevoid
    void convertCoords(float latitude, float longitude, const char* n_or_s, const char* e_or_w, float &lat_return, float &lon_return){ 
    
     /*
     Latitude	5213.2930,N	-->	52d 13.2930' N
     52 degrees 13.2930 minutes NORTH
     52 + (13.2930 / 60) = 52.22155
     Because it is north of the equator, the number remains positive.
     +52.22155
     */
    
     int lat_deg_int = int(latitude / 100);	//extract the first 2 chars to get the latitudinal degrees
     float latitude_float = latitude - (lat_deg_int * 100); //remove the degrees part of the coordinates - so we are left with only minutes-seconds part of the coordinates
     lat_return = lat_deg_int + latitude_float / 60;	//add back on the degrees part, so it is decimal degrees
    
     //Check if it is N or S, S will turn the value negative
    
     if (*n_or_s == 'S'){
      Serial.println("is South");
      lat_return *= -1;
     }
    
     /*
     Longitude	00004.5337,W	-->	00d 04.5337' W
     00 degrees 4.5337 minutes WEST
     00 + (4.5337 / 60) = 0.0755616
     Because it is West, the number becomes negative.
     -0.0755616
     */
    
     int lon_deg_int = int(longitude / 100);
     float longitude_float = longitude - lon_deg_int * 100;
     lon_return = lon_deg_int + longitude_float / 60;
     if (*e_or_w == 'W'){
      Serial.println("is West");
      lon_return *= -1;
     }
    }
  6. arrayToInt() — converts character array into an integer.

    Syntaxint arrayToInt(const char* char_array)
    Parametersconst char* char_array
    Return valueint
  7. arrayToFloat() — converts character array into an floating point number.

    Syntaxfloat arrayToFloat (const char* char_array)
    Parametersconst char* char_array
    Return valuefloat
  8. getComma() — identifies the location of a comma in a given string

    Syntaxstatic unsigned char getComma(unsigned char num, const char *str);
    Parametersunsigned char num, const char *str
    Return valuestatic unsigned char
  9. getIntNumber() — given a character array identifies the comma and converts each comma separated string into an integer.

    Syntaxstatic int getIntNumber(const char *s);
    Parametersconst char *s
    Return valuestatic int
  10. getFloatNumber() — given a character array identifies the comma and converts each comma separated string into a floating point number.

    Syntaxstatic float getFloatNumber(const char *s)
    Parametersconst char *s
    Return valuestatic float
  11. getCharString() — given a character array identifies the comma and returns each comma separated character.

    Syntaxstatic float getCharString (const char *s)
    Parametersconst char *s
    Return valuestatic float
  12. readSpeed() — read the GPVTG speed information from the NMEA sentence.

    Syntaxvoid readSpeed(char* str, GPSWaypoint* wayPoint)
    Parameterschar* str, GPSWaypoint* wayPoint
    Return valuevoid
    void readSpeed(char* str, GPSWaypoint* wayPoint){
     //GPVTG
     Serial.print(str);
     Serial.println("->readSpeed");
    
    
     float speed_temp;
     int tmp = getComma(7, str);
     speed_temp = getFloatNumber(&str[tmp]);
     speed_temp *= 0.621371; // convert to miles per hour
    
     Serial.println(speed_temp);
    
     wayPoint->speed = speed_temp;
    
    }

    The full list of function definitions in GPSFunction.h header file is shown below. 

    static unsigned char getComma(unsigned char num, const char *str);
    static int getIntNumber(const char *s);
    static float getFloatNumber(const char *s);
    static char* getCharString(const char *s);
    void parseGPGGA(const char* GPGGAstr, GPSWaypoint* wayPoint);
    boolean printGPGGA(char* str, char* GPS_formatted, GPSWaypoint* wayPoint);
    const char *nextToken(char* src, char* buf);
    void getGPSData(gpsSentenceInfoStruct &g_info, char* GPS_formatted, GPSWaypoint* positionData);
    void convertCoords(float latitude, float longitude, const char* n_or_s, const char* e_or_w, float &lat_return, float &lon_return);
    int arrayToInt(const char* char_array);
    float arrayToFloat(const char* char_array);
    void readSpeed(char* str, GPSWaypoint* wayPoint);

Now you can compile and upload the sketch to the LinkIt ONE development board as described in the LinkIt ONE quick start guide, then follow the instructions in the next section to visualize the output on the MCS.

Remote access to the MCS

In previous sections you’ve successfully created a prototype associated with the Car Tracker using MCS and programmed the software to define the connectivity and data channels in Arduino IDE. To visualize the output of the source code on the MCS console click My Devices on the MCS toolbar to view existing devices or add one.

View available devices on MCS


Accessing Car Tracker device details

Click Detail on Car Tracker device from the Device list menu. The location on the map and values of speed and accelerometer will be on the display as shown in Add data channels. Each of those controls has a shortcut menu. Open the shortcut menu for data channel to view the available options.

Card menu History and API Hint options

The History option provides all the past and present values of the data channel, in this case Centrifugal force.

Values of centrifugal force over time

 

Congratulations, you have now completed the Car Tracker prototype setup.

MCS provides mobile app to remotely control the existing prototypes connected to the LinkIt ONE development board. Download and install the app on an Android smartphone or tablet device to get started with the Car Tracker tutorial on a mobile device.

Conclusion

In this tutorial you have implemented a remote controlled Car Tracker application using LinkIt ONE development board, accelerometer, MediaTek Cloud Sandbox and Arduino programming environment.

For more information on MediaTek LinkIt ONE development and prototyping board and cloud services refer to LinkIt ONE developer’s guide and MediaTek Cloud Sandbox.