Project tutorial

Gesture-Controlled Lock © GPL3+

Control a lock by inputting a password via hand gestures.

  • 11,265 views
  • 9 comments
  • 37 respects

Components and supplies

Apps and online services

About this project

*The APDS-9960 sensor does not work with the Arduino Nano or Mega 2560 (in my testing).

This project is easy to make and use. Feel free to use any kind of servo or latching mechanism with this project. This is meant to be a starting platform for a gesture based lock. Onto building!

Materials

I got most of my parts from Amazon.com and the APDS-9960 sensor from Sparkfun. You can only use an Arduino Uno or Micro 3.3v so far, as any other board won't work for some odd reason.

Assembly

Attach the LCD as shown. If you don't have a 10k potentiometer, use a 1k resistor going from contrast to GND. The APDS-9960 sensor will need to be shifted if using the Arduino Uno, so what I did is take the SCL and SDA and connect them to a 4.7k resistor, then draw them high by taking the 4.7k resistor to 3.3v. Then connect them to A4 and A5, accordingly (see schematic). The Arduino can run off of a 9v battery with a DC power barrel attached.

Enclosure

I used a simple cardboard box and cut holes out of it to match where the components would go. You could solder this all to a piece of perfboard, but I just left it in the breadboard and connected jumper wires to the components. After I was finished, it looked like this.

Code

Arduino CodeC/C++
/* Hardware Connections:

IMPORTANT: The APDS-9960 can only accept 3.3V!
 
 Arduino Pin  APDS-9960 Board  Function
 
 3.3V         VCC              Power
 GND          GND              Ground
 A4           SDA              I2C Data
 A5           SCL              I2C Clock
 2            INT              Interrupt

Resources:
Include Wire.h and SparkFun_APDS-9960.h
*/

#include <Wire.h>
#include <SparkFun_APDS9960.h>
#include <LiquidCrystal.h>
#include <Servo.h>

#define PINSIZE 6 
#define SERVOPIN 9//How many gestures long your password is
// Pins
#define APDS9960_INT    2 // Needs to be an interrupt pin
LiquidCrystal lcd(12,11,6,5,4,3);
Servo servo;
uint8_t proximity_data = 0;
int red_led = A1;
int green_led = A2;
int pageNum = 0; //The LCD "page"
String secret[PINSIZE] = {"UP","DOWN","UP","UP","RIGHT","LEFT"}; //Password goes here. Must be in CAPS. Can be "UP", "DOWN", "LEFT", or "RIGHT"
String currentGesture = "";
int numRight = 0;

SparkFun_APDS9960 apds = SparkFun_APDS9960(); //Init APDS-9960 library
int isr_flag = 0;

void setup() {

  // Set interrupt pin as input
  pinMode(APDS9960_INT, INPUT);
lcd.begin(16,2);
servo.attach(SERVOPIN);
servo.write(0);
servo.detach();
  // Initialize Serial port
  Serial.begin(9600);
  Serial.print("Your password is ");
  Serial.print(PINSIZE);
  Serial.println(" gestures long.");
  Serial.println();
  Serial.println(F("----------------"));
  Serial.println(F("APDS-9960 Lock"));
  Serial.println(F("----------------"));
  
  
  // Initialize interrupt service routine
  attachInterrupt(0, interruptRoutine, FALLING);

  // Initialize APDS-9960 (configure I2C and initial values)
  if ( apds.init() ) {
    Serial.println(F("APDS-9960 initialization complete"));
  } else {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  if ( !apds.setProximityGain(PGAIN_1X) ) {
    Serial.println(F("Something went wrong trying to set PGAIN"));
  }
  if ( apds.enableProximitySensor(false) ) {
    Serial.println(F("Proximity sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during sensor init!"));
  }
  // Start running the APDS-9960 gesture sensor engine
  if ( apds.enableGestureSensor(true) ) {
    Serial.println(F("Gesture sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during gesture sensor init!"));
  }
  
}

void loop() {
  if(pageNum==0){
    if ( !apds.readProximity(proximity_data) ) {
    Serial.println("Error reading proximity value");
  } else {
    Serial.println(proximity_data);
    if((proximity_data >= 40) && (pageNum==0)){
    pageNum=1;
    delay(2000);
  }
  }
  }
  
  switch(pageNum){
    case 0:
    LCDClear();
    lcd.print("Locked- get");
    lcd.setCursor(0,1);
    lcd.print("3 inches away.");
    blinkRed();
    LCDClear();
  break;
  
  case 1:
  numRight = 0;
  lcd.print("Enter code...");
  lcd.setCursor(0,0);
  for(int x=0; x<PINSIZE;x++){
    Serial.println(x);
    while(apds.isGestureAvailable()==false){
      
    }
    if( isr_flag == 1 ) {
    detachInterrupt(0);
    handleGesture();
    isr_flag = 0;
    attachInterrupt(0, interruptRoutine, FALLING);
    if(currentGesture != "NONE"){
    if(currentGesture==secret[x]){
    LCDClear();
    lcd.print("Next");
    numRight += 1;
    analogWrite(green_led,255);
    delay(1000);
    allOff();
  }
  else if(currentGesture != secret[x]){
    LCDClear();
    lcd.print("Wrong, return to");
    lcd.setCursor(0,1);
    lcd.print("main page.");
    analogWrite(red_led,255);
    delay(1000);
    allOff();
    pageNum = 0;
    break;
  }
  if(numRight == PINSIZE){
    pageNum = 2;
    break;
  }
    }
    else if(currentGesture == "NONE"){
      LCDClear();
      lcd.print("Not recognized:");
      lcd.setCursor(0,1);
      lcd.print("Try again.");
      x -= 1;
    }
  }
  }
  
  break;

  case 2:
  LCDClear();
  lcd.print("Enter now.");
  pageNum = 0;
  servo.attach(SERVOPIN);
  servo.write(90);
  enter();
  delay(1000);
  servo.write(0);
  break;
  }
  
  
  
}

void interruptRoutine() {
  isr_flag = 1;
}

void handleGesture() {
    if ( apds.isGestureAvailable() ) {
    switch ( apds.readGesture() ) {
      case DIR_UP:
        Serial.println("UP");
        LCDClear();
        lcd.print("Up");
        currentGesture = "UP";
        break;
      case DIR_DOWN:
        Serial.println("DOWN");
        LCDClear();
        lcd.print("Down");
        currentGesture = "DOWN";
        break;
      case DIR_LEFT:
        Serial.println("LEFT");
        LCDClear();
        lcd.print("Left");
        currentGesture = "LEFT";
        break;
      case DIR_RIGHT:
        Serial.println("RIGHT");
        LCDClear();
        lcd.print("Right");
        currentGesture = "RIGHT";
        break;
      case DIR_NEAR:
        Serial.println("NEAR");
        LCDClear();
        lcd.print("Near");
        currentGesture = "NEAR";
        break;
      case DIR_FAR:
        Serial.println("FAR");
        LCDClear();
        lcd.print("Far");
        currentGesture = "FAR";
        break;
      default:
        Serial.println("NONE");
        LCDClear();
        lcd.print("None");
        currentGesture = "NONE";
    }
  }
}

void allOff(){
  analogWrite(red_led,0);
  analogWrite(green_led,0);
}

void blinkRed(){
  analogWrite(red_led,255);
  delay(250);
  allOff();
  delay(250);
}


void LCDClear(){
  lcd.clear();
  lcd.setCursor(0,0);
}

void enter(){
  //total delay of 16 seconds
  for(int x=0;x<30;x++){
  analogWrite(green_led,255);
  delay(100);
  allOff();
  delay(100);
}
for(int x=9;x>0;x--){
  LCDClear();
  lcd.print("Closing in: ");
  lcd.setCursor(0,1);
  lcd.print(x);
  lcd.setCursor(1,1);
  lcd.print(" seconds...");
  delay(1000);
}
LCDClear();
lcd.print("Closing");
}

Schematics

Schematic
Schematic bb3 ojgtzuoyct

Comments

Similar projects you might like

Arduino Keyless Door Lock System with Keypad and LCD

Project tutorial by DIY Hacking

  • 15,297 views
  • 9 comments
  • 43 respects

Gesture-Controlled Car

Project showcase by ashish_8284

  • 3,560 views
  • 2 comments
  • 13 respects

Electronic Safe with Arduino

Project showcase by chummer1010

  • 24,882 views
  • 28 comments
  • 54 respects

Android App-Based Home Automation System Using IOT

Project tutorial by Team Autoshack

  • 24,826 views
  • 17 comments
  • 75 respects

Door Lock System with Arduino

Project showcase by jayesh_nawani

  • 15,683 views
  • 2 comments
  • 15 respects

[Airbnb] Sigfox Lock Box

Project tutorial by Antoine de Chassey

  • 8,056 views
  • 0 comments
  • 12 respects
Add projectSign up / Login