Introduction: Use of GPS, Hall Sensor, LEDs and Firebase With the Edison

The following instructable describes how to connect your Intel Edison using the Grove GPS sensor, Hall sensor and the Base Shield (please note that the Grove GPS does not come standard in the Gove Starter Kit Plus).

The code and design was part of the Los Angeles Intel IoT Roadshow.

Step 1: Hardware Needed:

Intel Edison chip (Included in Grover Starter Kit Plus view here: https://software.intel.com/en-us/iot/hardware/edi...
Arduino Expansion board (Included in Grover Starter Kit Plus)

Base Shield (Included in Grover Starter Kit Plus)

Grove GPS sensor (view here http://www.seeedstudio.com/depot/Grove-GPS-p-959....

Step 2: Software:

-Eclipse C++ (https://software.intel.com/en-us/articles/install-eclipse-ide-on-intel-iot-platforms)
- Drivers (list for various OS https://software.intel.com/en-us/installing-drive)

-Tool Lite (view installation for OS https://software.intel.com/en-us/using-flash-tool

-Intel XDK

Step 3: Prerequisites:

By now you should be familiar with your Arduino Expansion board parts. To refresh your memory please visit http://www.intel.com/support/edison/breakout-bd/sb/CS-035653.htm

Step 4: Assemble of Board:

If this is your first using your Arduino Expansion board and Intel Edison please follow the ‘Assembling the Intel® Edison board with the Arduino expansion board’ tutorial to get your board assembled and ready for use.

-Assembling the Intel® Edison board with the Arduino expansion board

https://software.intel.com/en-us/assembling-intel-...

-Driver installation and updating firmware (enter link https://software.intel.com/en-us/installing-drive.)

-Updating firmware with ToolLite https://software.intel.com/en-us/installing-drive

-Flashing for mac https://software.intel.com/en-us/installing-drive

Once you successfully updated your firmware in a terminal follow the next steps:
~# screen /dev/tty.usbserial <tab> 115200 -L <tab>

~# root (no password)

~# configure_edison --setup


You will now be prompted to name your Edison. Please ensure that your name is unique as there might be a conflict if the name given to the board is the same as that of another user.Make sure that both the machine you are using to connect to your Edison is using the same network (wifi) as your Edison.

If you run into any issues with your wifi and need to re configure it please follow the next steps:

~# configure_edison --wifi

To verify that wifi connectivity is working try pinging a familiar web page such as google.com

Also, from another terminal outside your Edison terminal try pinging your the Edison IP. The IP can be found by running ifconfig from within your Edison terminal.

~# ping <edison ip>

Step 5: Creating Your Project in Eclipse C++

1. Launch your Eclipse C++ and Navigate to “File > New > Intel IoT C/C++ project”

2. Enter a name for your project (note no spaces are allowed).

Step 6: Getting the Code Ready

<strong>The full code is listed at</strong>  <a href="https://github.com/dtorczynski/safety_holster" rel="nofollow"> https://github.com/dtorczynski/safety_holster</a><br>Bellow is the full cpp code used for the hall and gps sensor. Please note that there is also an LED and button being used in the code along with integration with FireBase. 

/*<br> * Author: Thomas Lyet 
<thomas.lyet@intel.com>
 *
 * Copyright (c) 2015 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
// ip address 10.60.0.145
#include "mraa.hpp"</thomas.lyet@intel.com>
#include "UdpClient.hpp"
#include <grove.h>
#include <signal.h>
#include <ublox6.h>
#include <a110x.h>
#include <stdio.h>
#include <curl curl.h="">
#include <iostream>
#include <sstream>
#include <string></string></sstream></iostream></curl></stdio.h></a110x.h></ublox6.h></signal.h></grove.h>
using namespace upm;
using namespace std;
const size_t bufferLength = 256;
/*
 * IoT Cloud Analytics Example
 *
 * Demonstrate how to continuously send data to the IoT Cloud Analytics
 * (https://dashboard.us.enableiot.com/)
 * Read an analog voltage value from an input pin using the MRAA library,
 * then send its value to the IoT Cloud Analytics.
 * Any sensor that outputs a variable voltage can be used with this example
 * code. Suitable ones in the Grove Starter Kit are the Rotary Angle Sensor,
 * Light Sensor, Sound Sensor, Temperature Sensor.
 *
 * - analog in: analog sensor connected to pin A0 (Grove Base Shield Port A0)
 *
 * Additional linker flags: none
 *
*
 * Preliminary Step
 *
 * Follow the IoT Cloud Analytics Getting Started Guide:
 * http://www.intel.com/support/motherboards/desktop/sb/CS-035346.htm
 *
 * Please check if the iotkit-agent is active on your device via
 *  $ systemctl status iotkit-agent
 * If not, activate it with
 *  $ systemctl start iotkit-agent
 *
 * Check the date of your device! It is this date that will be registered
 * in IoT Cloud Analytics.
 *
*
 * NODE (host) and SERVICE (port)
 * iotkit-agent is listening for UDP data
 * as defined in /etc/iotkit-agent/config.json
 */
#define NODE "localhost"
#define SERVICE "41234"
/*
 * COMP_NAME is defined when a component is registered on the device
 *  $ iotkit-admin register ${COMP_NAME} ${CATALOG_ID}
 * In this example :
 *  $ iotkit-admin register temperature temperature.v1.0
 */
#define COMP_NAME "temperature"
int main()
{
	// Create the Grove LED object using GPIO pin 4
	upm::GroveLed* ledRed = new upm::GroveLed(4);
	upm::GroveLed* ledGreen = new upm::GroveLed(3);
	// create an analog input object from MRAA using pin A0
	mraa::Aio* a_pin = new mraa::Aio(0);
	// Create the button object using GPIO pin 8
	upm::GroveButton* button = new upm::GroveButton(8);
	// Instantiate a Ublox6 GPS device on uart 0.
	upm::Ublox6* nmea = new upm::Ublox6(0);
	int gunDrawn = 100;
	int magFieldAvg = 0;
	int magFieldCurrent = 0;
	int magField[10];
	int tempIndex = 0;
	int numSamples = 2;
	string tempData;
	// check that we are running on Galileo or Edison
	mraa_platform_t platform = mraa_get_platform_type();
	if ((platform != MRAA_INTEL_GALILEO_GEN1) &&
			(platform != MRAA_INTEL_GALILEO_GEN2) &&
			(platform != MRAA_INTEL_EDISON_FAB_C)) {
		std::cerr << "Unsupported platform, exiting" << std::endl;
		return MRAA_ERROR_INVALID_PLATFORM;
	}
	// Read in hall sensor data
	if (a_pin == NULL) {
		std::cerr << "Can't create mraa::Aio object, exiting" << std::endl;
		return MRAA_ERROR_UNSPECIFIED;
	}
	// GPS Setup
	// make sure port is initialized properly.  9600 baud is the default.
	if (!nmea->setupTty(B9600))
	{
	  cerr << "Failed to setup tty port parameters" << endl;
	  return 1;
	}
	// Curl setup
	//followed this curl example: http://curl.haxx.se/libcurl/c/http-post.html
	CURL *curl;
	CURLcode res;
	// In windows, this will init the winsock stuff
	curl_global_init(CURL_GLOBAL_ALL);
	// get a curl handle
	curl = curl_easy_init();
	// First set the URL that is about to receive our POST. This URL can
	//   just as well be a https:// URL if that is what should receive the
	//   data.
	curl_easy_setopt(curl, CURLOPT_URL, "https://flickering-inferno-5440.firebaseio.com/data.json");
	//this is only intended to collect NMEA data and not process it
	// should see output on console
	char nmeaBuffer[bufferLength];
	//char tempCharArray[10];
	// loop forever printing the input value every second
	while(1){
		uint16_t pin_value = a_pin->read();
		//std::cout << "analog input value " << pin_value << std::endl;
		//std::cout << "mag field average " << magFieldAvg << std::endl;
		// Calculate magnetic field average
		magFieldAvg = 0;
	    magField[magFieldCurrent++] = pin_value;
		if (magFieldCurrent >= numSamples) {
		  magFieldCurrent = 0;
		}
		for (int i = 0;i<numsamples;i++){ magfieldavg="" +="magField[i];" }="" =="" numsamples;<="" p=""></numsamples;i++){>
		sleep(1);
		if(magFieldAvg < gunDrawn) {
		  ledRed->off();
		  ledGreen->on();
		} else {
		      if (nmea->dataAvailable())
		        {
		          int rv = nmea->readData(nmeaBuffer, bufferLength);
		          if (rv > 0) {
		            write(1, nmeaBuffer, rv);
		            std::cout << nmeaBuffer << std::endl;
		          } else {
		        	 // some sort of read error occurred
		              cerr << "Port read error." << endl;
		              break;
		          }
		          //tempData = "{\"nmeaData\":\"";
		          //for(int i = 70;i<81;i++){
		          //	  tempCharArray[i-70] = nmeaBuffer[i];
		          // }
		          //tempData = tempData + string(nmeaBuffer) + "\"}";
		          //tempData.append(nmeaBuffer);
		          //tempData.append("\"}");
				  // Now specify the POST data
				  //curl_easy_setopt(curl, CURLOPT_POSTFIELDS, tempData.c_str());
				  //std::cout << tempData.c_str() << std::endl;
				  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"gunDrawn\":\"true\"}");
				  // Perform the request, res will get the return code
				  res = curl_easy_perform(curl);
				  // Check for errors
				  //std::cout << "curl output: " << res << std::endl;
				  if(res != CURLE_OK)
					fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
		        }
	      ledRed->on();
		  ledGreen->off();
		}
		if (button->value() == 1) {
			break;
		}
	}
	// Delete the Grove LED object
	ledGreen->off();
	ledRed->off();
	delete ledGreen;
	delete ledRed;
	delete a_pin;
	delete button;
	delete nmea;
	return MRAA_SUCCESS;
}

Step 7: Getting the Hardware and Sensors Connected

The GPS sensor:

The GPS sensor is linked to the UART input of the Base Shield (included in the Grove Starter Kit Plus). Once connected you should see the green light on the sensor turned on, this indicates its properly connected and receiving power.

The Hall sensor:

The Hall sensor is connected to A0 input of the Base Shield.

Take it a step further:

In addition, if you are feeling ambitious the LED sensor is connected to D4 and D3 (one for red and one for green) and the button sensor is connected to D8.

Step 8: Seeing the GPS Data in Action

Note that the GPS data is in NMEA format.

Once you have your the sensors connected to the board you are ready to build and deploy the code.

Once you deploy the code you should see the following in your console in Eclipse.

Step 9: Getting Intel IOT C++ to CURL JSON to Firebase

While Intel Edison provides instructions for having the Intel IOT Edison perform REST API calls with the python and javascript library, the documentation for C++ is lacking.

This example code (http://curl.haxx.se/libcurl/c/http-post.html) along with the instructions below describes how to get the Intel IOT Edison board’s C++ environment to perform CURL calls.

1. Include the .h files at the top of your cpp file:

#include <stdio.h>
#include <curl/curl.h>

2. Ensure curl is linked in the project properties setup.

In order to function, the cURL library must be linked. If you get complier errors, do the following to add the cURL library:

Right click on the project and select properties. Then navigate to C/C++ Build -->Settings --> Cross G++ Linker --> Libraries --> Click the green plus button,and add the “curl” library

3. Set up the code. This will be in your main() cpp code. Note that the highlighted yellow dummy link needs to be replaced with your own Firebase URL.

//CURL Setup
CURL *curl; CURLcode res; // In windows, this will init the winsock stuff curl_global_init(CURL_GLOBAL_ALL); // get a curl handle curl = curl_easy_init(); // First set the URL that is about to receive our POST. This URL can // just as well be a https:// URL if that is what should receive the // data. curl_easy_setopt(curl, CURLOPT_URL, "https://.firebaseio.com/data.json");

4. cURL Call. In the infinite loop portion of the code, perform the CURL call when the appreciate trigger occurs. You will need to replace the JSON data highlighted in yellow with your own data.

if (button->value()==1){
std::cout << button->name() << " value is " << button->value() << std::endl; // Now specify the POST data curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"lat\":23.343,\"long\":234.45345}"); // Perform the request, res will get the return code res = curl_easy_perform(curl); // Check for errors std::cout << "curl output: " << res << std::endl; if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); }

Step 10: See It Live in Action - IoT Smart Holster Demo

The steps showed throughout this tutorial were used on the Smart Holster project in the Santa Monica Intel IoT Roadshow. Below is a demo on how all the pieces come together.

How it all ties in together:

For smart holsters we used the hall sensor and gps sensor for the
functionality and red/green leds and button for demonstration purposes.

The hall sensor was used to detect when the pistol had been drawn out of the holster. In practice we would probably opt for the eddie effect sensor, which would provide greater reliability, but for demonstration magnets were taped on the end of the pistol and used to trigger the withdrawing of the pistol.

The gps was used once the hall sensor read the pistol was withdrawn. At that point gps data was recorded and pushed onto the cloud along with a time stamp to indicate to the person monitoring remotely that the gun had been withdrawn at this specific location. The leds were used to indicate whether the gun was withdrawn. Green indicated it was holstered, red withdrawn. The button was used to stop the program from running.

Overview of Smart Holster:

Through the use of a hall sensor and a gps sensor we aim to track the date, time and location of a weapon being unholstered. This time span will allow a quicker mean to search through the footage which is infrequently reviewed due to the volume of video. Additionally, it provides data for further integration into current crime analytics engines and shooting/crime scene investigations. Furthermore this will assist with additional metrics on effectiveness of de-escalation training programs. Such as the recent LAPD de-escalation training program announced this last week.

GPS locations will start to be tracked when the hall sensor detects a change in magnetic field. The data is then uploaded to the cloud using Firebase. The data can then be manipulated to be displayed on a map making it easier for somebody at the police station to identify locations where a gun is being unholstered. In addition we would like to integrate a live stream of the officer’s body cam on the GPS map.