Things used in this project

Hardware components:
Ard yun
Arduino Arduino Yun
×1
SeeedStudio Grove Starter Kit for Arduino
×1
Software apps and online services:
Ha 2up iot
Amazon Web Services AWS IoT
Screen%20shot%202015 07 20%20at%206.10.26%20pm
Amazon Web Services AWS Lambda
Uber API

Schematics

Arduino Yun and Grove Starter Kit assembly
AWS_IoT_Arduino.fzz

Code

Arduino Yun Pub/Sub to AWS IoTArduino
Publishes button presses (D3) to the "uber" topic and subscribes to "uber_respone" topic to activate the buzzer board (D2).
/*
 * Uber + AWS IoT + Lambda + Arduino
 * 
 * Use an AWS IoT connected Arduino Yun to indicate how far your Uber car
 * is away from you. This project started with the BasicPubSub example by
 * Amazon to interface with AWS IoT.
 * 
 * https://github.com/nothans/Uber-AWS-IoT
 * 
 * Created: January 31, 2016 by Hans Scharler - http://www.nothans.com
 */

// Include AWS IoT
#include <aws_iot_mqtt.h>
#include <aws_iot_version.h>
#include "aws_iot_config.h"

// Setup AWS IoT Client
aws_iot_mqtt_client myClient; // init iot_mqtt_client

// Setup global variables for AWS IoT
char msg[32]; // read-write buffer
int cnt = 0; // loop counts
int rc = -100; // return value placeholder
bool success_connect = false; // whether it is connected

// Create a callback for AWS IoT messages
void msg_callback(char* src, int len) {
  
  Serial.println("CALLBACK:");  
  int i;
  for(i = 0; i < len; i++) {
    Serial.print(src[i]);
  }
  Serial.println("");

  // Get number of beeps
  int n = atoi(src);
  
  // Signal Uber's ETA by beeping the buzzer
  soundBeeps(n, 500, 300);  
  
}

// Define pins for button and buzzer
const int pinButton = 3;
const int pinBuzzer = 2;

void setup() {
  // Configure button pin as a digital input
  pinMode(pinButton, INPUT);

  // Configure buzzer pin as a digital output
  pinMode(pinBuzzer, OUTPUT);
    
  // Start serial for debug / monitoring
  Serial.begin(115200);

  // Wait for serial before AWS IoT setup starts
  while(!Serial);
  //
  char curr_version[80];
  sprintf(curr_version, "AWS IoT SDK Version(dev) %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
  Serial.println(curr_version);
  // Set up the client
  if((rc = myClient.setup(AWS_IOT_CLIENT_ID)) == 0) {
    // Load user configuration
    if((rc = myClient.config(AWS_IOT_MQTT_HOST, AWS_IOT_MQTT_PORT, AWS_IOT_ROOT_CA_PATH, AWS_IOT_PRIVATE_KEY_PATH, AWS_IOT_CERTIFICATE_PATH)) == 0) {
      // Use default connect: 60 sec for keepalive
      if((rc = myClient.connect()) == 0) {
        success_connect = true;
        // Subscribe to "topic1"
        if((rc = myClient.subscribe("uber_response", 1, msg_callback)) != 0) {
          Serial.println("Subscribe failed!");
          Serial.println(rc);
        }
      }
      else {
        Serial.println("Connect failed!");
        Serial.println(rc);
      }
    }
    else {
      Serial.println("Config failed!");
      Serial.println(rc);
    }
  }
  else {
    Serial.println("Setup failed!");
    Serial.println(rc);
  }
  // Delay to make sure SUBACK is received, delay time could vary according to the server
  delay(2000);  
}

void loop() {

  // Check if button is pressed
  if (digitalRead(pinButton)) {
    publishToAWSIoT();
  }

  if (success_connect) {
 
    // Get a chance to run a callback
    if ((rc = myClient.yield()) != 0) {
      Serial.println("Yield failed!");
      Serial.println(rc);
    }
        
  }
    
  delay(1000);
  
}

int publishToAWSIoT() {
  
  if (success_connect) {
    
    // Send the message "estimate" to the "uber_request" topic
    sprintf(msg, "{\"command\":\"estimate\"}", cnt);
    
    if ((rc = myClient.publish("uber", msg, strlen(msg), 1, false)) != 0) {
      Serial.println("Publish failed!");
      Serial.println(rc);
    }
    
    delay(1000);
    
  }
  
}

void soundBeeps(int beeps, int duration, int wait) {
  
    for (int i = 0; i < beeps; i++) {
      
        digitalWrite(pinBuzzer, HIGH);
        delay(duration);
        digitalWrite(pinBuzzer, LOW);
        delay(wait);
        
    }
    
}
AWS Lambda FunctionJavaScript
This Lambda function is triggered when a message on the "uber" topic matches. The function requests data from the Uber API and replies back to the AWS IoT connected Arduino.
var AWS = require('aws-sdk');
var https = require('https');

// Set options for AWS IoT
//   - make sure credentials have AWSIoTDataAccess permissions policy
var CONFIG_AWSIOT = {
  endpoint: 'XXX.iot.us-east-1.amazonaws.com',
  region: 'us-east-1',
  accessKeyId: 'XXX',
  secretAccessKey: 'XXX'
};

// Set options for Uber API  
var CONFIG_UBER = {
  uber_token: "XXX",
  product_id: "XXX",
  start_latitude: 42.300080,
  start_longitude: -71.350349
};

function callUber(event, context) {
    
  var data =  {
    product_id:      CONFIG_UBER.product_id,
    start_latitude:  CONFIG_UBER.start_latitude,
    start_longitude: CONFIG_UBER.start_longitude
  };
  
  data = JSON.stringify(data);
  
  var headers = {
    'Authorization': 'Bearer ' + CONFIG_UBER.uber_token,
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(data)
  };

  var options = {
    host:    'api.uber.com',
    path:    '/v1/requests/estimate',
    method:  'POST',
    headers: headers
  };

  var req = https.request(options, function(res) {
      
    res.on('data', function (chunk) {
        
      uberData = JSON.parse(chunk);
      
      iotdata = new AWS.IotData(CONFIG_AWSIOT);
  
      params = {
        topic: 'uber_response',
        payload: uberData.pickup_estimate.toString(),
        qos: 0
      };
      
      iotdata.publish(params, function(err, data) {
        if (err) {
          console.log(err, err.stack);
          context.fail(event); 
        }
        else {
          console.log(data);
          context.succeed(event);
        }
      });
  
      console.log(chunk.toString());
    });

  });

  req.write(data);
  req.end();
  
  req.on('error', function(e) {
    context.fail(event); 
  });
  
}

exports.handler = callUber;

Credits

83e164e22a0b069f4807cac094df28aa
Hans

IoT Engineer, Maker - I have a toaster that has been tweeting since 2008.

Contact

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

Arduino on Internal Oscillator Crystal as Clock Source
Intermediate
  • 509
  • 41

Protip

Want to make an Arduino having only an ATmega328 chip and nothing else? Not even the crystal oscillator!

IoT Red Phone
Intermediate
  • 240
  • 4

Work in progress

The phone will ring if you have an alert in your AWS Cloudwatch. If you pick up the handset, it tells you whats wrong.

Real-Time Workspace Occupancy Sensing Based on AWS IoT
Intermediate
  • 330
  • 5

Sensor-based presence detection for individual workstations: capturing occupancy trends and space utilization in real-time.

Distance Measurement Vehicle via Websocket
Intermediate
  • 1,337
  • 14

Full instructions

A vehicle measures distance with an encoder on its wheel. It is remotely controlled and transmits the distance via Websocket.

Smart Shoes (Auto-lacing and Generating Electricity)
Intermediate
  • 251
  • 7

Full instructions

Features of smart shoes: generates electricity, auto lacing, step counting, etc.

Barbot: Cocktail Mixing Robot
Intermediate
  • 3,108
  • 16

Full instructions

Barbot is an open source Arduino cocktail mixing robot controlled with the hybrid mobile app via Bluetooth.

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login