Password help w/ Keypad & LCD
Cambodia
Posts: 2
Hello! A friend of mine and I are having issues getting any code dealing with passwords and keypads to work. I have looked online and on this forum for weeks without luck. Could anyone help us? Were using a 4x4 Matrix Membrane Keypad in pins 0-7 and a Parallax 2 x 16 Serial LCD (Non-Backlit) in pin 15. We know these two codes work:
LCD Code
Keypad Code
LCD Code
' {$STAMP BS2} ' {$PBASIC 2.5} TxPin CON 15 n9600 CON 84 HIGH TxPin ' Set serial pin port high PAUSE 100 ' Pause to initialize SEROUT TxPin, n9600, [12, 17] ' Clear, turn on backlight SEROUT TxPin, n9600, ["Hello, world...", 13] ' Print text, line feed SEROUT TxPin, n9600, ["from Parallax!"] SEROUT TxPin, n9600, [212, 220] ' Quarter A note PAUSE 3000 ' Wait 3 seconds SEROUT TxPin, n9600, [18] ' Turn backlight off
Keypad Code
' {$STAMP BS2} ' {$PBASIC 2.5} row VAR Nib ' Variable space for row counting column VAR Nib ' Variable space for column counting keypad VAR Word ' Variable space to store keypad output keypadOld VAR Word ' Variable space to store old keypad output temp VAR Nib ' Variable space for polling column states DEBUG CLS ' Clear Debug Terminal GOSUB Update ' Display keypad graphic DO GOSUB ReadKeypad ' Read keypad button states DEBUG HOME, BIN16 keypad, CR, CR, ' Display 16-bit keypad value BIN4 keypad >> 12,CR, ' Display 1st row 4-bit keypad value BIN4 keypad >> 8, CR, ' Display 2nd row 4-bit keypad value BIN4 keypad >> 4, CR, ' Display 3rd row 4-bit keypad value BIN4 keypad ' Display 4th row 4-bit keypad value IF keypad <> keypadOld THEN ' If different button is pressed, GOSUB Update ' update the keypad graphic to clear ENDIF ' old display IF keypad THEN ' Display button pressed in graphic GOSUB display ENDIF keypadOld = keypad ' Store keypad value in variable keypadOld LOOP ' -----[ Subroutine - ReadKeypad ]------------------------------------------------- ' Read keypad button states ReadKeypad: keypad = 0 OUTL = %00000000 ' Initialize IO DIRL = %00000000 FOR row = 0 TO 3 DIRB = %1111 ' Set columns (P7-P4) as outputs OUTB = %0000 ' Pull columns low (act as pull down) OUTA = 1 << Row ' Set rows high one by one DIRA = 1 << Row temp = 0 ' Reset temp variable to 0 FOR column = 0 TO 3 INPUT (column + 4) ' Set columns as inputs one by one temp = temp | (INB & (1 << column)) ' Poll column state and store in temp NEXT keypad = keypad << 4 | (Temp REV 4) ' Store keypad value NEXT RETURN ' -----[ Subroutine - Update ]----------------------------------------------------- ' Graphical depiction of keypad Update: DEBUG CRSRXY,0,7, "+---+---+---+---+",CR, "| | | | |",CR, "+---+---+---+---+",CR, "| | | | |",CR, "+---+---+---+---+",CR, "| | | | |",CR, "+---+---+---+---+",CR, "| | | | |",CR, "+---+---+---+---+" RETURN ' -----[ Subroutine - Display ]---------------------------------------------------- ' Display button pressed in keypad graphic Display: IF KeyPad.BIT15 THEN DEBUG CRSRXY, 02,08,"1" IF Keypad.BIT14 THEN DEBUG CRSRXY, 06,08,"2" IF KeyPad.BIT13 THEN DEBUG CRSRXY, 10,08,"3" IF Keypad.BIT12 THEN DEBUG CRSRXY, 14,08,"A" IF KeyPad.BIT11 THEN DEBUG CRSRXY, 02,10,"4" IF Keypad.BIT10 THEN DEBUG CRSRXY, 06,10,"5" IF KeyPad.BIT9 THEN DEBUG CRSRXY, 10,10,"6" IF Keypad.BIT8 THEN DEBUG CRSRXY, 14,10,"B" IF KeyPad.BIT7 THEN DEBUG CRSRXY, 02,12,"7" IF Keypad.BIT6 THEN DEBUG CRSRXY, 06,12,"8" IF KeyPad.BIT5 THEN DEBUG CRSRXY, 10,12,"9" IF Keypad.BIT4 THEN DEBUG CRSRXY, 14,12,"C" IF KeyPad.BIT3 THEN DEBUG CRSRXY, 02,14,"*" IF Keypad.BIT2 THEN DEBUG CRSRXY, 06,14,"0" IF KeyPad.BIT1 THEN DEBUG CRSRXY, 10,14,"#" IF Keypad.BIT0 THEN DEBUG CRSRXY, 14,14,"D" RETURN
Comments
Remember that your LCD expects characters, one byte per character, to be sent via SEROUT. Your keypad code supplies one bit for each button on the keypad and this is returned in "keypad" when you call ReadKeypad. There's no debouncing (look up debounce in the Wikipedia) done by ReadKeypad and there's no translation to a character. You have to do that yourself in your code. The NCD operator will take the "keypad" value and return the number of the first 1 bit found which you can use with LOOKUP to translate to a character. Look in the Stamp Reference Manual for the descriptions of these operators / statements.
I think there's a Nuts & Volts column on using a similar keypad. Have a look at the code they use for suggestions. The archive is on Parallax's website.
We've looked at the Manual for information on both keypad and passwords, and it has left us more confused than given us answers.
The only Nuts&Volts column I see that might be the one you're referring to is #22, and we've already looked at it. I'll double check with it though.
This is a code that we've been messing with to see if we could get it to work.
Which is based on this code:
We both don't have much knowledge with STAMP. Most of what we know about microcontrollers is from Ardunio and using C++
ReadKeypad is good, but you don't need Update or Display or keypadOld. Have you looked at NCD and LOOKUP yet? You have to understand those.
You need to create a subroutine (labelled GetAKey) that first sits in a loop (DO ... LOOP) calling ReadKeypad until keypad is zero. This ensures that none of the keys are pressed. Next in that subroutine is another loop (DO ... LOOP) that calls ReadKeypad until keypad is non-zero. This ensures that some key is pressed, maybe more than one. Now you have to identify which key is pressed and translate it like:
keypad = (NCD keypad) - 1
lookup keypad,["D","#","0","*","C","9","8","7","B","6","5","4","A","3","2","1"],keypad
The result in keypad is the character code and your subroutine can RETURN with that in keypad.
Go ahead and create the GetAKey subroutine. Read the Manual sections on DO/LOOP. Write a short main program (that comes first) that calls GetAKey and displays the result with DEBUG. See what you get.
Mike Green has gotten you off to a great start!
You should always have the Stamp Manual handy.
http://www.parallax.com/sites/default/files/downloads/27218-Web-BASICStampManual-v2.2.pdf
The older version of What's a Microcontroller had a password check program starting on page 289.
https://www.pololu.com/file/0J204/What%27s_a_microcontroller_text.pdf
Chapter 1 of the old Smart Sensors text shows how to use the Serial LCD.
http://www.parallax.com/sites/default/files/downloads/28029-Smart-Sensors-Text-v1.0.pdf
To modify ReusablePasswordChecker.bs2 you need to change all the DEBUG statements to SEROUT statements.
Adding CR CON 13 to the Constants section of your program will take care of any CR that is part of a DEBUG statement since a CR is actually an ASCII code of 13.
Also, if you notice some of your SEROUT statements end in 13 which is the same as sending a CR, so you can change them to CR since that's what they mean.
The password entry and check code is more of a problem since DEBUGIN will read in a String of 5 characters.
You can either call Get-A-Key 5X and store each value in a String BEFORE the FOR..NEXT or call Get_A_Key before the READ statement in the FOR...NEXT loop.
Remember though that normally a person will see the display change as each key is pressed. You can either display the key that was pressed or * so no one else can see it. To do this you would first call Get_A_Key and then send a SEROUT to the LCD.
You can use the keyscan subroutine portion of this along with the attached code to see how this kind of stuff is done. The attached program is from a demo I did back in 2006 using an EDE1144 keypad decoder. But between the two programs there is a lot of useful information there. Hopefully you will find it useful.
The Security test code even has a timeout function on the input as well as the ability to support extra functions from the keypad.