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,

  • 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? – Khalil Khalaf Aug 30 '16 at 16:27
  • I don't know how to do it. Could you recommend a site that explains it? – Raymond Ogunjimi Aug 30 '16 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. – Khalil Khalaf Aug 30 '16 at 16:37
  • Do you want a digit array, or a single number in the range `0-9999`? – Weather Vane Aug 30 '16 at 16:39
  • but that would overwrite the digit already stored in my variable each time I call getkey(), instead of adding to it...right?! – Raymond Ogunjimi Aug 30 '16 at 16:41
  • 1
    We all love Arduino and it simplicity but please don't copy paste code, make an effort to understand it. – vz0 Aug 30 '16 at 16:56
  • Of course, I want to understand it. – Raymond Ogunjimi Aug 30 '16 at 16:59
  • @vz0 is right, I gived you something which sounds complete (but it may not compile as its not tested) but you won't be able to modify it to suit your needs if you don't have at least the basic in programming. Do not hesitate to send me a message if you want precisions, and tweak the code as much as possible, there's plenty of room to make the behavior more user friendly ! (a buzzer or led to give the user some feedback) – abidon Aug 30 '16 at 17:00
  • I'll try to figure it out myself. Thank you very much for it!! – Raymond Ogunjimi Aug 30 '16 at 17:03
  • I already have an LED in the circuit by the way... :) https://circuits.io/circuits/2498018-combination-lock/embed#breadboard – Raymond Ogunjimi Aug 30 '16 at 17:06

2 Answers2

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)

abidon
  • 456
  • 4
  • 15
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.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • 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 '16 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` – Weather Vane Aug 30 '16 at 17:08