// Program written by Dan Hostler, August 2020.
// Feel free to use as you need to.
// PayPal donations appreciated at [email protected]
// LIBRARIES. (PLEASE INSTALL THESE LIBRARIES IF YOU HAVE NOT YET)
#include <Wire.h> // deals with I2C connections
#include <LiquidCrystal_I2C.h> // activates the LCD I2C library
#include <Keypad.h> // activates the Keypad library
// VARIABLES FOR THE 8-NUMBER PASSWORD INPUT DATA
#define Password_Length 9 // Amount of digits plus one null character (8 + 1 = 9) defines password length
char userInput[Password_Length]; // This variable will store the user input in a string
char Master[Password_Length] = "12345678"; // This variable holds the correct password that the user string must match, change as needed
char customKey; // This variable holds key input of every key pressed
byte pressCount = 0; // This variable holds a counter for the amount of times the keys were pressed
// KEYPAD CONFIGURATION (PLEASE MODIFY THIS SECTION IF YOUR KEYPAD WIRING IS DIFFERENT FROM BELOW)
const byte ROWS = 4; // Constants for row and
const byte COLS = 3; // column size of your keypad.
char twelveKeys[ROWS][COLS] = // Physical layout of the keypad being used in this program
{
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'C', '0', 'E'} // C = CLEAR, E = ENTER
};
byte rowPins[ROWS] = {9, 8, 7, 6}; // Defines how rowPins are connected on the Arduino to the keypad: 9 = R1, 8 = R2, 7 = R3, 6 = R4
byte colPins[COLS] = {5, 4, 3}; // Defines how colPins are connected on the Arduino to the keypad: 5 = C1, 4 = C2, 3 = C3, 2 = C2 (if you have a 4x4 keypad)
// OBJECT CONFIGURATIONS
Keypad customKeypad = Keypad(makeKeymap(twelveKeys), rowPins, colPins, ROWS, COLS); // Creates keypad "object"
LiquidCrystal_I2C lcd(0x27, 16, 2); // Creates LCD "object" (I2C address, rows, columns)
// PROGRAM SETUP
void setup() {
// LCD Initialization
lcd.backlight();
lcd.init();
lcd.clear();
}
// MAIN PROGRAM LOOP
void loop() {
lcd.setCursor(0,0);
lcd.print(" Type Password:"); // One space is offset to center the text on the LCD
customKey = customKeypad.waitForKey(); // Program will halt here until a key is pushed
if (customKey != NO_KEY && customKey != 'C' && customKey != 'E') // If the user presses the number keys, the data is entered
{
userInput[pressCount] = customKey; // Password string is being collected by the userInput variable
lcd.setCursor(pressCount + 4, 1); // Four is added to pressCount to center the input on the LCD
lcd.print("*"); // Asterisks are printed for confidentiality
pressCount++; // Key press count will roll over until 8 digits are entered
}
else if (customKey == 'C') // C is to clear the entire password input from any point and start over again as
{ // it calls up the clearData function.
lcd.clear();
clearData();
}
else if (customKey == 'E') // If less than 8 digits are entered, the input will be invalid and
{ // an error message will flash, then call the clearData function to
lcd.clear(); // start the entering process all over again.
lcd.setCursor(0,0);
lcd.print("INVALID ENTRY");
delay(800);
clearData();
}
if (pressCount == 8) // Once 8 digits are entered, the function to check the password string is called up and
{ // both the character and string data are sent to the function.
lcd.clear();
waitHere();
}
}
// THIS FUNCTION CHECKS THE PASSWORD STRING
void waitHere(){
lcd.setCursor(0,0);
lcd.print(" Type Password:");
lcd.setCursor(0,1);
lcd.print(" ********"); // Password data is hidden as asterisks for confidentiality purposes and
// is offset by 4 spaces to center the input on the LCD
customKey = customKeypad.waitForKey(); // Program will halt here until a key is pushed
if (customKey != NO_KEY && customKey == 'E') // The ENTER button is pushed and the password goes through the routine.
{
lcd.clear();
lcd.setCursor(0,0);
if (!strcmp(userInput, Master)) // The user input string is matched up with the Master password string and matches up
{ // running the routine to grant access before returning back to the beginning.
lcd.setCursor(0,0);
lcd.print("ACCESS GRANTED.");
lcd.setCursor(0,1);
lcd.print("WELCOME!!");
delay(5000);
clearData();
}
else if (strcmp(userInput, Master)) // The user input string is matched up with the Master password string and does not match up
{ // running the routine to deny access before returning back to the beginning.
lcd.setCursor(0,0);
lcd.print("ACCESS DENIED.");
delay(2000);
clearData();
}
}
if (customKey != NO_KEY && customKey == 'C') // If the CLEAR button is pushed, the data is cleared and the program starts over.
{
lcd.clear();
clearData();
}
if (customKey != NO_KEY && customKey == '0') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '1') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '2') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '3') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '4') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '5') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '6') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '7') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '8') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
if (customKey != NO_KEY && customKey == '9') // This numberical button has no purpose and does nothing when pressed.
{
waitHere();
}
}
// OPTIONAL FUNCTIONS TO USE IN CASE YOU WISH TO EXPAND OUT YOUR PROGRAM
//void accessGranted(){
//
//}
//
//void accessDenied(){
//
//}
// CLEARS THE ARRAY DATA, STARTS PROGRAM ALL OVER AGAIN
void clearData() {
while (pressCount != 0)
{
userInput[pressCount--] = 0; // Clears out the user input data, both digit and string data are reset to zero.
}
setup(); // Returns program back to the beginning
}