Nafeesa Arif
Published

Smart Gesture and Voice Control for Display Devices IoT

Take the freedom of operating with display devices into your hands and voice commands; eliminating the hassle of finding "the remote"!

IntermediateProtip1,481
Smart Gesture and Voice Control for Display Devices IoT

Things used in this project

Hardware components

ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
×1
IR receiver (generic)
×1
Bipolar - RF Transistor, NPN
Bipolar - RF Transistor, NPN
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×2
LED (generic)
LED (generic)
×1
Osram SFH 4545 IR LEDs
ams OSRAM Osram SFH 4545 IR LEDs
×1

Software apps and online services

SmartThings service
IFTTT SmartThings service
Grandeur
Grandeur

Story

Read more

Schematics

Circuit

IR Transmitter LED

Transmitter is connected to D2 on ESP8266

Source: techposts.org

Ultrasonic Sensors

Sensor A (Channel Changing Sensor ) is connected D5 and D6
Sensor B (Volume Changing Sensor ) is connected D7 and D8

Source: instructables.com

Code

Code

Arduino
/* Including the SDK and WiFi library */
#include <Grandeur.h>
#include <ESP8266WiFi.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include <IRsend.h>
#include <HCSR04.h>

/* Configurations */
String deviceID = "devicel7uetwtp00190kgiegd3f0oc";
String apiKey = "grandeurl7ueq9b600140kgi8dwv165j";
String token = "320d185132d2c303371a1ff6aa42fdee8b4006bd9f3bdaca2f3efcdbdfc93b25";

/* WiFi credentials */
String ssid = "YOUR WIFI SSID";
String password = "PASSWORD";

/*Variables*/
int LED1 = 0;
int LED2 = 0;

const int trigPin[2] = {D6, D8};  //D4
const int echoPin[2] = {D5, D7};  //D3

UltraSonicDistanceSensor distanceSensorA(trigPin[0], echoPin[0]);  // Initialize sensor that uses digital pins 13 and 12.
UltraSonicDistanceSensor distanceSensorB(trigPin[1], echoPin[1]);

int previousDist[2] = {20, 20};
int previousTime[2] = {millis(), millis()};

int currentDist[2];
int currentTime[2];

int interval[2];
double velocity[2];

int timeA = millis();
int timeB = millis();

bool timeNA = false;
bool timeNB = false;

double statVeloVA = 0;
double statVeloVB = 0;
double statVeloH = 0;

// An IR detector/demodulator is connected to D2 (on a NodeMCU board).

const uint16_t kIrLed = D2;  // ESP GPIO pin to use. Recommended: 4 (D2)
IRsend irsend(kIrLed);  // Set the GPIO to be used to sending the message.
decode_results results;


/* Create variable to hold project and device */
Grandeur::Project project;
Grandeur::Project::Device device;

/* Function prototypes */
void onConnection(bool status);
void nextUpdateHandler(const char* path, const char* state);
void prevUpdateHandler(const char* path, const char* state);
void upUpdateHandler(const char* path, const char* state);
void downUpdateHandler(const char* path, const char* state);
void connectWiFi();
int verticalDistance(int sensorNo);
double verticalVelocity(int sensorNo);
double horizontalVelocity();

void setup() {
    /* Begin the serial */
    Serial.begin(9600);

    /* Connect to WiFi */
    connectWiFi();

    /* Initializes the global object "grandeur" with your configurations. */
    project = grandeur.init(apiKey, token);

    /* Get reference to device */
    device = project.device(deviceID);

    /* Sets connection state update handler */
    project.onConnection(onConnection);

    /* Add event handler on state variable */
    device.data().on("next", nextUpdateHandler);
    device.data().on("prev", prevUpdateHandler);
    device.data().on("up", upUpdateHandler);
    device.data().on("down", downUpdateHandler);

    /* Set mode of LED to output */
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(16, OUTPUT);

    /* Turn the LED off by default */
    digitalWrite(LED_BUILTIN, 1);
    digitalWrite(16, 1);
  
    pinMode(2, OUTPUT);
    digitalWrite(2, 1);
    pinMode(16, OUTPUT);
    digitalWrite(16, 1);
    
    pinMode(trigPin[0], OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin[0], INPUT); // Sets the echoPin as an Input
    
    pinMode(trigPin[1], OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin[1], INPUT); // Sets the echoPin as an Input
    
    irsend.begin();

}

void loop() {
    /*  Runs the SDK.
        Connects to Grandeur only after the device is connected to WiFi.
    */
    if(WiFi.status() == WL_CONNECTED) project.loop();

    double veloH = 0, veloVA = 0, veloVB = 0;
    
    if(millis() % 45 == 0)
      veloVB = verticalVelocity(1);
    else if(millis() % 47 == 0)
      veloVA = verticalVelocity(0);

    int distA = distanceSensorA.measureDistanceCm();
    int distB = distanceSensorB.measureDistanceCm();
    
    if(statVeloVA != veloVA && veloVA != 0)
    {
      Serial.printf("Distance A = %d cms\n", distA);
      Serial.printf("Distance B = %d cms\n", distB);
      Serial.printf("Vertical Velocity A = %f m/s\n", veloVA);
      Serial.println();
      if(veloVA >= 0.001)
      {
        Serial.print("Activated Next Channel: ");
        Serial.println(1);
        Serial.println();
        
        irsend.sendNEC(0xFF52AD);
      }
      else if (veloVA <= -0.001)
      {
        Serial.print("Activated Previous Channel: ");
        Serial.println(1);
        Serial.println();
        
        irsend.sendNEC(0xFF12ED);
      }
      statVeloVA = veloVA;
    }

    if(statVeloVB != veloVB && veloVB != 0)
    {
      Serial.printf("Distance A = %d cms\n", distA);
      Serial.printf("Distance B = %d cms\n", distB);
      Serial.printf("Vertical Velocity B = %f m/s\n", veloVB);
      Serial.println();
      statVeloVB = veloVB;
      if(veloVB >= 0.001)
      {
        Serial.print("Activated Volume Up: ");
        Serial.println(1);
        Serial.println();
        
        irsend.sendNEC(0xFF30CF);
      }
      else if (veloVB <= -0.001)
      {
        Serial.print("Activated Volume Down: ");
        Serial.println(1);
        Serial.println();
        
        irsend.sendNEC(0xFF18E7);
      }
    }
}

/* Function to check device's connection status */
void onConnection(bool status) {
    switch(status) {
        case CONNECTED:
            /* Device connected to the cloud */
            
            Serial.println("Device is connected to the Grandeur.");
            
            return;

        case DISCONNECTED:
            /* Device disconnected from cloud */

            Serial.println("Device is disconnected from the Grandeur.");
            return;
    }
}

/* Function to handle state update event */
void nextUpdateHandler(const char* path, const char* state) {

    /* Print state */
    Serial.printf("\nLast Voice Command Received on %s\n", state);
    Serial.printf("Command was change to Next channel! \n");
    LED1 = !LED1;
    /* Update pin level */
    digitalWrite(LED_BUILTIN, !LED1);
    irsend.sendNEC(0xFF52AD);
}

/* Function to handle state update event */
void prevUpdateHandler(const char* path, const char* state) {

    /* Print state */
    Serial.printf("\nLast Voice Command Received on %s\n", state);
    Serial.printf("Command was change to Previous channel! \n");
    LED2 = !LED2;
    /* Update pin level */
    digitalWrite(16, !LED2);
    irsend.sendNEC(0xFF12ED);
}

/* Function to handle state update event */
void upUpdateHandler(const char* path, const char* state) {

    /* Print state */
    Serial.printf("\nLast Voice Command Received on %s\n", state);
    Serial.printf("Command was TV Volume Up! \n");
    LED1 = !LED1;
    /* Update pin level */
    digitalWrite(LED_BUILTIN, !LED1);
    irsend.sendNEC(0xFF30CF);
}

/* Function to handle state update event */
void downUpdateHandler(const char* path, const char* state) {

    /* Print state */
    Serial.printf("\nLast Voice Command Received on %s\n", state);
    Serial.printf("Command was TV Volume Down! \n");
    LED2 = !LED2;
    /* Update pin level */
    digitalWrite(16, !LED2);
    irsend.sendNEC(0xFF18E7);
}

/* Function to connect to WiFi */
void connectWiFi() {
    /* Set mode to station */
    WiFi.mode(WIFI_STA);

    /* Connect using the ssid and password */
    WiFi.begin(ssid, password);

    /* Block till the WiFi is connected */
    while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
    }

    /* Print message */
    Serial.println("");
    Serial.println("WiFi connected");

    /* And IP address */
    Serial.println(WiFi.localIP());
}


int verticalDistance(int sensorNo)
{ 
  
  long duration;
  int dis;
  // Clears the trigPin
  digitalWrite(trigPin[sensorNo], LOW);
  delayMicroseconds(2);
  
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin[sensorNo], HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin[sensorNo], LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin[sensorNo], HIGH);
  
  // Calculating the distance
  dis = duration / 29 / 2;

  return dis;
}

double verticalVelocity(int sensorNo)
{
  currentDist[sensorNo] = verticalDistance(sensorNo);
  currentTime[sensorNo] = millis();

  if(currentDist[sensorNo] > 3 && currentDist[sensorNo] < 50 && currentDist[sensorNo] != previousDist[sensorNo])
  {
    interval[sensorNo] = previousTime[sensorNo] - currentTime[sensorNo];
    if(interval[sensorNo] < 1000)
    {
      velocity[sensorNo] = ( double(previousDist[sensorNo] - currentDist[sensorNo]) / interval[sensorNo] ) / 10;
      previousDist[sensorNo] = currentDist[sensorNo];
      previousTime[sensorNo] = currentTime[sensorNo];
      return velocity[sensorNo];
    }
    else
    {
      previousDist[sensorNo] = currentDist[sensorNo];
      previousTime[sensorNo] = currentTime[sensorNo];
      return 0;
    }
  }
  return 0;
}

double horizontalVelocity()
{
  int distA = distanceSensorA.measureDistanceCm();
  int distB = distanceSensorB.measureDistanceCm();

  if(timeNA == false && timeNB == false)
  {
    if(distA < 50 && distA > 0)
    {
      timeA = millis();
      timeNA = true;
    }
    else if (distB < 50 && distB > 0)
    {
      timeB = millis();
      timeNB = true;
    }
  }
  else if(timeNA == true && timeNB == false)
  {
    if (distB < 50 && distB > 0)
    {
      timeB = millis();
      timeNB = true;
    }
  }
  
  else if(timeNA == false && timeNB == true)
  {
    if (distA < 50 && distA > 0)
    {
      timeA = millis();
      timeNA = true;
    }
  }
  else
  {
    timeNA = false;
    timeNB = false;
    double inter = double(timeB - timeA) / 1000;
    if(abs(inter) > 0.075 && abs(inter) <= 0.450)
      return (0.107 / inter);
  }
  return 0;
}

Credits

Nafeesa Arif
1 project • 8 followers
An ardent lover of building things and learning through new experiences!

Comments