how to capture input from keypad?

I have the 4 row by 3 column matrix keypad seen here:
http://www.arduino.cc/playground/Main/KeypadTutorial

I am trying to find a way to capture a 10-ish number code as it's typed in, so that I can compare it to a stored password that is declared in the code. Can someone show me an example of how to do this? I'm not really familiar with the language, so it's probably just a noobish question. Any help would be appreciated, thanks.

I have not run the code below but it should get you going in the right direction

char PW[] =  "1122334455";
char CANCEL_KEY = '*';

boolean getPW(){
  // returns true when all PW keys are pressed in sequence
  // returns false when number of keys in pW pressed but don't exactly match the PW
  // CANCEL_KEY erases all previous digits input

  int count;  // how many keys we have
  int matchCount;  // how many keys match
  
  for( count=0, matchCount=0; count < sizeof(PW)-1; count++){  
    char key;// = kpd.get_key();    
    if(key != '\0'){
      if(key == PW[count++])
        matchCount++;      
     else if(key == CANCEL_KEY)
       count = matchCount = 0;
    } 
  }
  // here when the same number of keys pressed as characters in the PW
  if( matchCount == count)
     return true;
  else
     return false;  
}

It seems to always be returning false, like it's not waiting until the full code it put in.

Just a wild gues, but i think that you should remove comment ('//') from this line:

char key;// = kpd.get_key();

because now you're not getting any input from keypad...
It should be like this:

char key = kpd.get_key();

Sorry it took so long to reply, been bogged down with college exams.

I saw that commented out section first and changed it, and added in some test cases. The arduino is getting the correct per key input from the keypad. I'll have to test a few more things and get back to you.

I fixed one error, and ended up with more. The always false problem was a code mistake by me, the getPW function was reset every second. I fixed that and now have a new problem. The for loop isn't waiting for input. I got it to print out the value of count and matchcount, and count just flashes 1,2,3 really fast, and the loop ends. Any help would be appreciated.

The code is not waiting for a kepress, try replacing the for loop code with this:

  for( count=0, matchCount=0; count < sizeof(PW)-1; count++){  
    char key; 
    do 
      key = kpd.get_key();           
    while(key == '\0');
    if(key == PW[count++])
      matchCount++;
    else if(key == CANCEL_KEY)
      count = matchCount = 0;
  }

That worked, thanks. The only problem is that I have to enter the code twice for some reason. The first time it goes through fine, getPW returns true, but the main loop wont continue until i type the code in again.

If you post your code then perhaps we can see what's causing that behavior.

Here it is:

  #include <keypad.h>

    #define ROWS 4
    #define COLS 3
keypad kpd = keypad(ROWS, COLS);



int second=30, minute=2, hour=0; // declare time variables
int var=1; //1 = Ready, 2 = Armed, 3 = Disarmed

char PW[] = "7355608";
char CANCEL_KEY = '*';

void setup()
{
  Serial.begin(9600);
  kpd.init();
  clearLCD();
  backlightOn();
}

void loop(){
  switch (var) {
    
    case 1:
selectLineOne();
delay(100);
Serial.print("Enter Code");

 if (getPW() == true) {
   clearLCD();
   delay(100);
   selectLineOne();
   Serial.print("Correct");
   var=2;
   delay(500);
   loop();
 }
 if (getPW() == false) {
   clearLCD();
   delay(100);
   selectLineOne();
   Serial.print("Incorrect");
 }
 
break;
   case 2:

static unsigned long lastTick = 0; // set up a local variable to hold the last time we decremented one second
// (static variables are initialized once and keep their values between function calls)

// decrement one second every 1000 milliseconds
if (second > 0) {
if (millis() - lastTick >= 1000) {
lastTick = millis();
second--;
serialOutput();
}
}

 // decrement one minute every 60 seconds
if (minute > 0) {
  
if (second <= 0) {
minute--;
second = 60; // reset seconds to 60
}
}

// decrement one hour every 60 minutes
if (hour > 0) {
if (minute <= 0) {
hour--;
minute = 60; // reset minutes to 60
}//closes if
}//closes if
}//closes switch
}//closes loop


boolean getPW(){
  // returns true when all PW keys are pressed in sequence
  // returns false when number of keys in pW pressed but don't exactly match the PW
  // CANCEL_KEY erases all previous digits input
 int count=0;  // how many keys we have
int matchCount=0;  // how many keys match
 
 for(count=0, matchCount=0; count < sizeof(PW)-1; count++){
    char key;
    do{
      key = kpd.get_key();
    }
    while(key == '\0');
    if(key == PW[count]) {
      matchCount++;
    }
    else if(key == CANCEL_KEY){
      count=0;
        matchCount=0;
        loop();
    }
 }
 
  // here when the same number of keys pressed as characters in the PW
  if(matchCount == count) {
    return true;
  }
  else {
     return false;

}
  }


void serialOutput() {
// this function creates a clock you can read through the serial port
// your clock project will have a MUCH more interesting way of displaying the time
// get creative!
clearLCD();
backlightOn();
//Print time on each line
selectLineTwo();
delay(100);
Serial.print("ARMED : ");
Serial.print(hour, DEC); // the hour, sent to the screen in decimal format
Serial.print(":"); // a colon between the hour and the minute
Serial.print(minute, DEC); // the minute, sent to the screen in decimal format
Serial.print(":"); // a colon between the minute and the second
Serial.println(second, DEC); // the second, sent to the screen in decimal format
//termination condition
if (second == 0 && minute == 0 && hour == 0) {
clearLCD();
backlightOn();
selectLineOne();
delay(100);
Serial.print("Have A Nice Day");
}
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(192, BYTE);    //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){ Serial.print(0xFE, BYTE);   //command flag
              Serial.print((position+128), BYTE);    //position
}else if (position<32){Serial.print(0xFE, BYTE);   //command flag
              Serial.print((position+48+128), BYTE);    //position 
} else { goTo(0); }
}

void clearLCD(){
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(0x01, BYTE);   //clear command.
}
void backlightOn(){  //turns on the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(128, BYTE);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.print(0xFE, BYTE);
}

Sorry it's not very organized, this is my first real attempt. This is for a timebomb prop for an MilSim airsoft group. After someone types the code in, the countdown starts, when the countdown ends it will eventually set off a buzzer.

You are calling the loop function from within the case statement in that loop function – not something you want to do.

I think in the case statment where the pw is true you want to replace the call to loop with code that sets the state (var) from armed to disarmed.

Its not clear from the code what you want to happen.

Giving your variables more meaningful names will make the code clearer. For example if the variable var is holding the state of the bomb, call it something like bombState instead of var.

You can also use constants to provide meaningful names, something like:

#define READY 1
#define ARMED 2
#define DISARMED 3

So your case becomes:

switch (bombState) {

case READY:
// your code here
break;

case ARMED:
// your code here
break;

case DISARMED:
// your code here
break;

}

Thanks for the tips. The call to the main loop was an attempt to fix this waiting for more button presses problem. Before i added that it would just pause on "Correct" until I pressed 7 more keys on the keypad. After I added that it just freezes once it reaches the countdown, and waits for 7 more key presses before the countdown will actually start.

Just wanted to reply saying that I fixed it, and thanks for all your help.

If you post your working code, that would help others who might have the same problem in the future

Could some one please help me with my code . i would like to use my keypad with a password as a switch.
i am new to programing and i have only just have my key pad working finally hear is my current code

#include <Keypad.h>
byte rows = 4; //four rows
byte cols = 4; //four columns
byte rowPins[] = {4, 9, 8, 6}; //connect to the row pinouts of the keypad
byte colPins[] = {5, 3, 7, 0}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad(rowPins,colPins,rows,cols);

void setup(){
Serial.begin(9600);
}

void loop(){
char key = keypad.getKey();

if (key != NO_KEY){
Serial.println(key);
}
}
i would like to know how to modify this code to switch a digital output when a password is entred.
:slight_smile: