UPDATE:
I added a hang timer of 5 seconds, but you can change the time if needed. I added more comments to try and explain what is occurring, and don't be alarmed about the method for getting the numbers, I explained what is happening. Also I got rid and commented out a few things you added.
#include <Keypad.h> //Includes keypad library
#include <EEPROM.h> //Includes EEPROM library
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {8, 7, 6};
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); //Creates the keypad
const int number_of_passwords = 4, length_of_password = 4;
char key[4];
int address = 0, street = 0, user = 1, num = 0;
unsigned long current_time = 0, time = 0, hang_time = 5000;
boolean timeout = false;
char myKey;
char datatest[number_of_passwords][length_of_password]={
{ '1','2','2','1' },
{ '1','2','2','3' },
{ '1','1','1','1' },
{ '9','9','9','9' }
};
#define ledPin 9
#define AlarmWrong 10
//int i = 0; //variable to count number of key pressed
void setup(){
Serial.begin(9600);
pinMode(ledPin, OUTPUT); //set the alarm open pin
pinMode(AlarmWrong, OUTPUT);
for(street = 0; street < number_of_passwords * length_of_password; street += 4)
{
for( address =0; address < length_of_password; address++)
{
EEPROM.write(address + street, datatest[street/4][address]);
}
}
address = 0; // clear address
street = 0; // clear street
}
void loop(){
timeout = false;
while(num != 4) // get four numbers
{
myKey = kpd.getKey(); // Check the first keypress
if(myKey){ // This will check to see if a key was pressed
current_time = millis(); // and if so, this will also store the current time.
key[num] = myKey; // This will add the keypress to the array
Serial.print(key[num]);
num++; // This will increment the array for the next keys
while(time < hang_time){ // This will allow the program to get the rest of the
time = millis() - current_time;// of the numbers within the time limit of 5 seconds
myKey = kpd.getKey(); // Check keypress again
if(myKey){
key[num] = myKey;
myKey = 0; // The key must be set to zero, otherwise the code will not work correctly
Serial.print(key[num]);
num++;
}
if(num == 4)
{
time = 0; // reset variable "time" for timer to start over
break;
}
}
if(time >= 5000) // If hang time has reached 5 seconds, display timeout message
{
Serial.println(" Timed out");
// ADD ALARMWRONG HERE
cleardata(); // Clear everything
timeout = true; // Even though timeout was set false in cleardata(), this is needed so that the last good password will not display.
time = 0;
break;
}
}
}
while(street != number_of_passwords * length_of_password) // while street does not exceed maximum number
{
if(key[address] == EEPROM.read(address + street) ) // look through the EEPROM and see if the serial/keypad data matches what was stored.
{
address++; // if the first number matches, get the next.
//WHY IS THIS NEEDED, bolded so it stands out?
// digitalWrite(ledPin, HIGH);
// delay(1000);
// digitalWrite(ledPin, LOW);
}
else // no match was found, try next password
{
address = 0; // set address back to zero and start over
user++; // keep track of users
if(street != (number_of_passwords * length_of_password) ) street+=4; // switch memory location
}
if(address == 4 && !timeout){ // if address equals 4, password was found for said user
Serial.print(" User ");
Serial.println(user);
correctpassword();
cleardata();
break;
}
}
if(street == (number_of_passwords * length_of_password) ) // if street reached max number of passwords, Alarm password is wrong.
{
Serial.println(" Password not found");
digitalWrite(AlarmWrong, HIGH);
delay(500);
digitalWrite(AlarmWrong, LOW);
cleardata(); // clear variables
}
}
void cleardata()
{
timeout = false;
address = 0;
street = 0;
user = 1;
num = 0;
return;
}
void correctpassword()
{
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(500);
cleardata(); //clears the input array
}