#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include "pitches.h"
#define SPEAKER_PIN 11
#define SERVO_PIN 2
#define SERVO_LOCKED_POS 0 // position of the servo motor when in locked status
#define SERVO_UNLOCKED_POS 90 // position of the servo motor when in unlocked status
Servo lockServo;
LiquidCrystal_I2C lcd (0x27,20,4);
const int ROW_NUM = 4;
const int COLUMN_NUM = 3;
byte pin_rows[ROW_NUM] = {9,8,7,6};
byte pin_column[COLUMN_NUM] = {5,4,3};
char keys[ROW_NUM][COLUMN_NUM] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
int currTry;
int leftTry;
int maxTry = 3;
int ledRed = 12;
int ledGreen = 13;
char key;
boolean statusLocked = true;
boolean instance = false;
boolean isSuccessful = false;
String storePassword;
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
//display initial screen
void startScreen(){
while(statusLocked){
lockServo.write(SERVO_LOCKED_POS);
lcd.setCursor(4, 0);
lcd.print("LOCKED!");
lcd.setCursor(1, 1);
lcd.print("'#' to Unlock");
ledStatus();
key = keypad.getKey();
if (key){
if (checkKeyLocked(key) && instance == false){ //true when used on the first run
createPass();
}
if (checkKeyLocked(key) && instance == true){ //true when used on the consecutive runs
locked();
}
}
}
}
// create new one time password when used for the first time
void createPass(){
while(statusLocked){ //door is still on the locked status
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter new pass:");
String newPass = passwordInpt();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Confirm new pass:");
String confirmPass = passwordInpt();
//verify if the new pass and confirm pass matches
if (newPass.equals(confirmPass)){
instance = true;
storePassword = newPass;
lcd.clear();
success();
startScreen();
}
else {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Password");
lcd.setCursor(4, 1);
lcd.print("Mismatch!");
delay(2000);
lcd.clear();
startScreen();
}
}
}
void locked (){
while(statusLocked){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
String tempPass = passwordInpt(); //store input to tempPass
if (tempPass == storePassword){
lcd.clear();
success();
unlocked();
}
else {
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Password");
lcd.setCursor(3, 1);
lcd.print("Incorrect!");
invalid();
check_first();
currTry +=1;
leftTry = maxTry - currTry;
delay(500);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Attempt/s left:");
lcd.setCursor(7, 1);
lcd.print(leftTry);
check_second();
delay(500);
lcd.clear();
startScreen();
}
}
}
void unlocked(){
isSuccessful = true;
statusLocked = false; //changed statusLocked flag to false
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("UNLOCKED!");
lockServo.write(SERVO_UNLOCKED_POS); //re-position the motor in unlocking
ledStatus();
delay(3000); //automatically locks after 3 seconds
statusLocked = true; //change the flag again to true
lcd.clear();
startScreen();
}
//change LED values depending statusLocked flag
void ledStatus(){
if (statusLocked == true){
digitalWrite(ledRed, HIGH);
digitalWrite(ledGreen, LOW);
}
else{
digitalWrite(ledGreen, HIGH);
digitalWrite(ledRed, LOW);
}
}
//performs an approriate tone when the combination of password is correct
void success(){
tone(SPEAKER_PIN, 650, 750);
delay(100);
tone(SPEAKER_PIN, 900, 1000);
delay(100);
tone(SPEAKER_PIN, 650, 750);
delay(100);
tone(SPEAKER_PIN, 900, 1000);
noTone(SPEAKER_PIN);
}
//performs an approriate tone when the combination of password is incorrect
void invalid(){
tone(SPEAKER_PIN, NOTE_G4);
delay(100);
tone(SPEAKER_PIN, NOTE_C4);
delay(100);
noTone(SPEAKER_PIN);
}
//first part of checking the attempts
void check_first(){
if (isSuccessful){
currTry = 0;
}
isSuccessful = false;
}
//second part of checking the attempts
void check_second(){
if (leftTry == 0){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Intruder Alert!!");
warning();
}
}
//when max attempts used
void warning(){
while(true){
digitalWrite(ledGreen, HIGH);
digitalWrite(ledRed, HIGH);
invalid();
key = keypad.getKey();
if (key == '*'){
currTry = 0;
break; //option to stop the alarm
}
}
}
//prompts the user to input 4-digit password
String passwordInpt(){
lcd.setCursor(5, 1);
lcd.print("[____]");
lcd.setCursor(6, 1);
String result = "";
while (result.length() < 4){
char key = keypad.getKey();
if (key >= '0' && key <='9'){
lcd.print('*');
result += key;
}
}
return result;
}
//check if key == '#'
boolean checkKeyLocked(char input){
if(input != '#'){
return false;
}
else{
return true;
}
}
void setup() {
lcd.init();
lcd.backlight();
lcd.home();
lockServo.attach(SERVO_PIN);
pinMode(SPEAKER_PIN, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
Serial.begin(9600);
statusLocked = true; //statusLocked is set true on default
}
void loop() {
startScreen();
}