Shop OBEX P1 Docs P2 Docs Learn Events
Storing an input from matrix keypad? — Parallax Forums

Storing an input from matrix keypad?

FlBuckeyeFlBuckeye Posts: 10
edited 2007-04-21 23:45 in Learn with BlocklyProp
I am using a 4x4 matrix keypad and I'm trying to store an input from the keypad subroutine for use in a password checker. I have the keypad working and have a password checker that works using the Debug window. My question is what command or series of commands is necessary to store the input from one subroutine and use it in another?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-21 01:31
    There isn't really any particular command involved. Subroutines share data by sharing variables. Say you have an input routine that responds to a keypress on the keypad, does the decoding, and leaves its keycode in a variable called 'key'. When the keypad subroutine is finished, it does a RETURN. Unless you change the 'key' variable, that value will remain there. If you call a routine 'password', you can use the value still in 'key' in 'password'.
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 02:10
    ok then my subroutines and variables appear ok, I think my problem is in the order of the main program. Back to hunting for the problem... Thanks anyway
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-21 02:42
    If you get stuck, I suggest including your program source as an attachment to an explanatory message describing the specifics of what you want to do, what input values were used and what incorrect behaviour / outputs were observed.
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 04:19
    Ok I'm stuck... I have tried doing this about 3 or 4 diffrent ways and right now I'm just not seeing where I'm messing up.

    I am attempting to use a homework board and a 4x4 matrix keypad as a password checker (once I get that part correct I will add more functionality). I can get either part to function fine on their own (keypad displays correct button pressed, and password checker works fine with the debug window and debugin for input). However when I combine the two I am getting one recorded keystroke and I can't seem to get the password checker to stop attempting to check the single keystroke to record the rest of the password.

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    Password DATA "1234" ' Store "secret" password here.

    db VAR Bit ' Debounce bit for use by keyScan.
    press VAR Bit ' Flag to indicate keypress.
    key VAR Nib ' Key number 0-15.
    row VAR Nib ' Counter used in scanning keys.
    cols VAR INB ' Input states of pins P4-P7.
    index VAR Nib ' Index variable.
    temp VAR Byte ' Stores single char.
    userEntry VAR Byte(4) ' Stores user entered password.

    DEBUG "enter Password"

    again:

    GOSUB keyScan


    IF press = 0 THEN again
    press = 0

    DEBUG userEntry, HEX key, CR


    DO
    FOR index = 0 TO 3
    READ Password + index, temp
    IF temp <> userEntry(index) THEN EXIT ' Compare to user input,
    NEXT

    IF index <> 3 THEN
    DEBUG CR, "Password not correct.", CR
    ENDIF
    LOOP UNTIL index = 3

    DEBUG "Password is correct"

    GOTO again



    keyScan:

    FOR row = 0 TO 3
    LOW row
    key = ~cols
    key = NCD key

    IF key <> 0 THEN push
    INPUT row
    NEXT
    db = 0
    RETURN


    push:
    IF db = 1 THEN done
    db = 1: press = 1
    key = (key-1)+(row*4)


    LOOKUP key,[noparse][[/noparse]1,2,3,10,4,5,6,11,7,8,9,12,14,0,15,13],key


    done:
    INPUT row
    RETURN
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-21 04:28
    I assume your keyScan works (I didn't look at it since you said it did). Your password checking code probably finds the password incorrect all the time partly because you've got two nested loops (DO/LOOP and FOR/NEXT) that are sort of doing the same thing. I suggest just using the DO/LOOP:
    index = 0
    DO
       read Password+index,temp
       if temp <> userEntry(index) then passFail
       index = index + 1
    LOOP until index = 4
    DEBUG "password correct",CR
    GOTO again
    passFail:
    DEBUG "password incorrect",CR
    GOTO again
    
    
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 04:39
    well that helped with the constant scrolling problem... now I just seem to still have a problem of it not correctly recording all 4 charcters to be checked. I greatly appreciate the help btw
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 04:45
    well I got it to wait for all 4 keys now by adding in

    userEntry(4) = key

    in the keyscan subroutine, but it still says the password is incorrect.
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 06:17
    still stuck... I'm thinking my problem might be in the way the "password" is stored. I have tried various methods and none of them seem to be working. I have tried:

    Password DATA "1234"
    Password DATA 1234
    Password DATA 1, 2, 3, 4

    I even tried specifying byte, and nib...

    I'm still stuck with the program not validating the password...

    I should have stuck with servos...
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-21 14:34
    1) You should use: Password DATA 1,2,3,4
    That's the way you're storing it, each keypress as a number from 1 to 14

    2) Your keyScan routine isn't storing the keypresses into 'userEntry', yet
    that's where you're looking for the entered information. That's what happens
    sometimes when you combine two routines that both work separately, yet
    don't work together. You sometimes forget the "glue" where one routine
    assumes that things are left one way and the other routine expects that
    things are left a slightly different way.
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 20:21
    Mike Green said...

    2) Your keyScan routine isn't storing the keypresses into 'userEntry', yet
    that's where you're looking for the entered information. That's what happens
    sometimes when you combine two routines that both work separately, yet
    don't work together. You sometimes forget the "glue" where one routine
    assumes that things are left one way and the other routine expects that
    things are left a slightly different way.

    hmmm... I thought that's what this was doing that I added in last night... apparently I'm just not quite getting it just yet... thanks for the patience...

    Here is what my understanding is of what I need to do...

    1. set password variable
    2. keyscan
    3. store entered variables from keyscan in 'userEntry'
    4. compare userEntry variable with password variable

    apparently it looks like it is only storing just one of the keypresses before comparing the variables, what do I need to do diffrent to make it store all 4 keys before attempting to check the password?



    keyScan:
    FOR row = 0 TO 3
    LOW row
    key = ~cols
    key = NCD key
    userEntry(4) = key
    IF key <> 0 THEN push
    INPUT row
    NEXT
    db = 0
    RETURN
    
    push:
    IF db = 1 THEN done
    db = 1: press = 1
    key = (key-1)+(row*4)
    RETURN
    
    LOOKUP key,[noparse][[/noparse]1,2,3,10,4,5,6,11,7,8,9,12,14,0,15,13],key
    
    done:
    INPUT row
    RETURN
    
  • Mike GreenMike Green Posts: 23,101
    edited 2007-04-21 20:35
    Here's something like your code that may work better:
    keyScan:
       index = 0
    nextKey:
       db = 0
       for row = 0 to 3
          low row
          key = NCD (~ cols)
          if key <> 0 then
             if db = 1 then
                input row
                key = (key-1) + (row*4)
                lookup key,[noparse][[/noparse]1,2,3,10,4,5,6,11,7,8,9,12,14,0,15,13],key
                userEntry(index) = key
                index = index + 1
                if index = 4 then
                   return
                endif
                goto nextKey
             endif
             db = 1
          endif
          next
          goto keyScan
    
    
  • FlBuckeyeFlBuckeye Posts: 10
    edited 2007-04-21 23:45
    Well it now works... I created an electronic lock of sorts... (with a little help from mike, thanks!) I'm sure it isn't perfect but it works...

    My two big errors were that I needed to loop the key sequence and where I put the line for the userEntry variable below (vs. above) where index incremented.

    I have a grayhill 4x4 keypad attached to p0 up to p7
    A servo (connected to a mechanical lock) on p12
    A bi-color LED connected to p14 and p15

    You enter the correct pin and the servo unlocks the lock and the light changes from red to green for about 5 seconds then relocks the lock and light goes green to red.

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    Password DATA     1,2,3,4   ' Store "secret" password here.
    
    db VAR Bit                          ' Debounce bit for use by keyScan.
    press VAR Bit                       ' Flag to indicate keypress.
    key VAR Nib                         ' Key number 0-15.
    row VAR Nib                         ' Counter used in scanning keys.
    cols VAR INB                        ' Input states of pins P4-P7.
    index VAR Nib                       ' Index variable.
    counter VAR Byte
    temp VAR Byte                       ' Stores single char.
    userEntry VAR Nib(4)               ' Stores user entered password.
    index2 VAR Nib
    
    
    
    start:
    DEBUG "enter Password",CR
    LOW 15
    HIGH 14
    
    FOR counter = 1 TO 10
    PULSOUT 12, 1000
    NEXT
    
    userEntry = 0 /4
    
    main:
    FOR index2 = 0 TO 3
      DO
        GOSUB keyScan
      LOOP WHILE press = 0
      DEBUG "key pressed = ", HEX key,CR
      press = 0
    NEXT
    index = 0
    GOSUB checkPassword
    
    checkPassword:
    DO
    READ Password+index,temp
    DEBUG DEC temp, " <> ", DEC userEntry(index),CR
    IF temp <> userEntry(index) THEN passFail
    index = index + 1
    LOOP UNTIL index = 4
    DEBUG "password correct",CR
    GOTO servoLight
    GOTO start
    
    passFail:
    DEBUG "password incorrect",CR
    GOTO start
    
    servoLight:
    FOR counter = 1 TO 180
    HIGH 15
    LOW 14
    PULSOUT 12, 500
    PAUSE 20
    NEXT
    GOTO start
    
    
    
    keyScan:
    FOR row = 0 TO 3
    LOW row
    key = ~cols
    key = NCD key
    IF key <> 0 THEN push
    INPUT row
    NEXT
    db = 0
    RETURN
    
    
    push:
    IF db = 1 THEN done
    db = 1: press = 1
    key = (key-1)+(row*4)
    LOOKUP key,[noparse][[/noparse]1,2,3,10,4,5,6,11,7,8,9,12,14,0,15,13],key
    userEntry(index) = key
    index = index + 1
    
    done:
    INPUT row ' Disconnect output on row.
    RETURN
    
    

    Post Edited (FlBuckeye) : 4/21/2007 11:49:43 PM GMT
Sign In or Register to comment.