Hello everyone! Let me start by saying I've searched for solutions to this problem before making this post, I just couldn't find a solution. I'm trying to make a countdown timer with a password to stop the timer. I'm making this for a local paintball game as a fake "bomb."
Problem:
I'm following this wiring schematic:
I have only connected the LCD and 3x4 Sparkfun keypad. The LCD is working perfectly but I can't get the Keypad to work at all. I think it may be because I have the keypad wired up wrong. I followed the above diagram and wired the 4 wires coming out of the keypad (3, 5, 6, 7) to 4 -1k Ohm resistors, and then conneced the other end of the resistors to my Arduino. Looking at other examples of keypads online, I've noticed that people usually have one side of the resistors grounded or with 5v going through it. I'll post pics of my Arduino setup once I get back to my house. If someone could point me in the right direction to helping me resolve this problem I would greatly appreciate it. Thanks, Mike
Also, if the below to code is to technical, could some could point to me a very bare bones code of just the keypad outputting data to the LCD screen? that would be very helpful. Thanks again, Mike
The code I modified for a 3x4 keypad:
/*Airsoft TIMER
Version 1.5
Creators:
Chase Cooley
Joey Meyer
Turned into usable code, 6/16/2011:
Matt Falcon
*/
#include <Keypad.h>
#include <LiquidCrystal.h>
#define pound 14
#define LED_RED 5
#define LED_GREEN 6
//#define KP_ROWS 3
//#define KP_COLS 4
unsigned int timerSeconds = 300; // start with 5 minutes on the clock
byte password[4];
byte entered[4];
int currentLength = 0;
byte i = 0;
const byte KP_ROWS = 4; //four rows
const byte KP_COLS = 3; //three columns
LiquidCrystal lcd(7, 8, 10, 11, 12, 13);
//Keypad
char keys[KP_ROWS][KP_COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[KP_ROWS] = {18, 2, 14, 16}; //connect to the row pinouts of the keypad {18, 2, 14, 16}
byte colPins[KP_COLS] = { 17, 19, 15 }; //connect to the column pinouts of the keypad {17, 19, 15}
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KP_ROWS, KP_COLS);
char key;
//LCD setup
void setup() {
pinMode(LED_RED, OUTPUT); // sets the digital pin as output
pinMode(LED_GREEN, OUTPUT); // sets the digital pin as output
lcd.begin(16, 2);
lcd.print("Enter Code NOW: ");
lcd.cursor();
lcd.setCursor(6, 1);
while (currentLength < 4) {
key = keypad.getKey();
if (key != NO_KEY) {
lcd.print(key);
password[currentLength] = key;
currentLength++;
lcd.setCursor(currentLength + 6, 1);
} else delay(100); // only sample it every 1/10 sec, no need to go apesh!t
}
lcd.noCursor();
lcd.clear();
lcd.print("You've Entered: ");
lcd.setCursor(6, 1);
lcd.print(password[0],DEC);
lcd.print(password[1],DEC);
lcd.print(password[2],DEC);
lcd.print(password[3],DEC);
delay(2500);
lcd.clear();
currentLength = 0;
}
void loop() {
lcd.clear();
lcd.print("Enter Code: ");
lcd.cursor();
key = keypad.getKey(); // get the key once per this loop
if (key != NO_KEY) {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
while (currentLength < 4) {
// here, we take the key that broke us into this "if" statement, instead of discarding it. this also pauses the timer, effectively.
if (key != NO_KEY) { // redundant for the first loop, but necessary for every next character
lcd.setCursor(currentLength + 5, 1);
lcd.print("*");
lcd.setCursor(currentLength + 6, 1);
lcd.print(key);
entered[currentLength] = key;
currentLength++;
} else delay(100); // only sample it every 1/10 sec
key = keypad.getKey(); // get the key every time "while" loops
}
if (memcmp(entered,password,4) == 0) { // shortcut to compare an array of bytes, use memcmp(A, B, length), will return 0 if match.
lcd.noCursor();
lcd.clear();
lcd.print(" Defused ");
lcd.setCursor(0, 1);
lcd.print("Reset the Bomb");
delay(2500); // hold that on screen for 2.5 seconds
currentLength = 0;
} else {
lcd.noCursor();
lcd.clear();
lcd.print(" Wrong ");
lcd.setCursor(0, 1);
lcd.print(" Time -0:30"); // Display time penalty
if (timerSeconds > 30) timerSeconds -= 30;
else timerSeconds = 1; // will trigger BOOM next cycle
currentLength = 0;
delay(2500); // hold that on screen for 2.5 seconds
}
}
timer(); // prints current time on screen, checks for "go off" time, holds loop for 1 second
}
void timer() {
lcd.setCursor(0, 1); // sets cursor to 2nd line
lcd.print("Timer: ");
lcd.print(timerSeconds / 60); // integer number of minutes on clock
lcd.print(":");
lcd.print(timerSeconds % 60); // mod 60; gives us number of seconds outside of 60sec/min
delay(950); // hold us here for 0.950 seconds
digitalWrite(LED_GREEN,!digitalRead(LED_GREEN)); // toggle the green LED once a second
tone(9,784, 200); // play bleep for 50ms
delay(50); // and there's the rest of that 1 second (not counting LCD delay)
timerSeconds--;
if (timerSeconds == 0) bombomb();
}
void bombomb() {
// routine for making ze BOMB GOEZ OFF!!!1 :D
lcd.noCursor();
lcd.clear();
lcd.print(" !BoOo0o0o0om! ");
tone(9,110, 200);
digitalWrite(LED_RED, HIGH); // sets the red LED on
delay(500); // waits half a second
tone(9,110, 200);
delay(500); // waits half a second
digitalWrite(LED_RED, LOW); // sets the red LED off
digitalWrite(LED_GREEN, HIGH); // sets the green LED on
tone(9,110, 200);
delay(500); // waits half a second
digitalWrite(LED_RED, HIGH); // sets the red LED on
digitalWrite(LED_GREEN, LOW); // sets the green LED off
tone(9,110, 200);
delay(500); // waits half a second
digitalWrite(LED_RED, LOW); // sets the red LED off
digitalWrite(LED_GREEN, HIGH); // sets the green LED on
tone(9,110, 200);
delay(500); // waits half a second
digitalWrite(LED_GREEN, LOW); // sets the green LED off
key = NO_KEY; // enter the while() loop, otherwise it'll skip. i could use do { } while();, but I'm lazy.
while (key == NO_KEY) {
key = keypad.getKey();
if (key == '#') {
lcd.clear();
lcd.print("Reset the Bomb");
delay(2500); // good ole' 2.5 sec delay
timerSeconds = 300; // put 5 minutes on the clock
// and we break the loop and go back to timer.
} else key = NO_KEY; // continue looking for pound key
}
}