Keypad gets stuck! Help

Hello, I am trying to make a code, I have a keypad and an lcd, first you need to give the factory reset key ('123'), if it's matching then set a new key, the problem is that when I try to give the new key (also of 3 digits) , the last '3' counts as the first digit of the new password or sometimes the first and second.

How can I make it so that the last press of 3 will not be taken accounted as the first digit in the new key I want to give.

#include <Servo.h>
#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal.h>

Servo servo1;
//rs, en, d4, d5, d6, d7
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //pins in the arduino

const int ledOpen = A9;
const int ledClosed = A8;
int pos = 0;
int openDoor = false;
int i = 0;
int j = 0;
long givenKey[3];
int cont = 0;
long factoryPass[3] = {1,2,3};
long newPass[3];
int k = 0;
int key1 = false;
int key2= false;
int key3 = false;
int check = false;

const byte ROWS = 4; 
const byte COLS = 4; 

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {13, 12, 11, 10};   //row pins in the arduino 
byte colPins[COLS] = {9, 8, 7, 6}; //col pins in the arduino


Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 


void setup() {
  servo1.attach(5);   //attach to pin 5
  lcd.begin(20,4);  // initialize lcd 20 x 4
  
  Serial.begin(9600);
}

void loop() {
  //while (cont == 1){
  //factory reset pass = 123
  char customKey = customKeypad.getKey(); //keypad key
  lcd.setCursor(0,0); // cursor column 0, line 0
  lcd.print("Enter Reset Key: ");
  

 if ( i <= 2){ //if there are 3 digits press
   if (customKey){
     givenKey[i] = customKey - '0'; //converts key press (char) to int
     lcd.setCursor(i,1); //writes down password in new column
     lcd.print(customKey); 
     i++;
   }
 }

delay(100);
   if(givenKey[j] == factoryPass[j]){ //if key1 is the same as the factory key1
      if(givenKey[j+1] == factoryPass[j+1]){  //if key2 is the same as the factory key2
        if(givenKey[j+2] == factoryPass[j+2]){  //if key3 is the same as the factory key3
          lcd.setCursor(0,1);
          lcd.print("Enter New Key: "); //if the 3 keys matched, give new password
             if ( k <= 2){
               if (customKey){
                  newPass[k] = customKey - '0'; //converts key press (char) to int
                  Serial.println(customKey);
                  Serial.print(",");
                  Serial.println(newPass[k]);
                  lcd.setCursor(k,2);
                  lcd.print(customKey);
                  k++;  
                }
                 if (k == 2){
                    lcd.clear();
                    lcd.setCursor(0,0);
                    lcd.print("Door Locked");                 
                  }
              }
              
        //}
        
        //else{
        //int key3 = false;
        //check = true;
        }
      }
      
      else{
        //int key2 = false;
        //check = true;
      }
    }
    
    //else{
      //int key1 = false;
      //check = true;
    //}
  }
 // if(check == true){
   // delay(100);
    //if( key1 == false or key2==false or key3 == false){
      //lcd.print("Wrong Password");
    //}
  //}
//}
//}

 /*
servo1.write(pos);
 
  int pass = false;
  
  if( pass = true) {
    for (pos = 0; pos <= 90; pos += 10) {  // servo opens door
      servo1.write(pos);
      delay(15);
      }
    }
  
  

  // Escribimos el número de segundos trascurridos
  //lcd.print(millis()/1000);
 // lcd.print(" segundos");

*/

i j k

What a bad variable names :scream:


Where do you ever reset variable

i


int openDoor = false;

Then make this a boolean

boolean openDoor = false;


Don't you think you need to get the new key press ?

if (customKey)
{
    newPass[k] = customKey - '0'; //converts key press (char) to int

hehe yes thankyou, I changed the names,
I am getting the new key press with if (customKey)
{}, but because it happens almost instantly I also get the old keypress as a new one, I tried adding delays but it doesn't work.

I don't reset i because since it's all in a loop and I have if( i <=2), then if i reset it outside the if's they will go on forever.

Please tell us what is supposed to happen ?

Example:

  • if the user enters the factory password the door unlocks.

etc.

if user enters the factory password then it gives the user access to change the factory password to a new one.
I am trying to change the new one, it does work if they give the correct factory pass '123', it asks for a new key but the first and sometimes second digit get stuck with the '3' of the '123'. The press of the factory 3 in the factory key counts in the new key and I don't know how to not have the code do that.
After the user gives correctly the new password the door locks.

Here is an old sketch with some of your stuff added.

You might get some ideas from this offering:

#include <Keypad.h>
#include <Wire.h>
#include <Servo.h>
Servo servo1;

//********************************************************************************
//#define serialLCDisBeingUsed  //uncomment if you have a serial LCD          <-----<<<<<

//********************************************************************************
#ifdef  serialLCDisBeingUsed
#include <Wire.h>

//Use I2C library:     https://github.com/duinoWitchery/hd44780
//LCD Reference:       https://www.arduino.cc/en/Reference/LiquidCrystal

#include <hd44780.h>   //main hd44780 header

//NOTE:
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)

#include <hd44780ioClass/hd44780_I2Cexp.h> //I2C expander i/o class header

//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
//OR
//Run: I2CexpDiag.ino
//C:\Users\YourName\Documents\Arduino1.69\libraries\hd44780\examples\ioClass\hd44780_I2Cexp\I2CexpDiag

//LCD I2C address
//hd44780_I2Cexp lcd(0x3F);
hd44780_I2Cexp lcd(0x27);

//********************************************************************************

#else

#include <LiquidCrystal.h>

// LCD pin         4   6  11  12  13  14
//                RS  EN  D4  D5  D6  D7
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

#endif

//********************************************************************************

#define ResetTimer  millis()

int passCode      = 123;
int newPassCode;

//states in our machine
//use names that mean something to you
enum StateMachine {Startup, StateOne, StateTwo, StateThree, StateFour, StateFive, StateSix};
StateMachine mState = Startup;

//timing stuff
unsigned long commonMillis;

//*********************************
const byte ROWS      = 4;
const byte COLS      = 4;

char hexaKeys[ROWS][COLS] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

//                        1   2   3   4
byte rowPins[ROWS]    = {13, 12, 11, 10};   //row pins in the Arduino
byte colPins[COLS]    = {9, 8, 7, 6};       //col pins in the Arduino


Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


//********************************************^************************************************
void setup()
{
  Serial.begin(9600);

  servo1.attach(5);   //attach to pin 5

  lcd.clear();
  lcd.begin(20, 4);   //initialize lcd 20 x 4

} //END of   setup()


//********************************************^************************************************
void loop()
{
  checkStateMachine();

} //END of   loop()


//********************************************^************************************************
void checkStateMachine()
{
  switch (mState)
  {
    //**********************
    case Startup:
      {
        newPassCode = 0;

        lcd.clear();
        lcd.setCursor(0, 0);
        //         01234567891111111111
        //                   0123456789
        lcd.print("Enter Pass Code     ");

        lcd.setCursor(0, 1);
        //         01234567891111111111
        //                   0123456789
        lcd.print("Press # When Done   ");

        mState = StateOne;
      }
      break;

    //**********************
    case StateOne:
      {
        char customKey = customKeypad.getKey();

        //was there a key pressed ?
        if (customKey != 0)
        {
          //was the terminator pressed ?
          if (customKey == '#')
          {
            mState = StateTwo;

            break;
          }

          newPassCode = newPassCode * 10 + customKey - '0';

          lcd.setCursor(0, 2);
          //         01234567891111111111
          //                   0123456789
          lcd.print(newPassCode);
        }
      }
      break;

    //**********************
    case StateTwo:
      {
        //do we have a match ?
        if (newPassCode == passCode)
        {
          newPassCode = 0;

          mState = StateThree;

          break;
        }

        else
        {
          mState = Startup;
        }
      }
      break;

    //**********************
    case StateThree:
      {
        lcd.clear();
        lcd.setCursor(0, 0);
        //         01234567891111111111
        //                   0123456789
        lcd.print("  ***New Code***    ");

        lcd.setCursor(0, 1);
        //         01234567891111111111
        //                   0123456789
        lcd.print("Press # When Done   ");

        mState = StateFour;
      }
      break;


    //**********************
    case StateFour:
      {
        char customKey = customKeypad.getKey();

        //was there a key pressed ?
        if (customKey != 0)
        {

          //was the terminator pressed ?
          if (customKey == '#')
          {
            mState = StateFive;

            break;
          }

          newPassCode = newPassCode * 10 + customKey - '0';

          lcd.setCursor(0, 2);
          //         01234567891111111111
          //                   0123456789
          lcd.print("                    ");

          lcd.setCursor(0, 2);
          lcd.print(newPassCode);
        }
      }
      break;

    //**********************
    case StateFive:
      {
        //reset the pass code to the new one
        passCode = newPassCode;

        newPassCode = 0;

        //unlock the door

        lcd.clear();
        lcd.setCursor(0, 0);
        //         01234567891111111111
        //                   0123456789
        lcd.print("Door  Is  Unlocked  ");

        commonMillis = ResetTimer;

        mState = StateSix;
      }
      break;

    //**********************
    case StateSix:
      {
        //has this TIMER expired (2 seconds) ?
        if (millis() - commonMillis >= 2000ul)
        {
          mState = Startup;
        }
      }
  } //END of   switch/case

} //END of    checkStateMachine()

thankyou but this is of no help :frowning: i can't seem to fix the error I have.

Hello, I am trying to make a code where I give a factory key "123#" and it asks for a new key to give.
The problem is that when I pres 123 the 3 gets "stuck" and I se 1233 in the output, this happens when I separate my
if (customKey){
}
I noticed this because at first I had factory key "123", when I pressed those numbers it gave access to give a new key but the first number always had the "3" which is the old key press.
For this code I have tried
if (customKey =! 3){
}
but it doesn't seem to work! help!

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

LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //pins in the arduino

boolean openDoor = false;
int i = 0;
int j = 0;
long givenKey[3];
int cont = 0;
long factoryPass[4] = {1,2,3,"#"};

const byte ROWS = 4; 
const byte COLS = 4; 

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {13, 12, 11, 10};   //row pins in the arduino 
byte colPins[COLS] = {9, 8, 7, 6}; //col pins in the arduino


Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 


void setup() {
  lcd.begin(20,4);  // initialize lcd 20 x 4

  lcd.setCursor(0,0); // cursor column 0, line 0
  lcd.print("Enter Reset Key: ");
  
  Serial.begin(9600);
}

void loop() {
  //while (cont == 1){
  //factory reset pass = 123
  char customKey = customKeypad.getKey(); //keypad key

 if ( i <= 2){ //if there are 3 digits press
   if (customKey != 0){
     givenKey[i] = customKey - '0'; //converts key press (char) to int
     lcd.setCursor(i,1); //writes down password in new column
     lcd.print(customKey); 
     Serial.print(i);
     i++;
   }
 }
if (i == 3){ 
   if(customKey) {   // giving repeated keypress
    givenKey[i] = customKey; //converts key press (char) to int
    lcd.setCursor(i,1); //writes down password in new column
    lcd.print(customKey); 
    Serial.print(i);
    i++;
   }
}

duplicate post
https://forum.arduino.cc/t/keypad-gets-stuck-help/1024748/5

its my post also but I made my code differently so it can be easier to understand

@adrianate

Your two topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

The sketch offered in post #6 works fine here.

What does it not do at your end ?

When I press 123 the 3 gets "stuck" and I see 1233 in the output and I can't add the 123#

Are you experiencing this on the sketch from post #6 ?


Post #6 code here works a follows:

  • The LCD displays:

Enter Pass Code
Press # When Done

  • You enter 123 then #

The LCD displays:

***New Code***
Press # When Done

  • You then enter 456 then #

  • The LCD displays (for 2 seconds):

Door Is Unlocked


The new number 456 is now your new Pass Code.

sorry I mean't my code.
I want a solution for my problem since its a code I have to give for a homework:(

but your code does work I just tried it, thankyou :slightly_smiling_face:
why did you give all your code in another function and not in the void loop()

Compare your code to the code offered in post #6.

See if you can discover what the differences are.

It keeps things organized.

However, it could all go into loop.


Here is your sketch reworked a bit.

It should unlock the door if the factory pass code matches the entered pass code.

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

//********************************************************************************
//#define serialLCDisBeingUsed  //uncomment if you have a serial LCD          <-----<<<<<

//********************************************************************************
#ifdef  serialLCDisBeingUsed
#include <Wire.h>

//Use I2C library:     https://github.com/duinoWitchery/hd44780
//LCD Reference:       https://www.arduino.cc/en/Reference/LiquidCrystal

#include <hd44780.h>   //main hd44780 header

//NOTE:
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)

#include <hd44780ioClass/hd44780_I2Cexp.h> //I2C expander i/o class header

//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
//OR
//Run: I2CexpDiag.ino
//C:\Users\YourName\Documents\Arduino1.69\libraries\hd44780\examples\ioClass\hd44780_I2Cexp\I2CexpDiag

//LCD I2C address
//hd44780_I2Cexp lcd(0x3F);
hd44780_I2Cexp lcd(0x27);

#else
#include <LiquidCrystal.h>
// LCD pin         4   6  11  12  13  14
//                RS  EN  D4  D5  D6  D7
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5); //pins in the arduino

#endif

//********************************************************************************

boolean Flag1        = false;  //if true the correct number of digits have been entered
boolean Flag2        = false;  //if true the entered pass code matches the factory pass code

byte index           = 0;

byte givenKey[3];
byte  factoryPass[3] = {1, 2, 3};

//********************************************************************************
const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = {13, 12, 11, 10};   
byte colPins[COLS] = {9, 8, 7, 6}; 

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


//********************************************************************************
void setup()
{
  Serial.begin(9600);

  lcd.begin(20, 4); 

  lcd.clear();
  lcd.print("Enter Reset Key: ");

} //END of   setup()


//********************************************************************************
void loop()
{
  //get the key press
  char customKey = customKeypad.getKey(); 

  //assemble the received code
  if ( index <= 2)
  {
    //is this a valid number ?
    if (customKey >= '0' && customKey <= '9')
    {
      //convert to an integer
      givenKey[index] = customKey - '0';

      //display the key pressed
      lcd.setCursor(index, 1);
      lcd.print(customKey);

      //ready for the next value to be entered
      index++;

      //have all the digits been entered ?
      if (index > 2)
      {
        //get ready for the next entered code
        index = 0;

        //we are finished collecting the 3 digits, enable the Flag
        Flag1 = true;
      }
    }
  }

  //have all the digits been entered ?
  if (Flag1 == true)
  {
    //disable this Flag
    Flag1 = false;

    //compare arrays
    for (byte x = 0; x <= 2; x++)
    {
      //are these two elements the same ?
      if (givenKey[x] == factoryPass[x])
      {
        //enable the compare Flag
        Flag2 = true;
      }

      //there was no match in the numbers
      else
      {
        //disable the compare Flag
        Flag2 = false;

        lcd.clear();
        lcd.print("Enter Reset Key: ");
      }
    }
  }

  //did the 2 arrays compare ?
  if (Flag2 == true)
  {
    //disable this Flag
    Flag2 = false;

    //code to unlock the door goes here

    lcd.clear();
    lcd.setCursor(0, 0);
    //         01234567891111111111
    //                   0123456789
    lcd.print("The door is unlocked");

    //wait here to read the LCD
    delay(3000);

    lcd.clear();
    lcd.print("Enter Reset Key: ");
  }

} //END of   loop()