Pages: [1]   Go Down
Author Topic: how to capture input from keypad?  (Read 1374 times)
0 Members and 1 Guest are viewing this topic.
Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

London
Offline Offline
Faraday Member
**
Karma: 10
Posts: 6248
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have not run the code below but it should get you going in the right direction
Code:
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;  
}
« Last Edit: February 15, 2009, 01:39:55 am by mem » Logged

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just a wild gues, but i think that you should remove comment ('//') from this line:
Code:
char key;// = kpd.get_key();
because now you're not getting any input from keypad...
It should be like this:
Code:
char key = kpd.get_key();
Logged

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: February 20, 2009, 12:21:40 am by wizdum » Logged

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: March 11, 2009, 01:56:42 am by wizdum » Logged

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

London
Offline Offline
Faraday Member
**
Karma: 10
Posts: 6248
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
 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;
  }
Logged

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

London
Offline Offline
Faraday Member
**
Karma: 10
Posts: 6248
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here it is:
Code:
 #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.
Logged

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

London
Offline Offline
Faraday Member
**
Karma: 10
Posts: 6248
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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;

  }
« Last Edit: March 12, 2009, 05:01:24 pm by mem » Logged

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: March 12, 2009, 05:21:28 pm by wizdum » Logged

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

Maine
Offline Offline
Sr. Member
****
Karma: 14
Posts: 417
Caution: Explosives in use.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Anyone who isn't confused really doesn't understand the situation."

Electronic props for Airsoft, paintball, and laser tag -> www.nightscapetech.com

0
Offline Offline
God Member
*****
Karma: 0
Posts: 572
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
 smiley
 
Logged

Pages: [1]   Go Up
Jump to: