#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); //LCD Define
Servo doorServo; //servo define
//---------------------------------------------------------
// Pin Definitions
//---------------------------------------------------------
#define SERVO_PIN 9
#define GREEN_LED 11
#define RED_LED 12
#define BUZZER 10
//-------------------------- Keypad -------------------------------
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] =
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] =
{
22,23,24,25
};
byte colPins[COLS] =
{
26,27,28,29
};
Keypad keypad =
Keypad(makeKeymap(keys),rowPins,colPins,ROWS,COLS);
const int EEPROM_ADDR = 0; //EEPROM Address
/*---------------------------------------------------------
Password
---------------------------------------------------------*/
char storedPassword[5] = "1234";
char enteredPassword[5];
byte passwordIndex = 0;
/*---------------------------------------------------------
States
---------------------------------------------------------*/
enum SystemState
{
STATE_MENU,
STATE_ENTER_PASSWORD,
STATE_VERIFY,
STATE_OPEN_DOOR,
STATE_CHANGE_OLD,
STATE_CHANGE_NEW,
STATE_ABOUT
};
SystemState currentState = STATE_MENU;
//---------------------------Timing Variables------------------------------
unsigned long previousMillis = 0;
const unsigned long splashTime = 2000;
/*---------------------------------------------------------
Function Prototypes
---------------------------------------------------------*/
void showMenu();
void readMenu();
void enterPassword();
void verifyPassword();
void openDoor();
void aboutScreen();
void changeOldPassword();
void changeNewPassword();
void loadPassword();
void savePassword();
void clearPasswordBuffer();
void beepSuccess();
void beepError();
void unlockDoor();
void lockDoor();
//====================================================================
// Set-Up
//====================================================================
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
doorServo.attach(SERVO_PIN);
lockDoor();
loadPassword();
showMenu();
}
//====================================================================
// Loop
//====================================================================
void loop()
{
switch(currentState)
{
case STATE_MENU:
readMenu();
break;
case STATE_ENTER_PASSWORD:
enterPassword();
break;
case STATE_VERIFY:
verifyPassword();
break;
case STATE_OPEN_DOOR:
openDoor();
break;
case STATE_CHANGE_OLD:
changeOldPassword();
break;
case STATE_CHANGE_NEW:
changeNewPassword();
break;
case STATE_ABOUT:
aboutScreen();
showMenu();
break;
}
}
//-----------------------------Lock & Unlock Functions-------------------------------
void unlockDoor(){
doorServo.write(90);
}
void lockDoor(){
doorServo.write(0);
}
//--------------------------------Buzzer Functions-------------------------------
void beepSuccess(){
tone(BUZZER, 1500, 150);
}
void beepError(){
tone(BUZZER, 500, 300);
}
//--------------------------------Password Buffer-------------------------------
void clearPasswordBuffer(){
memset(enteredPassword, 0, sizeof(enteredPassword));
passwordIndex = 0;
}
//-------------------------------------------------------------------------------
void showMenu()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1:Open 2:Password");
lcd.setCursor(0, 1);
lcd.print("3:About");
clearPasswordBuffer();
}
//-------------------------------------------------------------------------------
void readMenu()
{
char key = keypad.getKey();
if (!key) return;
switch (key)
{
case '1':
currentState = STATE_ENTER_PASSWORD;
lcd.clear();
lcd.print("Enter Password");
lcd.setCursor(0,1);
break;
case '2':
currentState = STATE_CHANGE_OLD;
lcd.clear();
lcd.print("Old Password");
lcd.setCursor(0,1);
clearPasswordBuffer();
break;
case '3':
currentState = STATE_ABOUT;
break;
}
}
//-------------------------------------------------------------------------------
void enterPassword()
{
char key = keypad.getKey();
if (!key)
return;
if (key >= '0' && key <= '9')
{
if (passwordIndex < 4)
{
enteredPassword[passwordIndex++] = key;
lcd.print('*');
}
}
if (key == '#')
{
enteredPassword[4] = '\0';
currentState = STATE_VERIFY;
}
if (key == '*')
{
clearPasswordBuffer();
lcd.clear();
lcd.print("Enter Password");
lcd.setCursor(0,1);
}
}
//-------------------------------------------------------------------------------
void verifyPassword()
{
lcd.clear();
if (strcmp(enteredPassword, storedPassword) == 0)
{
lcd.print("Access Granted");
beepSuccess();
digitalWrite(GREEN_LED, HIGH);
delay(1000);
digitalWrite(GREEN_LED, LOW);
currentState = STATE_OPEN_DOOR;
}
else
{
lcd.print("Wrong Password");
beepError();
digitalWrite(RED_LED, HIGH);
delay(1000);
digitalWrite(RED_LED, LOW);
clearPasswordBuffer();
currentState = STATE_MENU;
showMenu();
}
}
//-------------------------------------------------------------------------------
void openDoor()
{
lcd.clear();
lcd.print("Door Opening");
unlockDoor();
delay(3000);
lcd.clear();
lcd.print("Door Closing");
lockDoor();
delay(1500);
clearPasswordBuffer();
currentState = STATE_MENU;
showMenu();
}
//-------------------------------------------------------------------------------
void aboutScreen()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Industrial HMI");
lcd.setCursor(0,1);
lcd.print("Version 1.0");
delay(2000);
currentState = STATE_MENU;
showMenu();
}
//-------------------------------------------------------------------------------
void changeOldPassword()
{
char key = keypad.getKey();
if (!key)
return;
if (key >= '0' && key <= '9')
{
if (passwordIndex < 4)
{
enteredPassword[passwordIndex++] = key;
lcd.print('*');
}
}
if (key == '#')
{
enteredPassword[4] = '\0';
if (strcmp(enteredPassword, storedPassword) == 0)
{
lcd.clear();
lcd.print("New Password");
lcd.setCursor(0,1);
clearPasswordBuffer();
currentState = STATE_CHANGE_NEW;
}
else
{
lcd.clear();
lcd.print("Wrong Password");
beepError();
delay(2000);
currentState = STATE_MENU;
showMenu();
}
}
}
//-------------------------------------------------------------------------------
void changeNewPassword()
{
char key = keypad.getKey();
if (!key)
return;
if (key >= '0' && key <= '9')
{
if (passwordIndex < 4)
{
enteredPassword[passwordIndex++] = key;
lcd.print('*');
}
}
if (key == '#')
{
enteredPassword[4] = '\0';
strcpy(storedPassword, enteredPassword);
savePassword();
lcd.clear();
lcd.print("Password Saved");
beepSuccess();
delay(2000);
currentState = STATE_MENU;
showMenu();
}
}
//-------------------------------------------------------------------------------
void loadPassword()
{
for (int i = 0; i < 4; i++)
{
char c = EEPROM.read(EEPROM_ADDR + i);
if (c < '0' || c > '9')
{
strcpy(storedPassword, "1234");
savePassword();
return;
}
storedPassword[i] = c;
}
storedPassword[4] = '\0';
}
//-------------------------------------------------------------------------------
void savePassword()
{
for (int i = 0; i < 4; i++)
{
EEPROM.write(EEPROM_ADDR + i, storedPassword[i]);
}
}