Things used in this project

Hardware components:
Intel.web.720.405
Intel Edison
×1
Intel Arduino expansion board
×1
SeeedStudio Grove base shield V2
×1
SeeedStudio Gas Sensor (MQ2)
×1
SeeedStudio Gas Sensor (MQ5)
×1
SeeedStudio Gas Sensor (MQ9)
×1
SeeedStudio Grove GPS
×1
Cui5nuaex0mk czvqn8v6ersbkzkze9sazv229i3gf4
3DR Solo
×1
Tens70
9V battery (generic)
×2
Keystone 233 image 75px
9V Battery Clip
×1
Software apps and online services:
Ha 2up iot
Amazon Web Services AWS IoT
Simpleicon sns
Amazon Web Services AWS SNS
Iam logo
Amazon Web Services AWS IAM
Rm web services amazon s3
Amazon Web Services AWS S3
Amazon ElasticSearch Service
Kibana: Explore & Visualize Your Data
3DR DroneKit-Python
Hand tools and fabrication machines:
Hy gluegun
Hot glue gun (generic)
Dremel
5/8" spade bit
3/4" spade bit
8mm drill bit

Schematics

Wiring Diagram for Node
This shows how to connect the sensors directly to the Edison breakout board for one of our Nodes without the need for a Base Shield. Download Fritzing to zoom in high quality.
AQMNode.fzz
Wiring Diagram for Node Fritzing Image
Connection Details
Aqmnode bb

Code

Edison_updated.jsJavaScript
//NOTE: This code is unfinished and the dependencies are incomplete. It should be used for reference only at this point  

//node.js deps

//npm deps

//app deps
const thingShadow = require('./thing');
//const isUndefined = require('../common/lib/is-undefined');
//const cmdLineProcess   = require('./lib/cmdline');

//UPM dependencies 
// Load Grove module
var groveSensor = require('jsupm_grove');


var moment = require('moment-timezone');

// Load MQ2 gas sensor module
var upmMQ2 = require("jsupm_gas"); 
// GPS library
var GPSSensor = require('jsupm_ublox6');

// Load RTC Clock module for Grove - RTC clock
var ds1307 = require('jsupm_ds1307');

var GPSSensor = require('jsupm_ublox6');



// Create the MQ2 gas sensor object using AIO pin 0
var MQ2_module = new upmMQ2.MQ2(0);

// Create the temperature sensor object using AIO pin 1
// Create the MQ5 gas sensor object using AIO pin 1
var MQ5_module = new upmMQ2.MQ5(1); // Already declared object of MQ2 sensor is used to save memory


//setup sensor on Analog pin #2 (A2)
var TP401_module = new upmMQ2.TP401(2); // Already declared object of MQ2 sensor is used to save memory

// Create the MQ9 gas sensor object using AIO pin 3
var MQ9_module = new upmMQ2.MQ9(3);

// Instantiate a Ublox6 GPS device on uart 0.
var myGPSSensor = new GPSSensor.Ublox6(0);     

// load this on i2c bus 0
var RTC_module = new ds1307.DS1307(0);



//Define your device name
var Device_Name = 'Node_1';


//exit device if GPS not found
if (!myGPSSensor.setupTty(GPSSensor.int_B9600))
{
  console.log("Failed to setup tty port parameters");
  process.exit(0);
}


// Collect and output NMEA data.
var bufferLength = 256;
var nmeaBuffer  = new GPSSensor.charArray(bufferLength);

//define AWS certificate path paramenters
var args = {


  privateKey:'/home/root/aws_certs/new/privateKey.pem',
  clientCert:'/home/root/aws_certs/new/cert.pem',
  caCert:'/home/root/aws_certs/new/rootCA.crt',
  clientId:'Node_1',
  region:'us-east-1', //at time of writing only region that supports AWS IoT
  reconnectPeriod:'10' //asumming reconnect period in seconds
} 


//create global state variable

var reported_state={ MQ2_gas: 0, MQ5_gas: 0, TP401_gas: 0, MQ9_gas:0, GPS_lat:0, GPS_long:0};

//create global sensor value variables:

//var read_lux = 0;

var read_MQ2 = 0;
var read_MQ5 = 0;
var read_TP401 = 0;
var read_MQ9 = 0;
var read_gpslat=null;
var read_gpslon=null;
var read_time=null;

//launch sample app function 
update_state(args);

function update_state(args) {

  //create a things Shadows object
  
  const thingShadows = thingShadow({
    keyPath: args.privateKey,
    certPath: args.clientCert,
    caPath: args.caCert,
    clientId: args.clientId,
    region: args.region,
    reconnectPeriod: args.reconnectPeriod,
  });

  //When Thing Shadows connects to AWS server:


  thingShadows
    .on('connect', function() {
      console.log('registering device: '+ Device_Name)
  
      //register device
      thingShadows.register(Device_Name);
  
      
      //read sensor values and send to AWS IoT every 5 seconds 
      setInterval(function(){
  
      read_sensor(send_state); 
  
    }, 15000);
  
    });
  
  
  //monitor for events in the stream and print to console:
  
  thingShadows 
    .on('close', function() {
      console.log('close');
    });
  thingShadows 
    .on('reconnect', function() {
      console.log('reconnect');
    });
  thingShadows 
    .on('offline', function() {
      console.log('offline');
    });
  thingShadows
    .on('error', function(error) {
      console.log('error', error);
    });
  thingShadows
    .on('message', function(topic, payload) {
      console.log('message', topic, payload.toString());
    });
  
  //define function for reading sensor
  function read_sensor(cb){

  //  read_lux = light.value();
  
      read_MQ2 = MQ2_module.getSample();
      read_MQ5 = MQ5_module.getSample();
      read_TP401 = TP401_module.getSample();
      read_MQ9 = MQ9_module.getSample();
      read_time=getDateTime();
    getGPSInfo();

    if(read_MQ2 > 10 ){
      thingShadows.publish('Data_1', JSON.stringify({ MQ2_gas: read_MQ2, MQ5_gas: read_MQ5, TP401_gas:read_TP401, MQ9_gas:read_MQ9, GPS_latitude:read_gpslat, GPS_longitude:read_gpslon,Time:read_time}));      //change this <--------------------------------------------------------------------

        
   }
   

    cb();

  };

  //define function for updating thing state:

  function send_state(){

    //define the payload with sensor values
    reported_state ={MQ2_gas: read_MQ2, MQ5_gas: read_MQ5, TP401_gas:read_TP401, MQ9_gas:read_MQ9, GPS_latitude:read_gpslat, GPS_longitude:read_gpslon}; //change this <--------------------------------------------------------------------

    //create state update payload JSON:
    device_state={state: { reported: reported_state }};

    //send update payload to aws:
    thingShadows.update(Device_Name, device_state );

  };

  
};

function getDateTime () {
  return moment().tz('America/Los_Angeles').format().slice(0, 19).replace(/T/, ' ');
   //return new Date().getTime();
}

function getGPSInfo()
{
  // we don't want the read to block in this example, so always
  // check to see if data is available first.
  if (myGPSSensor.dataAvailable())
  {
    var rv = myGPSSensor.readData(nmeaBuffer, bufferLength);

    var GPSData, dataCharCode, isNewLine, lastNewLine;
    var numlines= 0;
    if (rv > 0)
    {
      GPSData = "";
      // read only the number of characters
      // specified by myGPSSensor.readData
      for (var x = 0; x < rv; x++)
        GPSData += nmeaBuffer.getitem(x);
      // <<--------------------------->>
      var data_string=GPSData;
      if (data_string.substring(0,6) == '$GPGGA') {
              gpgga_string = data_string.split('\n')[0];
              gpgga_string = gpgga_string.replace('\n', '');
              gps_data = gpgga_string.split(',');
              console.log('data received: ' + gps_data);
             /* var time_string = gps_data[1];
              var gps_time = new Date();
              var gps_time_hours = parseInt(gps_data[1].substring(0,2));
              var gps_time_minutes = parseInt(gps_data[1].substring(2,4));
              var gps_time_seconds = parseInt(gps_data[1].substring(4,6));
              gps_time.setHours(gps_time_hours);
              gps_time.setMinutes(gps_time_minutes);
              gps_time.setSeconds(gps_time_seconds);
              */
              gps_lat = gps_data[2];
              gps_lat_ns = gps_data[3];
              gps_lon = gps_data[4];
              gps_lon_ew = gps_data[5];
              /*console.log('gps_time', gps_time);
              console.log(gps_lat, gps_lat_ns);
              console.log(gps_lon, gps_lon_ew);*/
                var temp;
                temp=decimalToDMS(gps_lat);
                read_gpslat=temp+ gps_lat_ns;
                //console.log('\n');
                //console.log(temp+ gps_lat_ns);
                temp=decimalToDMS(gps_lon);
                read_gpslon=temp+gps_lon_ew;
                //console.log(temp+gps_lon_ew);

          }





      //<<-------------------------->>
      
    }

    if (rv < 0) // some sort of read error occured
    {
      console.log("Port read error.");
      process.exit(0);
    }
  }
}



// Print message when exiting
process.on('SIGINT', function()
{
  console.log("Exiting...");
  process.exit(0);
});






function decimalToDMS(temp) {
  temp=parseFloat(temp);
deg=parseInt(temp/100);
temp=new String(temp);
temp=temp.slice(2,temp.length);
temp/=60;

temp=deg+temp;
temp=temp.toPrecision(10);
return temp;
}
Drone ControlPython
#!/usr/bin/python
'''
This code is based on drone kit project and a project by Mario Cannistr on hackster.io (Python and Paho for MQTT with AWS IoT)
This code doesn't have any warranty, expressed or implied. 
please execute this using python 3, to connect the drone, please use the proper IP address and port number

'''

import paho.mqtt.client as mqtt
import json, math, time, sys, ssl

from pymavlink import mavutil

import logging, logging.handlers, traceback

from dronekit import connect, Command
import time


# Amazon Webservices Descriptors
cert_path = "/home/ubuntu/Downloads/"
host = "A1KV2GD2H9GCVR.iot.us-east-1.amazonaws.com"
topic = "Data_2"
root_cert = cert_path + "root-CA.crt"
cert_file = cert_path + "8f02d2127a-certificate.pem.crt"
key_file = cert_path + "8f02d2127a-private.pem.key"

#Set up option parsing to get connection string
import argparse  
parser = argparse.ArgumentParser(description='Demonstrates mission import/export from a file.')
parser.add_argument('--connect', 
                   help="Vehicle connection target string. If not specified, SITL automatically started and used.")
args = parser.parse_args()

connection_string = args.connect
sitl = None


#Start SITL if no connection string specified
if not args.connect:
    print "Starting copter simulator (SITL)"
    from dronekit_sitl import SITL
    sitl = SITL()
    sitl.download('copter', '3.3', verbose=True)
    sitl_args = ['-I0', '--model', 'quad', '--home=-35.363261,149.165230,584,353']
    sitl.launch(sitl_args, await_ready=True, restart=True)
    connection_string='tcp:127.0.0.1:5760'


# Connect to the Vehicle
print 'Connecting to vehicle on: %s' % connection_string
vehicle = connect(connection_string, wait_ready=True)

# Check that vehicle is armable. 
# This ensures home_location is set (needed when saving WP file)

while not vehicle.is_armable:
    print " Waiting for vehicle to initialise..."
    time.sleep(1)


def readmission(aFileName):
    """
    Load a mission from a file into a list. The mission definition is in the Waypoint file
    format (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format).

    This function is used by upload_mission().
    """
    print "\nReading mission from file: %s" % aFileName
    cmds = vehicle.commands
    missionlist=[]
    with open(aFileName) as f:
        for i, line in enumerate(f):
            if i==0:
                if not line.startswith('QGC WPL 110'):
                    raise Exception('File is not supported WP version')
            else:
                linearray=line.split('\t')
                ln_index=int(linearray[0])
                ln_currentwp=int(linearray[1])
                ln_frame=int(linearray[2])
                ln_command=int(linearray[3])
                ln_param1=float(linearray[4])
                ln_param2=float(linearray[5])
                ln_param3=float(linearray[6])
                ln_param4=float(linearray[7])
                ln_param5=float(linearray[8])
                ln_param6=float(linearray[9])
                ln_param7=float(linearray[10])
                ln_autocontinue=int(linearray[11].strip())
                cmd = Command( 0, 0, 0, ln_frame, ln_command, ln_currentwp, ln_autocontinue, ln_param1, ln_param2, ln_param3, ln_param4, ln_param5, ln_param6, ln_param7)
                missionlist.append(cmd)
    return missionlist


def upload_mission(aFileName):
    """
    Upload a mission from a file. 
    """
    #Read mission from file
    missionlist = readmission(aFileName)
    
    print "\nUpload mission from a file: %s" % import_mission_filename
    #Clear existing mission from vehicle
    print ' Clear mission'
    cmds = vehicle.commands
    cmds.clear()
    #Add new mission to vehicle
    for command in missionlist:
        cmds.add(command)
    print ' Upload mission'
    vehicle.commands.upload()


def download_mission():
    """
    Downloads the current mission and returns it in a list.
    It is used in save_mission() to get the file information to save.
    """
    print " Download mission from vehicle"
    missionlist=[]
    cmds = vehicle.commands
    cmds.download()
    cmds.wait_ready()
    for cmd in cmds:
        missionlist.append(cmd)
    return missionlist

def save_mission(aFileName):
    """
    Save a mission in the Waypoint file format 
    (http://qgroundcontrol.org/mavlink/waypoint_protocol#waypoint_file_format).
    """
    print "\nSave mission from Vehicle to file: %s" % export_mission_filename    
    #Download mission from vehicle
    missionlist = download_mission()
    #Add file-format information
    output='QGC WPL 110\n'
    #Add home location as 0th waypoint
    home = vehicle.home_location
    output+="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (0,1,0,16,0,0,0,0,home.lat,home.lon,home.alt,1)
    #Add commands
    for cmd in missionlist:
        commandline="%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" % (cmd.seq,cmd.current,cmd.frame,cmd.command,cmd.param1,cmd.param2,cmd.param3,cmd.param4,cmd.x,cmd.y,cmd.z,cmd.autocontinue)
        output+=commandline
    with open(aFileName, 'w') as file_:
        print " Write mission to file"
        file_.write(output)
        
        
def printfile(aFileName):
    """
    Print a mission file to demonstrate "round trip"
    """
    print "\nMission file: %s" % aFileName
    with open(aFileName) as f:
        for line in f:
            print ' %s' % line.strip()        


def drone_response_req():  
    cmds = vehicle.commands
    import_mission_filename = 'waypoint.txt'
        
    #Upload mission from file
    upload_mission(import_mission_filename)

    #Close vehicle object before exiting script
    vehicle.mode    = VehicleMode("GUIDED")
    vehicle.armed   = True
    vehicle.flush()

    while not vehicle.armed and not api.exit:
        print " Waiting for arming..."
    time.sleep(1)

    print "Taking off!"
    vehicle.commands.takeoff(10) # Take off to target altitude
    vehicle.flush()
    print "Starting mission"
    # Set mode to AUTO to start mission
    vehicle.mode = VehicleMode("AUTO")
    vehicle.flush()

    print "Close vehicle object"
    vehicle.close()

    # Shut down simulator if it was started.
    if sitl is not None:
        sitl.stop()


# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    client.subscribe(topic)

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print("payload: "+str(msg.payload))
    data=str(msg.payload);
    ind=data.find('goto_node_1')
    if(ind>-1):
        print ('command requested! ')
        drone_response_req
    else:
        print("Not found!")

   
client = mqtt.Client(client_id="drone_control.py")
client.on_connect = on_connect
client.on_message = on_message
client.on_log = on_log
client.tls_set(root_cert,
               certfile = cert_file,
               keyfile = key_file,
               tls_version=ssl.PROTOCOL_TLSv1_2,
               ciphers=None)

client.connect(host, 8883, 60)

client.loop_forever()
Sample waypoints filePlain text
QGC WPL 110
0	1	0	16	0	0	0	0	42.353613	-83.077283	1.000000	1
1	0	3	22	15.000000	0.000000	0.000000	0.000000	0.000000	0.000000	10.000000	1
2	0	3	18	5.000000	0.000000	5.000000	0.000000	42.353276	-83.078581	100.000000	1
3	0	3	20	0.000000	0.000000	0.000000	0.000000	42.353589	-83.077272	100.000000	1
4	0	3	21	0.000000	0.000000	0.000000	0.000000	42.353589	-83.077272	0.000000	1

Credits

Iotwarriors
IoTWarriors

IoT Warriors is a team comprised of three Wayne State University Engineering students (Pranav Chokda, Kalmajit Chahal, Chris Gregory).

Carciature
Kamaljit Chahal

Martian but totally down to Earth

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Toilet Management System
Advanced
  • 20
  • 2

Work in progress

Using the system multiple persons can share a single toilet efficiently.

GO2
Advanced
  • 77
  • 3

Work in progress

We found an app that will look into the weather and gives you the best manner to go to school or work.

Smart Parking
Advanced
  • 1,660
  • 18

it system that managing cars access to parking place by using Rfid Technology

Smart Parking

Team Hadramoot

ADITI: Affordable Diagnostic Thermal Incubator
Advanced
  • 264
  • 1

Full instructions

ADITI is a connected bodysuit heating enabled incubator for preterm infants measuring ECG, Heart Rate, SpO2,Temp & Respiration comfortably.

How to make Arduino based Automatic Door Opening
Advanced
  • 1,938
  • 7

Full instructions

How to make Arduino based Automatic Door Opening Using HC SR 04

BIO-SMART WEAR
Advanced
  • 147
  • 0

Full instructions

My application is based on the use of this kind of devices to connect our body to the cloud.

BIO-SMART WEAR

Team smartwear

ProjectsCommunitiesContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login
Respect project
Feedback