0

I am working on a keypad password lock system based on arduino UNO. I have used the password library from Arduino's website.

What I am trying to accomplish is to set two passwords, namely pass1 and pass 2.

The condition is that this circuit is attached to a gate, if user 1 lets say knows pass1, after entering the pass the gate will unlock for 10 seconds and the pass1 becomes invalid i.e. can not be used in future. However if user 2 comes and knows pass2, after entering the pass2, the gate will open for 10 seconds and then pass2 becomes invalid; so each password can be used only once. I am attaching the code I already have below.

The problem with this code is that when pass1 is executed, the system does not take pass2 until unless the system is reset.

Kindly tell me a solution to fix this.

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

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
Password password1 = Password("1234");
Password password2 = Password("4567");
int ledpin = A5;
int a = 0;
const byte ROWS = 4; // Four rows
const byte COLS = 4; // columns

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

byte rowPins[ROWS] = {A0, A1, A2, A3};
byte colPins[COLS] = { 8,  9, 10, 11};

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


void setup() {
    lcd.begin(16, 2);
    keypad.addEventListener(keypadEvent); //add an event listener for this keypad
}

void loop() {
    keypad.getKey();
}

void keypadEvent(KeypadEvent eKey) {
    switch (keypad.getState()) {
        case PRESSED:
            lcd.println(eKey);
            switch (eKey) {
                case '*':
                    checkPassword();
                    break;
                case '#':
                    password1.reset();
                    password2.reset();
                    break;
                default:
                    password1.append(eKey);
                    password2.append(eKey);
            }
            return;
    }
}

void checkPassword() {
    if (password1.evaluate()) {
        lcd.setCursor(0, 1);
        lcd.println("code1 OK");
        delay(2000);
        digitalWrite(ledpin, HIGH);
        delay(10000);
        digitalWrite(ledpin, LOW);
        password1.append('1');
        lcd.clear();
        return;
    } else if (password2.evaluate()) {
        lcd.setCursor(0, 1);
        lcd.println("code2 OK");
        delay (2000);
        digitalWrite(ledpin, HIGH);
        delay(10000);
        digitalWrite(ledpin, LOW);
        password2.append('2');
        lcd.clear();
        return;
    } else {
        lcd.setCursor(0, 1);
        lcd.println("Wrong");
        delay(2000);
        lcd.clear();
        lcd.print("Wait for 5 Sec");
        delay(5000);
        lcd.clear();
        return;
    }
    return;
}

Regards Fawad

  • Password 2 contains password 1 while it's being typed. You need to empty out Password 2 when password 1 is accepted and vice versa. – Majenko Jun 16 '15 at 8:46
  • As a matter of courtesy for those who read your question, you should at least try to properly indent your code, as this makes it easier to read. I've done it for you now, but please do it yourself in the future. – Edgar Bonet Jun 16 '15 at 9:30
2

You are never really invalidating the passwords. The statement

password1.append('1');

adds '1' to the guess, it does not change the password itself. If you really want to invalidate the password, you should change it to something that cannot be typed on the keypad. For example

password1.set("X");  // untypable password

Whether or not you do invalidate the previously used passwords, you should reset the guesses once a password has been checked. This can be done in checkPassword(), or in keypadEvent() as follows:

switch (eKey) {
    case '*':
        checkPassword();
        password1.reset();
        password2.reset();
        break;
    ...
}

BTW, all your return statements are useless, and the first switch/case in keypadEvent can be replaced by

    if (keypad.getState() == PRESSED)

which would be easier to read.

  • Thanks Edgar, I am sorry for the indent part as you can tell I am very new to the community. I will try these changes, and will get back to you!! Could you kindly elaborate the change in the indent code at the very last. Regards Fawad – Fawad Jun 16 '15 at 16:38
  • @Fawad: Statements that are at the same logical level should be lined up. There are various common indent styles. They are all OK as long as you pick one and use it consistently. – Edgar Bonet Jun 16 '15 at 17:14
  • I tried your suggestion to reset password in the case loop but it only resets it thus eliminating the main requirenment of one use per password... – Fawad Jun 18 '15 at 4:04
  • @Fawad: This requirement is not fulfilled in your current code: typing '#' allows to reuse passwords. The reset() I suggested has nothing to do with this requirement either: it's meant to allow the use of the other password, and to give a second chance if you mistype the password. If you want to enforce single-use, issue passwordN.set("X"); once password N has been accepted, as I already mentioned in the answer. – Edgar Bonet Jun 18 '15 at 5:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.