Keypad door lock reset

This is the code I have been working.

#include <Keypad.h>
#include <EEPROM.h>
char* secretCode = "1234";
int position = 0;
int position2 = 0;
boolean locked = true;
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] = {2, 3, 4, 5};
byte colPins[cols] = {14, 15, 16};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

int solenoidPin = 13;
int redPin = 8;
int bluePin = 9;
int greenPin = 10;

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(6, 7, 12, 17, 18, 19);



void setup()
{

pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

pinMode(solenoidPin, OUTPUT);

lcd.begin(16, 2);
lcd.setCursor(0, 0);

loadCode(); // load the code from EEPROM

updateOutputs();
screen();

}
void loop()
{

char key = keypad.getKey();
if (key)
{
position2 ++;
digitalWrite(bluePin, HIGH);
delay(30);
digitalWrite(bluePin, LOW);
lcd.print("?");
}

if (key == '*' ) 

{
// * pressed so change code
position = 0;
position2 = 0;
getNewCode();
updateOutputs();
screen();
}



if (key == '#' )   // manual locked when push '#'
{
locked = true;
position = 0;
position2= 0;
updateOutputs();
digitalWrite(bluePin, HIGH);
delay(100);
digitalWrite(bluePin, LOW);
screen();
}

if (key == secretCode[position])
{
position ++;
}
if (position == 4 & position2 == 4)
{
locked = false;
digitalWrite(bluePin, HIGH);
delay(300);
digitalWrite(bluePin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("password correct");
lcd.setCursor(0, 1);
lcd.print("access granted");
updateOutputs();
screen();
}
}


void updateOutputs()
{
if (locked)
{
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, LOW);
}
else
{
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(solenoidPin, HIGH);

}
delay(1000);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, LOW);
locked = true;
position = 0;
position2= 0;
}



void getNewCode()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("new password?");
lcd.setCursor(6, 1);
lcd.print("");

flash();
for (int i = 0; i < 4; i++ )
{
char key;
key = keypad.getKey();
while (key == 0)
{
key = keypad.getKey();
}
flash();
secretCode[i] = key;
lcd.print(key);
}
saveCode();
flash();flash();

}


void loadCode()
{
if (EEPROM.read(0) == 7)
{
secretCode[0] = EEPROM.read(1);
secretCode[1] = EEPROM.read(2);
secretCode[2] = EEPROM.read(3);
secretCode[3] = EEPROM.read(4);
}
}

void saveCode()
{
EEPROM.write(1, secretCode[0]);
EEPROM.write(2, secretCode[1]);
EEPROM.write(3, secretCode[2]);
EEPROM.write(4, secretCode[3]);
EEPROM.write(0, 7);
}


void eraseCode() // 
{
EEPROM.write(1, 2);
EEPROM.write(2, 2);
EEPROM.write(3, 5);
EEPROM.write(4, 5);
EEPROM.write(0, 2);
}


void flash()
{
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(100);
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
delay(100);
}

void screen()
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("LOCKED");
lcd.setCursor(0, 1);
delay(100);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("enter password");
lcd.setCursor(0, 1);
}

It works great but if you enter wrong 4 digit password it doesn’t automatically reset position.You need to press “#” to reset and re-enter the 4 digit password.

I modded that as this:

if (key == secretCode[position])
{
  {
position ++;
}
if (position == 4 & position2 == 4)
{
locked = false;
digitalWrite(bluePin, HIGH);
delay(300);
digitalWrite(bluePin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("password correct");
lcd.setCursor(0, 1);
lcd.print("access granted");
updateOutputs();
screen();
}
else
{
locked = true;
position = 0;
position2= 0;
updateOutputs();
digitalWrite(bluePin, HIGH);
delay(300);
digitalWrite(bluePin, LOW);
screen();
}
  
}
}

But it doesn’t work for this case.What am I doing wrong?

Just looking at the code for a few seconds I have to ask:
Do you mean?
if (position == 4 & position2 == 4)
Or do you mean?
if (position == 4 && position2 == 4)

I tried both alternatives for the source code.It doesn't matter.It works great for both.But I couldn't reset it for per 4 characters key enterance.

By the way thanks for your reply. :wink:

Maybe this will help you. I don’t expect you to have the libraries that are used in this sketch, its is merely just an example.

/* 
 || @version 1.0
 || @author Andrew Mascolo
 ||
 || @description
 || Simple use of keypad, password and LCD
 */
#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define Password_Lenght 7 // Give enough room for six chars + NULL char

LiquidCrystal_I2C lcd(0x20,20,4);
char Data[Password_Lenght]; // 6 is the number of chars it can hold + the null char = 7
char Master[Password_Lenght] = "123456"; 
byte data_count = 0, master_count = 0;
boolean good;
char customKey;

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] = {
  2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  10,9,8}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad 

void setup(){
  lcd.init();// initialize the lcd 
  lcd.backlight();
}

void loop()
{
  lcd.setCursor(0,0);
  lcd.print("Enter Password");
  
  customKey = customKeypad.getKey();
  if (customKey) // makes sure a key is actually pressed, equal to (customKey != NO_KEY)
  {
    Data[data_count] = customKey; // store char into data array
    lcd.setCursor(data_count,1); // move cursor to show each new char
    lcd.print(Data[data_count]); // print char at said cursor
    data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
  }

  if(data_count == Password_Lenght-1) // if the array index is equal to the number of expected chars, compare data to master
  {
    if(!strcmp(Data, Master)) // equal to (strcmp(Data, Master) == 0)
      good = true;
    else 
      good = false;  

    lcd.setCursor(0,0);
    delay(1000); // added 1 second delay to make the password completely show on screen before it gets cleared.
    if(good) // equal to (good == true)
    {
      lcd.clear(); //clear the screen for new message
      lcd.print("Password is good");
      delay(1000);
      lcd.clear(); // clear the screen for next use
      clearData(); // reset the array holding the user password
    }
    else 
    {
      lcd.clear(); // same as above
      lcd.print("Password is bad");
      delay(1000);
      lcd.clear(); // same as above
      clearData(); // same as above
    }
  }
}

void clearData()
{
  while(data_count !=0)
  {   // This can be used for any array size, 
    Data[data_count--] = 0; //clear array for new data
  }
  return;
}

LarryD:
Just looking at the code for a few seconds I have to ask:
Do you mean?
if (position == 4 & position2 == 4)
Or do you mean?
if (position == 4 && position2 == 4)

Either way produces the same results.

now to the problem OP has, you should first buffer all 4 digits and then compare them to password all 4 digits at once and decide whether to unlock. In either way you reset input. What you are doing is aweful, I’m sorry. There is problem everywhere, such as how you handle variables, sometimes in loops and sometimes in functions. Google some examples. Well, qhile I was typing on this stupid tablet, Hazardmind got you code.

Hazardsmind’s code sample is great.I have modified it and it is working as I expect.Here is the working one:

#include <Keypad.h>
#include <Wire.h> 
#include <EEPROM.h>


#define Password_Lenght 5 // Give enough room for six chars + NULL char

char Data[Password_Lenght]; // 4 is the number of chars it can hold + the null char = 5
char Master[Password_Lenght] = "1234"; 

byte data_count = 0, master_count = 0;
boolean good;

char customKey;

const byte ROWS = 4;
const byte COLS = 3;
char customKeys[ROWS][COLS] = {
  {
    '1','2','3'    }
  ,
  {
    '4','5','6'    }
  ,
  {
    '7','8','9'    }
  ,
  {
    '*','0','#'    }
};



byte rowPins[ROWS] = {
  2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  14,15,16}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(customKeys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad 






void setup(){
  pinMode(13,OUTPUT);
  pinMode(8,OUTPUT);

  digitalWrite(13,LOW);
  Serial.begin(9600);
  loadCode();
}



void loop()
{
  customKey = customKeypad.getKey();
  if (customKey != NO_KEY){
    delay(60); 
    digitalWrite(13,HIGH);
    delay(10);
    digitalWrite(13,LOW);
    switch (customKey){
    case '#': 
      changePassword();
      break;
    case '*': 
      resetPassword(); 
      break;
    default: 
      processNumberKey(customKey);
    }
  }
}


void resetPassword()
{

  Serial.println("PRESSED *     RESET");
  digitalWrite(13,HIGH);
  delay(1500);
  digitalWrite(13,LOW);
  clearData(); // same as above

}
void processNumberKey(char customKey)  
{ 

  {
    Serial.println(customKey);
    Data[data_count] = customKey; // store char into data array
    data_count++; // increment data array by 1 to store new char, also keep track of the number of chars entered
  }


  if(data_count == Password_Lenght-1) // if the array index is equal to the number of expected chars, compare data to master
  {
    if(!strcmp(Data, Master)) // equal to (strcmp(Data, Master) == 0)
      good = true;
    else 
      good = false;  

    if(good) // equal to (good == true)
    {
      Serial.println("Password is good");
      digitalWrite(13,HIGH);
      delay(1500);
      digitalWrite(13,LOW);
      clearData(); // same as above


    }
    else

        Serial.println("Password is bad");
    clearData(); // same as above
  }
}


void clearData()
{
  while(data_count !=0)
  {   // This can be used for any array size, 
    Data[data_count--] = 0; //clear array for new data
  }
  return;
}



void changePassword()
{
  Serial.println("Change password");
  digitalWrite(13,HIGH);
  for (int i = 0; i < 4; i++ )
  {
    char customKey;
    customKey = customKeypad.getKey();
    while (customKey == 0)
    {
      customKey = customKeypad.getKey();

    }
    digitalWrite(8,HIGH);
    delay(30);
    digitalWrite(8,LOW);

    Master[i] = customKey;
  }
  saveCode();
}



void saveCode()
{
  EEPROM.write(1, Master[0]);
  EEPROM.write(2, Master[1]);
  EEPROM.write(3, Master[2]);
  EEPROM.write(4, Master[3]);
  EEPROM.write(0, 1); 
  digitalWrite(13,LOW); 
}
void loadCode()
{
  if (EEPROM.read(0) == 1)
  {
    Master[0] = EEPROM.read(1);
    Master[1] = EEPROM.read(2);
    Master[2] = EEPROM.read(3);
    Master[3] = EEPROM.read(4);
  }
}

Thanks for all. :wink:

It’s nice to once in a while read others’ code. Gives you different perspective, right?

You are right.It can also solve the point that you have stuck,and save you time.So in my opinion it is very important to paste the working code at the end of the topic if the problem is solved.