Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
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,463
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!
Contact

Comments

Please log in or sign up to comment.