Reputation: 13
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,
Upvotes: 0
Views: 10284
Reputation: 34585
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.
Upvotes: 0
Reputation: 456
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)
Upvotes: 1