KevinZhangHKSteve KimGraham Hoyes
Published

Eye Lock

A smarter smart door than your smart door! Use the power of facial recognition and natural language technology to make a true smart door.

AdvancedFull instructions provided10 hours12,320
Eye Lock

Things used in this project

Story

Read more

Custom parts and enclosures

Complete Circuit

The complete circuit used

Schematics

Nema 17 Stepper Motor Circuit

The circuit used to control the Nema 17 Stepper Motors

Photo Resistor Circuit

Circuit schematic for the photo resistor

Temperature and Humidity Sensor (DHT11) Circuit

Circuit schematic for the DHT11

LED Circuit

Circuit schematic used to control the LED

Soil Moisture Sensor Circuit

The circuit schematic used for the soil moisture sensor

Code

Python Flask Server

Python
from flask import Flask 
from flask_ask import Ask,  request, session, statement, question
from random import randint
import serial 
from recognition_tutorial import initialization, recognize

arduinoSerial = serial.Serial("/dev/ttyACM0", 9600, timeout=1)
app = Flask(__name__) 
ask = Ask(app, '/') 

isDoorOpen = 0
initialization();

#start of Alexa handler
@ask.launch
def launch():	
	return question("Welcome, this is eye lock!")

@ask.intent("testLightOn") 
def testLightOn(): 
	arduinoSerial.write(b'O') 
	return question("Test light turned on!") 

@ask.intent("testLightOff") 
def testLightOff(): 
	arduinoSerial.write(b'X') 
	return question("Test light turned off!") 

@ask.intent("getOutdoorCondition") 
def getOutdoorCondition():
	arduinoSerial.write(b'A')
	soilMoisture = arduinoSerial.readline()
	sunLight = arduinoSerial.readline()
	temperature = arduinoSerial.readline()
	humidity = arduinoSerial.readline()

	if (int(soilMoisture) < 15):
		soilMoisture = "dry. "
	elif (int(soilMoisture) < 25):
		soilMoisture = "fairly dry. "
	elif (int(soilMoisture) < 60):
		soilMoisture = "damp. "
	elif (int(soilMoisture) < 80):
		soilMoisture = "fairly wet. "
	else: soilMoisture = "flooded. "

	if (int(sunLight) < 10):
		sunLight = "It is pitch black, probably night time. "	
	elif (int(sunLight) < 25):
		sunLight = "There seems to be moonlight, it is probably night time. " 	
	elif (int(sunLight) < 50):
		sunLight = "It is cloudy, overcast skies. "	
	elif (int(sunLight) < 80):
		sunLight = "It is a nice day, but not excessively bright. "   	
	else: sunLight = "It is super bright. "

	returnStatement = "Here is information about the weather outside. The ground is " + soilMoisture + sunLight + "The temperature is " + str(float(temperature)) + " degrees Celsius. " + "And the relative humidity is " + str(float(humidity)) + " percent."

	return statement(returnStatement)

@ask.intent("checkTemp")
def checkTemp():
	arduinoSerial.write(b'T')
	temperature = arduinoSerial.readline()
	returnStatement = "The temperature is " + str(float(temperature)) + " degrees Celsius. "
	return statement(returnStatement)

@ask.intent("checkHumid")
def checkHumid():
	arduinoSerial.write(b'H')
	humidity = arduinoSerial.readline()
	returnStatement = "The relative humidity is " + str(float(humidity)) + " percent."
	return statement(returnStatement)

@ask.intent("doorUnlock") 
def doorUnlock():
	global isDoorOpen
	if (isDoorOpen == 1):
		return statement("The door is already open!")
	
	if (recognize() == "s1"): 
		arduinoSerial.write(b'o')
		isDoorOpen = 1
		return statement("The door has been unlocked and opened")
	
	return question("Sorry, your face is not recognized, would you like to try again?")

@ask.intent("doorLock") 
def doorLock():
	global isDoorOpen
	if (isDoorOpen == 1):
		isDoorOpen = 0
		
	return statement("Door has been locked")

if __name__ == "__main__":
	app.run(debug=True) 

ASK Dialog Model

JSON
{
  "languageModel": {
    "intents": [
      {
        "name": "AMAZON.CancelIntent",
        "samples": []
      },
      {
        "name": "AMAZON.HelpIntent",
        "samples": []
      },
      {
        "name": "AMAZON.StopIntent",
        "samples": []
      },
      {
        "name": "checkHumid",
        "samples": [
          "humidity",
          "hows the humidity outside",
          "whats the humidity outside"
        ],
        "slots": []
      },
      {
        "name": "checkTemp",
        "samples": [
          "what's the temperature outside my door",
          "whats the temperature outsid",
          "temperature"
        ],
        "slots": []
      },
      {
        "name": "doorLock",
        "samples": [
          "lock the door",
          "close the door",
          "close",
          "door close",
          "please close the doo"
        ],
        "slots": []
      },
      {
        "name": "doorUnlock",
        "samples": [
          "unlock the door",
          "open the door",
          "open",
          "unlock",
          "please open the door"
        ],
        "slots": []
      },
      {
        "name": "getOutdoorCondition",
        "samples": [
          "whats the weather outside",
          "hows the weather outside",
          "weather outside",
          "weather"
        ],
        "slots": []
      },
      {
        "name": "test",
        "samples": [
          "test"
        ],
        "slots": []
      },
      {
        "name": "testLightOff",
        "samples": [
          "turn light off",
          "light off"
        ],
        "slots": []
      },
      {
        "name": "testLightOn",
        "samples": [
          "turn light on",
          "light on"
        ],
        "slots": []
      }
    ],
    "invocationName": "eyelock"
  }
}

Arduino Code

Arduino
#include <SimpleDHT.h>
// #include <dht.h>


/* ==========================================================
eyeLock

By: Steve Kim, Graham Hoyes, Kevin Zhang
==============================================================
*/

// Setting pin assignments

#define led 2
#define photoPin 1
#define moisturePin 0
#define tempHumidPin 7
#define stepPin 9
#define dirPin 8
#define enable 13

//const int stepPin = 9;
//const int dirPin = 8;
//const int enable = 13;

char cmd = 'Z';

int minLight; // Used to calibrate the readings for brightness
int maxLight;
int lightLevel;
int normalizedLightLevel;

int minMoisture; // Used to calibrate the readings for moisture levels
int maxMoisture;
int moistureLevel;
int normalizedMoistureLevel;

SimpleDHT11 dht11; 

void setup() {
 Serial.begin(9600);
 
 pinMode(led, OUTPUT);
 pinMode(stepPin,OUTPUT);
 pinMode(enable,OUTPUT);
 
 // Setup the starting light level limits
 lightLevel = analogRead(photoPin);
 minLight = lightLevel-20;
 maxLight = lightLevel;

 
 // Setup the starting moisture level limits
 moistureLevel = analogRead(moisturePin);
 minMoisture = moistureLevel-20;
 maxMoisture= moistureLevel;
 
 //Turn off motor initially 
 digitalWrite(enable,HIGH);
 
}

void loop() { 
  cmd = 'Z';
  
  if (Serial.available() > 0){
    cmd = Serial.read();
  }
  
  if (cmd == 'O') { 
    digitalWrite(led, HIGH);
  }
  else if(cmd == 'X') {
    digitalWrite(led, LOW);
  } 
  else if(cmd == 'A') {
    /*Start of soil moisture sensor code*/
    moistureLevel = analogRead(moisturePin);
    
    if(minMoisture >  moistureLevel){
      minMoisture =  moistureLevel;
    }
    if(maxMoisture < lightLevel){
      maxMoisture = lightLevel;
    }
    
    //Adjust the light level for a normalized result b/w 0 and 100.
    normalizedMoistureLevel = map(moistureLevel, minMoisture, maxMoisture, 100, 0);
    
    /*Start of photocell code*/
    //auto-adjust the minimum and maximum limits in real time
    lightLevel = analogRead(photoPin);
    
    if(minLight > lightLevel){
      minLight = lightLevel;
    }
    if(maxLight < lightLevel){
      maxLight = lightLevel;
    }

    //Adjust the light level for a normalized result b/w 0 and 100.
    normalizedLightLevel = map(lightLevel, minLight, maxLight, 100, 0);

    /*Start of temp and humidity sensor code*/
    byte temperature = 0;
    byte humidity = 0;
    dht11.read(tempHumidPin, &temperature, &humidity, NULL);
    
    /*Printing results to serial*/
    Serial.println(normalizedMoistureLevel);
    Serial.println(normalizedLightLevel);
    Serial.println(int(temperature));
    Serial.println(int(humidity));
  }
  else if(cmd == 'T') {
    /*Start of temp and humidity sensor code*/
    byte temperature = 0;
    byte humidity = 0;
    dht11.read(tempHumidPin, &temperature, &humidity, NULL);
    
    Serial.println(int(temperature));  
  }
  else if(cmd == 'H') {
    byte temperature = 0;
    byte humidity = 0;
    dht11.read(tempHumidPin, &temperature, &humidity, NULL);
    
    Serial.println(int(humidity));
  }
  else if(cmd == 'o') { 
    digitalWrite(enable,LOW);
    
    Serial.println("opening");

    digitalWrite(dirPin,HIGH);
    for(int x = 0; x < 7000; x++) {
      digitalWrite(stepPin,HIGH);   
      delayMicroseconds(1200); 
      digitalWrite(stepPin,LOW); 
      delayMicroseconds(1200); 
    }
    digitalWrite(enable,HIGH);
  }
  else if(cmd == 'c') {
    digitalWrite(enable,LOW);
    
    Serial.println("closing");
    
    digitalWrite(dirPin,LOW); 
    for(int x = 0; x < 7000; x++) {
      digitalWrite(stepPin,HIGH);
      delayMicroseconds(1200);
      digitalWrite(stepPin,LOW);
      delayMicroseconds(1200);
    }  
    digitalWrite(enable,HIGH);
  
  }
  delay(50);
}

Capture Photos

Python
import cv2

cam = cv2.VideoCapture(0)

cv2.namedWindow("test")

img_counter = 0

while True:
    ret, frame = cam.read()
    cv2.imshow("test", frame)
    if not ret:
        break
    k = cv2.waitKey(1)

    if k%256 == 27:
        # ESC pressed
        print("Escape hit, closing...")
        break
    elif k%256 == 32:
        # SPACE pressed
        img_name = "opencv_frame_cam_{}.jpg".format(img_counter)
        cv2.imwrite(img_name, frame)
        print("{} written!".format(img_name))
        img_counter += 1

cam.release()

cv2.destroyAllWindows()

EyeLock Repository

Github Repository

Credits

KevinZhangHK

KevinZhangHK

4 projects • 10 followers
Steve Kim

Steve Kim

1 project • 3 followers
Graham Hoyes

Graham Hoyes

1 project • 4 followers

Comments