Keypad isnt working

I have this one project witch is too long to explain so in the most simple way possible:

this project uses a LCD and a LED (also a EEPROM but later after I figure out what's wrong)

When I turn on the arduino:

(LCD)
Enter Passcode:
**
if passcode incorrect go back and try again, if passcode correct:

Press A to start (LED is a replacement for a relay cause I dont have a transistor and a relay laying around plus its just a demo)

When A is pressed:
LED Turn on and LCD says "Press B to stop"

Only after passcode is entered and on the press A to start screen (this is where EEPROM comes in later)
If i press * it will bring me into passcode reset screen and confirm passcode screen which explanation is in the code.

Here is my code:

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

bool passcodeEntered = false;
bool asteriskPressed = false;

const int LED = 2;
const int rs = A0, en = A1, d4 = A2, d5 = A3, d6 = A4, d7 = A5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

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] = { 8, 7, 6, 5 };
byte colPins[COLS] = { 12, 11, 10, 9 };

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

const unsigned long PASSCODE_TIMEOUT = 15000;  // 15 seconds
const String DEFAULT_PASSCODE = "1501";
String passcode = "";

enum State {
  ENTER_PASSCODE,
  PRESS_A_TO_START,
  LED_ON,
  PASSCODE_CHANGE,
  ENTER_NEW_PASSCODE,
  CONFIRM_NEW_PASSCODE
};

State currentState = ENTER_PASSCODE;
unsigned long passcodeTimer;
bool passcodeChangeRequested = false;
int passcodeLength = 0;  // Variable to keep track of the number of characters entered during passcode reset

void setup() {
  pinMode(LED, OUTPUT);
  lcd.begin(16, 2);
  lcd.print("Enter Passcode:");
  Serial.begin(9600);
}


void loop() {

  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.print("Key pressed: ");
    Serial.println(key);
    switch (currentState) {
      case ENTER_PASSCODE:
        handlePasscodeInput(key);
        break;

      case PRESS_A_TO_START:
        if (key == 'A') {
          lcd.clear();
          lcd.print("Press B to Stop");
          digitalWrite(LED, HIGH);  // Turn on the LED
        } else if (key == 'B') {
          currentState = ENTER_PASSCODE;
          passcodeEntered = false;
          lcd.clear();
          lcd.print("Enter Passcode:");
          lcd.setCursor(0, 1);
          passcode = "";

          digitalWrite(LED, LOW);  // Turn off the LED
        }
        break;

      case ENTER_NEW_PASSCODE:
        if (key == '#') {
          currentState = CONFIRM_NEW_PASSCODE;
          passcodeTimer = millis();
          lcd.clear();
          lcd.print("Confirm Pass:");
        } else if (key == 'B') {
          currentState = ENTER_PASSCODE;
          passcode = "";
          passcodeChangeRequested = false;
          passcodeLength = 0;  // Reset the passcode length
          lcd.clear();
          lcd.print("Enter Passcode:");
        }
        break;

      case CONFIRM_NEW_PASSCODE:
        if (passcodeLength == passcode.length()) {  // Check if the passcode length is the same
          if (passcode.equals(DEFAULT_PASSCODE)) {
            currentState = ENTER_PASSCODE;
            lcd.clear();
            lcd.print("Passcode set");
            delay(2000);
            lcd.clear();
            lcd.print("Enter Passcode:");
            passcode = "";
            passcodeLength = 0;  // Reset the passcode length
          } else {
            lcd.clear();
            lcd.print("Passcodes don't");
            lcd.setCursor(0, 1);
            lcd.print("match. Try again.");
            delay(2000);
            lcd.clear();
            lcd.print("Enter New Pass:");
            passcode = "";
            passcodeLength = 0;  // Reset the passcode length
          }
        } else if (millis() - passcodeTimer >= PASSCODE_TIMEOUT) {
          currentState = ENTER_PASSCODE;
          lcd.clear();
          lcd.print("Timeout");
          delay(2000);
          lcd.clear();
          lcd.print("Enter Passcode:");
          passcode = "";
          passcodeLength = 0;  // Reset the passcode length
        }
        break;
    }
  }
}

void handlePasscodeInput(char key) {
  if (key == '#') {
    if (passcode.equals(DEFAULT_PASSCODE) && !passcodeChangeRequested) {
      currentState = PRESS_A_TO_START;
      lcd.clear();
      lcd.print("Press A to start");
      passcodeEntered = true;  // Set passcodeEntered to true when the correct passcode is entered
      lcd.setCursor(0, 1);
      lcd.print("PE");  // Display "PE" on the LCD
    } else {
      lcd.clear();
      lcd.print("Incorrect Password");
      lcd.setCursor(0, 1);
      lcd.print("Please Try again");
      delay(2000);
      lcd.clear();
      lcd.print("Enter Passcode:");
      lcd.setCursor(0, 1);
      passcode = "";
      passcodeEntered = false;  // Set passcodeEntered to false when an incorrect passcode is entered
    }
  } else if (key == 'A') {
    if (currentState == PRESS_A_TO_START && passcodeEntered) {
      // Proceed to the passcode reset screen
      currentState = PASSCODE_CHANGE;
      lcd.clear();
      lcd.print("Reset Passcode");
      delay(2000);
      lcd.clear();
      lcd.print("Enter New Pass:");
      passcode = "";
      passcodeLength = 0;  // Reset the passcode length
    } else {
      lcd.clear();
      lcd.print("Invalid Key");
    }
  } else if (key == 'B') {
    currentState = ENTER_PASSCODE;
    passcodeEntered = false;
    lcd.clear();
    lcd.print("Enter Passcode:");
    lcd.setCursor(0, 1);
    passcode = "";
    digitalWrite(LED, LOW);  // Turn off the LED
  } else if (key != NO_KEY) {
    lcd.setCursor(0, 1);
    lcd.print(key);  // Display the pressed key on the LCD
    if (passcode.length() < DEFAULT_PASSCODE.length()) {
      passcode += key;
      lcd.setCursor(passcode.length() - 1, 1);
      lcd.print("*");
    }
  }
}

Note: asteriskPressed is because when I was focusing on setting up the part of the code where I wanted to make it so when I hold the * key for 5 seconds it should display a asterisks on the lcd for 5 seconds indicating that asterisks pressed is true and I press # to get into the passcode reset screen so just ignore it cause I aint using it right now.

Now for some context, I have a Geni lift and it doesn't have security at all like I undo the emergency button and press the power on button and the thing just turns on. If you dont know a Geni lift can move around so a thief can just drive away. I have everything built Infront of me (so no simulation) and there will be things changing like pressing the * button to change the passcode and adding EEPROM and I will do those later. For now I want to debug why I cant seem to get into the passcode changed menu and I want to test it. The main issue: My keypad works until I get into the Press A to start state. It seems to me that the only 2 keys that do work is A and B nothing else. The keypad does work at the beginning of the whole thing when it asks for a passcode. I removed it but the way I found out was Serial.println(key); and i did that on my lcd too in the handlePasscodeInput function.

Thanks a lot for reading this.

Have you written a simple sketch to test the keypad functionality? Press a key, print it. Do you get the expected results for every key?

Looks like perfectly suited for analysing in a WOKWI-simulation
I took the wiring of the demo-caclulator as template
and
added my debug-macros
anything else is as in your code

best regards Stefan

Thanks for the reply, I took a look at this simulator and looks like I get the same issue and I am in the process of debugging it, thanks!

What I did was on a separate Arduino sketch I made it so it prints the keys I press and from the looks of it all the keys work on the key pad. I dont get the expected results when its telling me to press A to start but before that when it asks me for my passcode it seems to work,

@rclare15

I have tested your sketch of post #1 in UNO; unfortunately, it does not respond in a logical manner.

Please, list all the tasks that your program is expected to carry out.

The following algorithm turns on LED when the entered Passcode matches with "1501".

1. Upload the following sketch in UNO.

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

bool flag = false;
char passCode[5] = {0};
int index = 0;
const int LED = 13;

const int rs = A0, en = A1, d4 = A2, d5 = A3, d6 = A4, d7 = A5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
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] = { 8, 7, 6, 5 };
byte colPins[COLS] = { 12, 11, 10, 9 };

Keypad keypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
const char DEFAULT_PASSCODE[] = "1501";

void setup()
{
  pinMode(LED, OUTPUT);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);  //displayPos, linePos
  lcd.print("Enter Passcode:");
  Serial.begin(9600);
}

void loop()
{
  char key = keypad.getKey();
  if (key != NO_KEY)
  {
    if (flag == false)
    {
      lcd.setCursor(0, 0);//disPos, linePos
      lcd.clear();
      lcd.print("Key Pressed: ");
      lcd.setCursor(0, 1);
      lcd.print(key);
      passCode[index] = key;
      index++;
      flag = true;
    }
    else
    {
      lcd.print(key);
      passCode[index] = key;
      index++;
      if (index == 4)  //4-digit Passcode has been entered
      {
        passCode[index] = '\0'; //insert Null-charcater
        if (strcmp(passCode, DEFAULT_PASSCODE) == 0) //Passcode matches
        {
          digitalWrite(LED, HIGH);
          index = 0;
          flag = false;
        }
        else  //clear/reset the display
        {
          lcd.clear();
          index = 0;
          flag = false;
          lcd.setCursor(0, 0);
          lcd.print("Enter Passcode: ");
        }
      }
    }
  }
}

2. Press RESET button of UNO.
LCD shows on Top Line: Enter Passcode:

3. Press 1 from Keypad.
LCD shows on Top Line: Key Pressed:
LCD shows on Bot Line: 1

4. Press 5 0 1 from Keypad.
LCD shows on Bot Line: 1501
LED at DPin-2 becomes ON.

5. You may use the sketch of Section-1 as a "Building Block" and add simple codes with this one for your other tasks one at a time. You may use "Flow Chart" approach or "FSM" approach create codes for your sketch.

6. Note that it is not recommended to use String data type/class for AVR MCU.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.