Ryan ChanConnor CherneskyCuong Nguyen
Published © GPL3+

Touchless Hand Gesture Door Opener

Open a garage door using only hand gestures!

IntermediateFull instructions provided5 hours6,299
Touchless Hand Gesture Door Opener

Things used in this project

Hardware components

Arduino Nano Every
Arduino Nano Every
×1
Proximity Sensor- Pyroelectric Infrared Sensor Module
KEMET Electronics Corporation Proximity Sensor- Pyroelectric Infrared Sensor Module
×2
HM-10 Bluetooth Low Energy Module
×1
Garage Door Remote
×1
16x2 LCD Screen
×1
Power MOSFET N-Channel
Power MOSFET N-Channel
×1
Resistor 10k ohm
Resistor 10k ohm
×1
Resistor 220 ohm
Resistor 220 ohm
330 ohm will also work. This is for the LCD back-light
×1
Resistor 2k ohm
×1
Resistor 1k ohm
Resistor 1k ohm
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
Female headers
×1
3-pin Screw Terminal
×2
2-pin Screw Terminal
×1
JST 5-pin Cable (1 mm pitch)
×2

Software apps and online services

Arduino IDE
Arduino IDE
Any BLE Serial Terminal App

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
3D Printer (generic)
3D Printer (generic)
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Custom parts and enclosures

Main Enclosure

Lid

Schematics

PCB Gerber File

Breadboard Schematic

Code

Code

Arduino
//This is the password to grant you access to change the doorCode
const String bluetoothPassword = "YourPasswordHere";

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

SoftwareSerial softSerial =  SoftwareSerial(6, 7); //setup software serial (rxPin(in), txPin(out))
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //setup LCD
const int inputSensor = A0; //input sensor analog pin 0
const int enterSensor = A1; //enter sensor analog pin 1
const int doorPin = 8; //garage remote pin 8
const int backlightPin = 9; //LCD back light pin 9

unsigned long timeout = 0;
bool stabilized = false;

int doorCodeDecimal = 0; //code in decimal form as it is stored in the Arduino's EEPROM


void setup() {
  lcd.begin(16, 2);
  pinMode(inputSensor,INPUT); //input sensor connected to A0
  pinMode(enterSensor, INPUT); //enter sensor connected to A1
  pinMode(doorPin, OUTPUT); //Setup door pin
  pinMode(backlightPin, OUTPUT); //setup LED backlight pin

  softSerial.begin(9600); //setup serial with Bluetooth
  doorCodeDecimal = EEPROM.read(0); //read password saved in device

  //allow time for device to warm up
  digitalWrite(backlightPin, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Warming up...");
  delay(30000);
}

void loop() {

  sleepMode(); //sleep when not in use, while allowing interactions through Bluetooth

  //The sensor detects a hand

  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print("Current:");

  String userInput = "";
  int signalsRead = 0; //how many signals have been read
  bool correctPassword = false;
  while (signalsRead < 8 && !correctPassword) {
  //read signals till code is right or tell the user at the end of 8 readings that the password was wrong

    //wait for enter signal
    lcd.setCursor(0, 0);
    lcd.print("Ready!        ");
    timeout = millis() + 10000;
    while (digitalRead(enterSensor) < 1 && millis() < timeout) { }
    if (millis() >= timeout) { break; }

    //******if there is no signal for 2 secs, the input is 0; 1 otherwise
    lcd.setCursor(0, 0);
    lcd.print("Reading...      ");
    timeout = millis() + 500;
    while (millis() < timeout) {
      if (digitalRead(inputSensor) > 0) {
        userInput += "1";
        break;
      }
    }
    if (userInput.length() == signalsRead) { userInput += "0"; }
    signalsRead++; //record that a new signal is recorded
    //******------------------------------------------------------------

    //display input
    lcd.setCursor(8, 1);
    lcd.print(userInput);

    if (binaryToDecimal(userInput) == doorCodeDecimal) {
      correctPassword = true; //compare user input and actual password. If they equal, terminate and tell user the result
    }

    stabilized = false; //wait for the input sensor to stabilize (read all 0 for 1 second straight)
    lcd.setCursor(0, 0);
    lcd.print("Remove hand...  ");
    while (!stabilized) {
      stabilized = stabilize(inputSensor);
    }
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  if (correctPassword) {
    lcd.print("Correct Password!");
    lcd.setCursor(0, 1);
    lcd.print("Opening Door...");
    digitalWrite(doorPin, HIGH);
    delay(5000); //give garage door time to open
    digitalWrite(doorPin,LOW);
    lcd.setCursor(0, 1);
    lcd.print("Door Opened!   ");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Have a Good Day!");
    delay(1000);
  } else {
    lcd.print("Wrong Password!");
    lcd.setCursor(0, 1);
    lcd.print("Maybe Try Again!");
    delay(1000);
  }
}


void sleepMode() { //wait for enter signal while reading inputs from Bluetooth terminal
  digitalWrite(backlightPin, HIGH);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Sleeping..."); delay(1000);
  digitalWrite(backlightPin, LOW);
  lcd.clear();
  while (digitalRead(enterSensor) < 1) { //while the user hasn't hit ENTER
    if (softSerial.available()) { //check to see if user wants to change the door code
      String input = softSerial.readString();
      input = input.substring(0, input.length() - 2); //take off the \n from input
      
      if (input.equals(bluetoothPassword)) { //If the input equals the password, allow the user to change the doorCode
        boolean enteredCode=false;
        softSerial.println("\nInput new door code:\n");
        String doorCodeBinary;
        
        while(!enteredCode){ 
          if(softSerial.available()){
             doorCodeBinary= softSerial.readString();
             enteredCode=true;
          }
        }       
        doorCodeBinary = doorCodeBinary.substring(0, doorCodeBinary.length() - 2);
        delay(500);
        doorCodeDecimal = binaryToDecimal(doorCodeBinary);
        EEPROM.write(0, doorCodeDecimal);
        softSerial.println("\nNew door code is: " + doorCodeBinary + "\n");
      }
    }
  }
  digitalWrite(backlightPin, HIGH);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Booting up...");
  stabilized = false; //wait for enter sensor to be stabilized
  while (!stabilized) {
    stabilized = stabilize(enterSensor);
  }
}

bool stabilize(int sensorPin) { //looped until the sensor reads only 0 for 1 second straight
  unsigned long period = millis() + 1000;
  while (millis() < period) {
    if (digitalRead(enterSensor) > 0) {
      return false;
    }
  }
  return true;
}

int binaryToDecimal(String n) { //convert code in Binary into Decimal
  int output = 0;
  int factor = 0;
  while (n.length() != 0) {
    int lastNum = (n.substring(n.length() - 1)).toInt();
    if (lastNum == 1) {
      output += bit(factor);
    }
    factor += 1;
    n = n.substring(0, n.length() - 1);
  }
  return output;
}

Credits

Ryan Chan

Ryan Chan

9 projects • 228 followers
I like turtles. I also like robots.
Connor Chernesky

Connor Chernesky

1 project • 2 followers
Cuong Nguyen

Cuong Nguyen

1 project • 1 follower
Programmer. Robotic Engineer

Comments