0

I am trying to make a combination lock using an Arduino, a keypad and a Servo but I have come across an obstacle.

I can't find a way to store a 4 digit value in a variable. since keypad.getKey only allows to store one digit.

After some browsing on the internet I came upon a solution for my problem on a forum but the answer didn't include a code sample, and I couldn't find anything else about in on the internet.

The answer said to either use a time limit for the user to input the number or a terminating character (which would be the better option according to them).

I would like to know more bout these terminating characters and how to implement them, or if anybody could suggest a better solution that would be much appreciated as well.

Thank you in advance,

10
  • It is the same when an AI phone operator tells you to "Enter your phone number followed by the bound key" so what is stopping you from doing that? Aug 30, 2016 at 16:27
  • I don't know how to do it. Could you recommend a site that explains it? Aug 30, 2016 at 16:33
  • It is simple. Just think about it: populate your digits container by keep calling getkey(). Each time you get a key, check it, of it is the terminating key then stop, else call getkey() again to get a new key. Aug 30, 2016 at 16:37
  • Do you want a digit array, or a single number in the range 0-9999? Aug 30, 2016 at 16:39
  • 1
    We all love Arduino and it simplicity but please don't copy paste code, make an effort to understand it.
    – vz0
    Aug 30, 2016 at 16:56

2 Answers 2

1

To store 4 digit values, the easiest and naive way to do it is probably to use an array of size 4. Assuming keypad.getKey returns an int, you could do something like this: int input[4] = {0};.
You will need a cursor variable to know into which slot of the array you need to write when the next key is pressed so you can do some kind of loop like this:

int input[4] = {0};
for (unsigned cursor = 0; cursor < 4; ++cursor) {
    input[cursor] = keypad.getKey();
}

If you want to use a terminating character (lets say your keyboard have 0-9 and A-F keys, we could say the F is the terminating key), the code changes for something like:

bool checkPassword() {
    static const int expected[4] = {4,8,6,7}; // our password
    int input[4] = {0};

    // Get the next 4 key presses
    for (unsigned cursor = 0; cursor < 4; ++cursor) {
        int key = keypad.getKey();

        // if F is pressed too early, then it fails
        if (key == 15) {
            return false;
        }

        // store the keypress value in our input array
        input[cursor] = key;
    }

    // If the key pressed here isn't F (terminating key), it fails
    if (keypad.getKey() != 15)
        return false;

    // Check if input equals expected
    for (unsigned i = 0; i < 4; ++i) {
        // If it doesn't, it fails
        if (expected[i] != input[i]) {
            return false;
        }
    }

    // If we manage to get here the password is right :)
    return true;
}

Now you can use the checkPassword function in your main function like this:

int main() {
    while (true) {
        if (checkPassword())
            //unlock the thing
    }
    return 0;
}

NB: Using a timer sounds possible too (and can be combined with the terminating character option, they are not exclusive). The way to do this is to set a timer to the duration of your choice and when it ends you reset the cursor variable to 0.

(I never programmed on arduino and don't know about its keypad library but the logic is here, its up to you now)

0

In comment OP says a single number is wanted. The typical algorithm is that for each digit entered you multiply an accumulator by 10 and add the digit entered. This assumes that the key entry is ASCII, hence subtracting '0' from it to get a digit 0..9 instead of '0'..'9'.

#define MAXVAL 9999
int value = 0;                                  // the number accumulator
int keyval;                                     // the key press
int isnum;                                      // set if a digit was entered
do {
    keyval = getkey();                          // input the key
    isnum = (keyval >= '0' && keyval <= '9');   // is it a digit?
    if(isnum) {                                 // if so...
        value = value * 10 + keyval - '0';      // accumulate the input number
    }
} while(isnum && value <= MAXVAL);              // until not a digit

If you have a backspace key, you simply divide the accumulator value by 10.

2
  • It would work if it wasn't a 4*4 keyboard. btw it can be modified to use a byte per keypress instead, giving access to all the keypad possibilities :)
    – abidon
    Aug 30, 2016 at 17:04
  • @Aureo the keyboard is not relevant to the question. OP answered my comment question, his aim is to input a single number in the range 0..9999 Aug 30, 2016 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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