Hey everyone. After having it sit around unfinished for a few months, I finally finished my car door keypad code. The keypad is a five button keypad from a ford explorer, interfaced with my arduino and ready to be embedded into my Dodge. The software is 100% finished and now I'm letting the hardware run on 12v for a while in my house before I take the plunge and cut the hole in my door.
Basically, you type in the combo and it unlocks your doors. (closes an optical relay) If you press the last two together, it locks your doors. The backlight lights when you press a button, and goes out 4 seconds later. The entered code is sliding, so if the code was 12345, you could press 5512345 and get in. I thought about not having it this way, but I'd rather not have to wait if I mispress. I mean, no one is really going to try and brute force it, so I'm not worried. The entered code is cleared after the same timeout as the backlight.
This is my first real project, so it may be kind of hard to read.
// Car Keypad
// Version 0.20 beta
//
// Michael Casson Rogers (michael.casson@yahoo.com)
// March 10th, 2009
//
// Takes input from keys, compares last 5 pressed keys to the pre-programmed code.
// If last 5 pressed keys are the same as the code, unlock door.
// If last two buttons are pressed simultaneously, lock door.
//
// Input keys are assigned values starting with 0 for the first, 1 for the second, etc.
//
// Time out (reset input keys) after programmable time (default 4 seconds).
//
// For this program I borrowed heavily from Simple Simon 2.0 by Gian Pablo Villamil
// http://itp.nyu.edu/~gpv206/2006/09/simple_simon_v2.html
//
// Define the pins the lock and unlock relays are connected to.
#define UnlockPin 18
#define LockPin 19
#define BackLight 17 // Define backlight pin.
#define DebounceTime 20 // debounce time in milliseconds
#define TimeOutTime 4000 // timeout in milliseconds
// Define the pin assignments for the input switches
#define ButtonStartPin 2
#define ButtonEndPin 6
// Set how many buttons
int ButtonValues = ButtonEndPin - ButtonStartPin ;
int codeLength = 5; // Set code length
int CodeArray[5] = {1, 2, 4, 1, 0}; // Enter desired combination code here, must match codeLength
int InputArray[5] = {9, 9, 9, 9, 9}; // Starts InputArray with all 9's
// Remember when last press was for timeout function.
// Also, set lastPress as having just timed out so that the backlight doesn't light for the first few
// seconds on initialization because lastPress and millis are both zero.
unsigned long lastPress = millis() - (TimeOutTime + 1);
// Define inputScore (used to compare InputArray to CodeArray)
int inputScore = 0 ;
// Define rightAnswer (set to true when code is validated)
int rightAnswer = false ;
// counter for debouncing routine
unsigned long SwitchDownTime ;
void setup () {
//Serial.begin(9600); // set up Serial library at 9600 bps, used for debugging.
pinMode(LockPin, OUTPUT);
pinMode(UnlockPin, OUTPUT);
pinMode(BackLight, OUTPUT);
for (int i = ButtonStartPin; i <= ButtonEndPin; i++) {
pinMode(i, INPUT);
}
}
// Main loop - should be easy to follow
void loop () {
getAnswer () ;
timeOut () ;
checkAnswer () ;
if (rightAnswer) {
Success();
}
}
// Get the user's button presses and store it in InputArray
void getAnswer () {
for (int i = 0; i < codeLength; i++) {
for (int j = 0; j <= ButtonValues; j++) { // poll the switches
if (digitalRead(ButtonStartPin+j)) { // If current polled button is down
SwitchDownTime = millis() ; // Record time it went down (for debounce)
digitalWrite(BackLight, HIGH); // Light backlight while pressed
lastPress = millis() ; // Needed here to light as soon as button is pressed
while (digitalRead(ButtonStartPin+j)) { // While a button is pressed
if (digitalRead(ButtonEndPin - 1) && digitalRead(ButtonEndPin)) { // If the last two are pressed together
digitalWrite(LockPin, HIGH); //
} else {
digitalWrite(LockPin, LOW);
}
}
if (millis() - SwitchDownTime > DebounceTime) { // If button was down longer than debounce
InputArray[0] = InputArray[1];
InputArray[1] = InputArray[2];
InputArray[2] = InputArray[3];
InputArray[3] = InputArray[4];
InputArray[4] = j;
lastPress = millis() ; //Needed here also, in case button is held down for more than timeout value
} // end if
} // end if
} // end for
} // end for
} // end GetAnswer
// Compare CodeArray with InputArray
void checkAnswer () {
// Print current InputArray
//for (int i = 0; i < codeLength; i++) {
// Serial.print(InputArray[i]);
//}
// Serial.println(" ");
// End print current InputArray
inputScore = 0;
for (int i = 0; i < codeLength; i++) {
if (CodeArray[i] == InputArray[i]) {
inputScore = inputScore + 1;
}
}
if (inputScore == codeLength) {rightAnswer = true;}
}
void Success () {
digitalWrite(UnlockPin, HIGH);
delay(100);
digitalWrite(UnlockPin, LOW);
clearArray () ;
rightAnswer = false;
}
void timeOut () {
if (millis() - lastPress > TimeOutTime) {
clearArray() ;
digitalWrite(BackLight, LOW);
lastPress = millis() - (TimeOutTime + 1); //lastPress follows millis() just outside of timeout, to prevent problems with millis rollover lighting backlight after 50 days
} else {
digitalWrite(BackLight, HIGH);
}
}
void clearArray () {
InputArray[4] = 9;
InputArray[3] = 9;
InputArray[2] = 9;
InputArray[1] = 9;
InputArray[0] = 9;
}