Detailed Explanation:
To begin with, I had to research how my truck unlocked the power doors. I thought it was a simple 12 V on a switch but I was definitely wrong. I found that it needed a “Negative Trigger” on a certain wire through a 330 Ω resistor. I tested this on the truck and found the proper wires that needed to be shunted with the resistor. I knew I was going to use a relay to close the circuit, but the only relay I had on hand had a 12 V coil. I knew I wanted a 2N3904 to activate the coil, so I did a bit of research and found an excellent write up on how to design the circuit. (http://www.instructables.com/id/Connecting-a-12V-Relay-to-Arduino/?ALLSTEPS). I already measured my coils on current at 30 mA and the β of my transistor to be 282. I needed a base current of about 0.1 mA to drive the collector current. I realized just now that I should have accounted for the 0.7 VBE drop, but originally I didn’t. I simply took 5 V / 0.1 mA and found that I needed a base resistor of about 50 kΩ. I used a 51 kΩ that I had already.
Beyond this, all the work was wiring and putting it together. I didn’t take photos while I was working on it, but I stuffed it all into a jewelry box.
Device Use:
This device is meant to be very easy to use. The code is initialized as “123AB” in the program above. Any time the Arduino loses power, it will have this code upon power restoration. At any time, the user can enter “CDCBA” to enter the “Password Reset” mode. After entering that special code, a series of beeps would be heard, and the next five buttons pressed become the new password. The device uses a “rolling” entry method, so if a mistake is made when entering the code, simply start over at any time. As long as the correct five characters are entered in the correct order, the doors will unlock. Additionally, there is a time-out feature; if at any time 10 seconds goes by without pressing a button, the previously pressed buttons will reset to “0”. This is active all the time except when entering a new password.
Future Considerations:
The first and most obvious mistake I made was with the buzzer. It is far too quiet to be heard outside the truck. I was originally going to mount the box with the buzzer held firmly against the sheet metal, but I had to flip it around to get it where I needed it. This means that the buzzer is essentially useless. Some have brought up the consideration of weather resistance. I would have loved to use a higher quality keypad, but I was working with what I had on hand. It seems as though the keypad itself will be very weather-proof. Additionally, the adhesive on the back seems very strong, but time will tell if it will hold up to the elements. Lastly, had I access to a 3D printer, and more time, I would have loved to have printed a custom enclosure for this device. I would have also loved to have printed a custom PCB, as that would have been easier for wiring. Since there were only a few components, the point-to-point soldering worked fine for inside the box.
Code:
// Dodge Dakota Keypad Entry System
// S. Newberry, August 2014
//*************************************
//*****SETUP FOR KEYPAD****************
//*************************************
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'},
};
byte rowPins[ROWS] = {3, 4, 5, 6};
byte colPins[COLS] = {7, 8, 9, 10};
Keypad entryKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
//*******************************************
//************SETUP FOR OTHER VARIABLES******
//*******************************************
int relayPin = 2; //set pin number for the relay actuation
char pw1 = '1'; //these are the password
char pw2 = '2';
char pw3 = '3';
char pw4 = 'A';
char pw5 = 'B';
char key1 = '0'; //starting values in the thingy
char key2 = '0';
char key3 = '0';
char key4 = '0';
char key5 = '0';
unsigned long startTime = millis(); //set the start time
//*******************************************
//************END OF THIS SETUP**************
//*******************************************
void setup() {
pinMode(relayPin, OUTPUT); //set relay pin output to pin two
}
void loop() {
char newKey = entryKeypad.getKey(); //Get key pressed
if (newKey){ //if the key is pressed
tone(13, 500, 100);
startTime = millis(); //set a new start time
key1 = key2; //move all the other values
key2 = key3;
key3 = key4;
key4 = key5;
key5 = newKey; //set the new one to 5
if (key1 == 'C' & key2 == 'D' & key3 == 'C' & key4 == 'B’ & key5 == 'A') { //detect pw change routine
//This goes here because it prevents user from entering pw as the same as the change entry routine.
delay(150); //tones for pw change entry
tone(13, 1000, 100);
delay(200);
tone(13, 1000, 100);
delay(200);
tone(13, 1000, 100);
char newpw1 = entryKeypad.waitForKey(); //force keypresses
if (newpw1) { //once key is pressed
pw1 = newpw1; //set new pw
tone(13, 500, 100); //tone for keypress
char newpw2 = entryKeypad.waitForKey(); //repeat
if (newpw2) {
pw2 = newpw2;
tone(13, 500, 100);
char newpw3 = entryKeypad.waitForKey(); //repeat
if (newpw3) {
pw3 = newpw3;
tone(13, 500, 100);
char newpw4 = entryKeypad.waitForKey(); //repeat
if (newpw4) {
pw4 = newpw4;
tone(13, 500, 100);
char newpw5 = entryKeypad.waitForKey(); //repeat
if (newpw5) {
pw5 = newpw5;
tone(13, 500, 50); //keypress tone
delay(500);
tone(13, 2000, 100); //confirm pw was changed tone
delay(200);
tone(13, 2000, 100);
delay(200);
tone(13, 2000, 100);
delay(200);
tone(13, 2000, 100);
delay(200);
tone(13, 2000, 100);
}
}
}
}
}
}
else if (key1 == pw1 & key2 == pw2 & key3 == pw3 & key4 == pw4 & key5 == pw5) { //check all values in the chain
digitalWrite(relayPin, HIGH); //relay goes high
delay(500); //half a second high
digitalWrite(relayPin, LOW); //relay goes back low
delay(250);
tone(13, 1300, 100); //entry success tone
delay(200);
tone(13, 1500, 100);
}
}
else if (millis() > startTime + 10000) { //no key was pressed for 10 seconds
startTime = millis(); //reset the start time
key1 = '0'; //reset all counter values
key2 = '0';
key3 = '0';
key4 = '0';
key5 = '0';
}
}