//Libraries
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <EEPROM.h>
#include <avr/interrupt.h>
#define Code_l 5
//LCD SETUP
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//KEYPAD SETUP
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] = {6, 7, 8, 9};
byte colPins[COLS] = {A1, A2, A3, A4};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//Variables
char Data[Code_l];//Recieved data
char Data2[Code_l];//Recieved data
char Passcode[Code_l] = {'0', '0', '0', '0'}; //Passcode -initially (Default Passcode)
char Mastercode[Code_l] = {'0', '2', '3', '0'}; //Master Passcode -initially (Default Mastercode)
char OTP[Code_l];// One Time Passcode
byte data_count = 0;//Number of recieved data
char key;//What is the key recieved
byte key_state = 0; //State of the key (To Detect Hold)
char last;//Last Key
byte mode = 0;//Switch between modes
int attemps = 0;// Number of Attemps
boolean done = false; //Check if the time taken
long start; //Started time for admin mode
int test=0;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
DDRB = 0xFF;
TCCR1A = 0x00;
TCCR1B = 0x04;
TIMSK1 |= (1<<TOIE1);
}
void loop() {
if((mode == 2 || mode == 1) && !done){
done = true;
start = test;
}
sei();
if (attemps == 3)
mode = 11;
//Get Data From Keypad
key = keypad.getKey();
key_state = keypad.getState();
if (key) {
last = key;
Serial.println(key);
}
// Mode's Title
//Locked Mode
if (mode == 0) {
lcd.setCursor(1, 0);
lcd.print("Enter Passcode");
PORTB = 0x00;
test = 0;
}
//Unlocked Mode
else if (mode == 1) {
lcd.setCursor(4, 0);
lcd.print("UNLOCKED");
PORTB |= 0x04;
done = false;
}
//Admin Mode (Take MasterCode)
else if (mode == 2) {
lcd.setCursor(3, 0);
lcd.print("ADMIN MODE");
if(test - start == 5)
mode = 0;
}
//Function Mode (ADMIN!)
else if (mode == 3) { //admin mode functions
lcd.setCursor(4, 0);
lcd.print("Function");
test = 0;
}
//Changing MasterCode [Set] (ADMIN!)
else if (mode == 4) {
lcd.setCursor(1, 0);
lcd.print("New Mastercode");
}
//Changing MasterCode [Confirm] (ADMIN!)
else if (mode == 5) {
lcd.setCursor(0, 0);
lcd.print("Enter Code Again");
}
//Changing PassCode [Set] (ADMIN!)
else if (mode == 6) {
lcd.setCursor(2, 0);
lcd.print("New Passcode");
}
//Changing PassCode [Confirm] (ADMIN!)
else if (mode == 7) {
lcd.setCursor(0, 0);
lcd.print("Enter Code Again");
}
//Set OTP (ADMIN!)
else if (mode == 8) {
lcd.setCursor(4, 0);
lcd.print("SET OTP");
}
//Remove OTP (ADMIN!)
else if (mode == 9) {
lcd.setCursor(1, 0);
lcd.print("Removing OTP");
}
//Open Door Mode (ADMIN!)
else if (mode == 10) {
lcd.setCursor(2, 0);
lcd.print("Door is Open");
lcd.setCursor(4, 1);
lcd.print("Weclome");
}
//CoolDown Mode
if (mode == 11) {
lcd.setCursor(4, 0);
lcd.print("CoolDown");
}
// Condition's to take values from keypad (Values feed to Data but you can still press keys)
if (key && key != '#' && key != '*' && mode != 1 && mode != 3 && mode != 10 && attemps != 3) {
collectKey();
} // Condition's to take values from keypad Finished
// Condition to wait for 4 Digit Passcode
if (data_count == Code_l - 1) {
// Locked Mode
if (mode == 0) {
lcd.clear();
// Correct Passcode or OTP(Locked) - if OTP used ? Delete it
if (compare_code (Data, Passcode) || compare_code (Data, OTP)) {
if (compare_code (Data, OTP))
OTP_clear();
lcd.setCursor(4, 0);
lcd.print("Unlocking");
//Delay_1_s ();
digitalWrite (13, HIGH);
mode = 1;
attemps = 0;
} //Correct Passcode or OTP(Locked) Finished
// Incorrect Passcode (Locked)
else {
lcd.setCursor(1, 0);
lcd.print("Wrong Passcode");
//Delay_1_s ();
attemps++;
} //Incorrect Passcode (Locked) Finished
//Delay_1_s ();
lcd.clear();
Data_clear();
} // Locked Mode Finished
// Admin Mode (Password)
else if (mode == 2) {
lcd.clear();
// Correct Mastercode (Admin)
if (compare_code (Data, Mastercode)) {
lcd.setCursor(1, 0);
lcd.print("ACCESS GRANTED");
//Delay_1_s ();
mode = 3;
}// Correct Mastercode (Admin) Finished
// Incorrect Mastercode (Admin)
else {
lcd.setCursor(0, 0);
lcd.print("WRONG MASTERCODE");
//Delay_1_s ();
mode = 0;
} // Incorrect Mastercode (Admin) Finished
//Delay_1_s ();
lcd.clear();
Data_clear();
} // Admin Mode (Password) Finished
// MasterCode Change (ADMIN)
else if (mode == 4) {
lcd.clear();
mode = 5;
for (int i = 0 ; i < Code_l ; i++)
Data2[i] = Data[i];
Data_clear();
} // MasterCode Change (ADMIN) Finished
// MasterCode Confirm (Admin)
else if (mode == 5) {
// Both Mastercode Match
if (compare_code (Data, Data2)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mastercode is");
lcd.setCursor(4, 1);
lcd.print(Data);
//Delay_1_s ();
//Delay_1_s ();
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Saving...");
//Delay_1_s ();
copy_array(Mastercode, Data);
}// Both Mastercode Match Finished
// Missmatch
else {
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("MISSMATCH");
//Delay_1_s ();
} // Missmatch Finished
mode = 3;
//Delay_1_s ();
Data_clear();
lcd.clear();
} // MasterCode Confirm (Admin) Finished
// PassCode Change (ADMIN)
else if (mode == 6) {
lcd.clear();
mode = 7;
for (int i = 0 ; i < Code_l ; i++)
Data2[i] = Data[i];
Data_clear();
} // PassCode Change (ADMIN) Finished
// PassCode Confirm (ADMIN)
else if (mode == 7) {
// Both Passcode Match
if (compare_code (Data, Data2)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Passcode is");
lcd.setCursor(4, 1);
lcd.print(Data);
//Delay_1_s ();
//Delay_1_s ();
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Saving...");
//Delay_1_s ();
copy_array(Passcode, Data);
}// Both Passcode Match Finished
// Missmatch
else {
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("MISSMATCH");
//Delay_1_s ();
} // Missmatch Finished
//Delay_1_s ();
mode = 3;
Data_clear();
lcd.clear();
} // PassCode Confirm (ADMIN) Finished
// Set OTP (ADMIN)
else if (mode == 8) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("OTP is");
lcd.setCursor(4, 1);
lcd.print(Data);
//Delay_1_s ();
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Saving...");
//Delay_1_s ();
//Delay_1_s ();
copy_array(OTP, Data);
mode = 3;
Data_clear();
lcd.clear();
} // Set OTP (ADMIN) Finished
} //Condition to wait for 4 Digit Passcode Finished
// Unlocked Mode
else if (mode == 1) {
boolean done = true;
while ((test - start) != 10) {
key = keypad.getKey();
if (key == 'A') {
mode = 2;
lcd.clear();
done = false;
break;
}
}
if (done)
mode = 0;
} // Unlocked Mode Finished
// Function Selector (ADMIN)
else if (mode == 3) {
// Change Mastercode Function
if (keypad.isPressed('1')) {
mode = 4;
lcd.clear();
} //Change Mastercode Function Finished
// Change Passcode Function
else if (keypad.isPressed('2')) {
mode = 6;
lcd.clear();
} // Change Passcode Function Finished
// SET OTP Function
else if (keypad.isPressed('3')) {
mode = 8;
lcd.clear();
} // SET OTP Function Finished
// Remove OTP Function
else if (keypad.isPressed('4')) {
mode = 9;
lcd.clear();
} // Remove OTP Function Finished
// Open Door Function
else if (keypad.isPressed('5')) {
mode = 10;
lcd.clear();
} // Open Function Finished
// Exit Function
else if (keypad.isPressed('*')) {
mode = 0;
} // Exit Function Finished
} // Function Select (ADMIN) Finished
// Remove OTP (ADMIN)
else if (mode == 9) {
OTP_clear();
Delay_1_s ();
Delay_1_s ();
mode = 3;
lcd.clear();
} // Remove OTP (ADMIN) Finished
//Open Door (ADMIN)
else if (mode == 10) {
if (last == '*' && key_state == 2) {
mode = 0;
lcd.clear();
}
} //Open Door (ADMIN) Finished
//CoolDown Mode
else if (mode == 11) {
for (int i = 60 ; i >= 0 ; i--) {
if (i > 9)
lcd.setCursor(7, 1);
else {
lcd.setCursor(7, 1);
lcd.print(" ");
}
lcd.print(i);
//Delay_1_s ();
}
attemps = 0;
lcd.clear();
mode = 0;
}
} // END OF LOOP
// Functions
// Collect Data Function
void collectKey() {
Data[data_count] = key;
lcd.setCursor(6 + data_count, 1);
lcd.print("*");
data_count++;
} // Collect Data Function Finished
// Data Clear Function
void Data_clear() {
while (data_count != 0)
Data[data_count--] = 0;
} // Data Clear Function Finished
// OTP Clear Function
void OTP_clear() {
char OTP_temp[] = {'F', 'F', 'F', 'F'};
copy_array(OTP , OTP_temp);
} // OTP Clear Function Finished
// Delay 1 Second Function
void Delay_1_s () {
cli();
// Set Timer 1 to normal mode with a prescaler of 1024
TCCR1A = 0x00;
TCCR1B = 0x04;
// Set the initial timer count
TCNT1H = 0x0B;
TCNT1L = 0xDC;
// Wait for the timer to overflow
while ((TIFR1 & (1 << TOV1)) == 0);
// Clear the overflow flag and stop the timer
TIFR1 = (1 << TOV1);
TCCR1B = 0x00;
} // Delay 1 Second Function Finished*/
// Compare Function
boolean compare_code (char a[], char b[]) {
for (int i = 0 ; i < Code_l - 1 ; i++)
if (a[i] != b[i])
return false;
return true;
} // Compare Function Finished
// Copy Function
void copy_array (char a[], char b[]) {
for (int i = 0 ; i < Code_l - 1 ; i++)
a[i] = b[i];
} // Copy Function Finished
ISR (TIMER1_OVF_vect){
TCNT1 = 0x0BDC;
test++;
Serial.println(test);
}