#include <Keypad.h> // used for the keypad
#include <Stepper.h> // used for the stepper motor
const int ROW_NUM = 4; // Four rows
const int COLUMN_NUM = 4; // Four columns
char keys[ROW_NUM][COLUMN_NUM] = {
{'1','2','3', 'A'},
{'4','5','6', 'B'},
{'7','8','9', 'C'},
{'*','0','#', 'D'}
};
// Connect to the row pinouts of the keypad
byte pin_rows[ROW_NUM] = {9, 8, 7, 6};
// Connect to the column pinouts of the keypad
byte pin_column[COLUMN_NUM] = {5, 4, 3, 2};
// Set up the keypad with the keys above
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
// Create the array of variables to set the guess array and password array
const int NUMBER_OF_DIGITS = 4;
char guessList[NUMBER_OF_DIGITS] = {'0', '0', '0', '0'};
char passList[NUMBER_OF_DIGITS] = {'1', '1', '1', '1'};
int currentDigit = 0;
// used to tell if we need to reset the password
bool setPassword = true;
// Ignore very last digit entered since it uses the last digit of the password as the first digit of the guess
bool first = true;
bool passwordSet = false; // used to tell us when the password is first set
// Total number of steps
const int TOTAL_STEPS = 200;
// steps per a half turn
const int HALF_TURN = 100;
// time to wait in seconds
const int TIME_TO_WAIT = 10;
// initialize the stepper and pins it uses
Stepper stepper(TOTAL_STEPS, 14, 15, 16, 17);
// Function to change the current digit in the array
void changeDigit(char newDigit){
guessList[currentDigit] = newDigit;
++currentDigit;
// loop around once we hit the end
if (currentDigit == NUMBER_OF_DIGITS){
setPassword = false;
currentDigit = 0;
}
}
bool checkPassword(){
bool passMatch = true;
for (int i = 0; i < NUMBER_OF_DIGITS; ++i){
if (guessList[i] != passList[i]){
passMatch = false;
}
}
return passMatch;
}
// turn the motor to unlock, wait a set amount of time, turn the other way to lock
// we assume the lock is locked when we start the program
void unlockThenLock(){
//Serial.println("Unlocking!");
// unlock the lock
stepper.step(HALF_TURN);
// wait the set amount of time, using delay since we don't need to do anything while it's waiting
delay(TIME_TO_WAIT * 1000);
Serial.println("Locking!");
// lock the lock
stepper.step(-HALF_TURN);
// reset the guess so it doesn't spam unlock and lock
for (int i = 0; i < NUMBER_OF_DIGITS; ++i){
// set to X since it's a character the user can't enter on the keypad
guessList[i] = 'X';
}
}
void setup() {
// put your setup code here, to run once:
// set the speed of the new stepper to 60 RPM
stepper.setSpeed(60);
// initialize the serial port at a baud rate of 9600
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
char key = keypad.getKey();
// Reset the password if the * key is pressed
if (key == '*'){
currentDigit = 0;
setPassword = true;
}
// If we need to set the password, and a key is pressed that isn't *, we reset the password
if (setPassword && key && key != '*'){
passList[currentDigit] = key;
++currentDigit;
// Loop around to the beginning of the array when we hit the end
if (currentDigit == NUMBER_OF_DIGITS){
currentDigit = 0;
setPassword = false;
passwordSet = true;
}
}
// If we don't need to reset the password, add the digit to the guest list
if(setPassword == false && key && key != '*' && first == false){
changeDigit(key);
}
// set first to false if we hit the max number of digits so we can edit the guess
if (first == true && passwordSet == true) first = false;
// If password matches the guess, unlock then lock
if (checkPassword() == true){
unlockThenLock();
}
}