How to: Get multiple digits using PCF8574 and 4x4 Keypad
I wanted to add a 4 x 4 keypad to my Magellan bot using the PCF 8574 I/O expander. It was a simple plan but good gosh did it take longer than I originally thought.
Below is the culmination of others work and my own small code contribution. Im sure there is a better software solution than what I show below, but here is the gear head result.
Big thanks to doggiedoc for his PCB. Attached are a few pictures showing the board. I used 10K resistors throughout, and garden variety Radio Shack PNP transistors. The capacitor is a 104. I added a 90 degree header on the same side as the chip so that the keypad and leads folded over from the other side. I added a piece of EPDM roofing rubber to act as a base covering the solder stubble on the board. I also added a zip tie to keep the chip from vibrating out of the socket.
In this version, the # key sums up all the key entries, and the * key acts as a backspace. In the end, its pretty simple code, and can be adapted very easily. It just took me 15 hours of beating my head against the wall to determine that it was easy! LOL!
Below are links to the project and related posts:
http://forums.parallax.com/showthread.php/144101-Robo-Magellan?p=1157618#post1157618
http://forums.parallax.com/showthrea...r-the-Hard-Way
http://forums.parallax.com/showthrea...=1#post1153611
http://forums.parallax.com/showthrea...-review-please!
http://obex.parallax.com/objects/sea...53fd64f0384712
http://forums.parallax.com/showthread.php/146337-How-to-Wire-4x4-Keypad-to-work-with-PCF8574A-I-O-expander-chip?p=1167113#post1167113
Thanks
Steve
Below is the culmination of others work and my own small code contribution. Im sure there is a better software solution than what I show below, but here is the gear head result.
Big thanks to doggiedoc for his PCB. Attached are a few pictures showing the board. I used 10K resistors throughout, and garden variety Radio Shack PNP transistors. The capacitor is a 104. I added a 90 degree header on the same side as the chip so that the keypad and leads folded over from the other side. I added a piece of EPDM roofing rubber to act as a base covering the solder stubble on the board. I also added a zip tie to keep the chip from vibrating out of the socket.
In this version, the # key sums up all the key entries, and the * key acts as a backspace. In the end, its pretty simple code, and can be adapted very easily. It just took me 15 hours of beating my head against the wall to determine that it was easy! LOL!
Below are links to the project and related posts:
http://forums.parallax.com/showthread.php/144101-Robo-Magellan?p=1157618#post1157618
http://forums.parallax.com/showthrea...r-the-Hard-Way
http://forums.parallax.com/showthrea...=1#post1153611
http://forums.parallax.com/showthrea...-review-please!
http://obex.parallax.com/objects/sea...53fd64f0384712
http://forums.parallax.com/showthread.php/146337-How-to-Wire-4x4-Keypad-to-work-with-PCF8574A-I-O-expander-chip?p=1167113#post1167113
Thanks
Steve
''KeyPad Tester using Craig Webers PCF 8574 driver and
'' Paul A. Willoughby, DVM interface circuit.
'' Key pad mapped to match the typical membrane type
''
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'*******************
PST = 0 ' Port for Communication to PST
LCD = 1 ' Port for Communication to LCD Tx only
GPSPort = 2 ' Port for Communication to GPS Rx only
PST_BAUD = 115_200 ' PST baud rates, debug to terminal
LCD_BAUD = 19_200 ' LCD baud rate
GPS_BAUD = 9_600 ' GPS baud rate
LCD_TXPIN = 4 ' LCD Tx pin
LCD_RXPIN = -1 ' LCD Rx pin THERE IS NONE
GPS_TXPIN = 14 ' GPS Tx
GPS_RXPIN = 15 ' GPS Rx pin
PST_TXPIN = 30 ' PST Tx Pin
PST_RXPIN = 31 ' PST Rx Pin
LF = 10
CR = 13
'********************
KeySCL = 7' 15 'PCF8574 Serial ClK line
KeySDA = 6 '14 'PCF8574 Serial DATA line
KeyADDR = 56 'PCF8574A I2C Address (A0, A1, A2 all pulled low)
CLS = 0
OBJ
IO : "PCF8574_Driver"
FDS : "FullDuplexSerial"
Pub Main |x
fds.start(31, 30, %0000, 115200) 'Start the PST in the usual manner
waitcnt(clkfreq*4+cnt) 'Wait 4 seconds
repeat
fds.str(string(13, "STARTING!!: ")) 'Send notice that we are atarting
waitcnt(clkfreq+cnt) 'Wait a second
x:=GetKey
if x > 9999
blink_LED
PUB GetKey |BitPattern,KeyPressed,KeyNum,KeyTotal 'Demonstrates the basic functionality of getting keyvalues into to Prop
KeyNum:=KeyTotal:=0 'Zero out any previous value
Repeat until KeyNum == 500 'Repeat until # is pressed as defined below
IO.Set_Pins(KeySCL, KeySDA)
IO.Initialize 'Initializes the I2C line with the PCF8574 chip
IO.OUT(KeyADDR, %11111111) 'Sends output command to PCF chip
KeyNum:=0 'Zero out the previous value
KeyPressed:=0 'Zero out local variable
Repeat until KeyPressed==1 'Keep repeating the loop until a key is pressed
'could use UNTIL BitPattern, but then any non zero value would be valid.
fds.tx(cls) 'Clear the PST screen
BitPattern := IO.IN(KeyAddr) 'Determine the bit pattern
case BitPattern 'For various bit pattern cases, determine a value of the key being pressed.
%1000_1000 : KeyNum := 1
KeyPressed := 1
%1000_0100 : KeyNum := 2
KeyPressed := 1
%1000_0010 : KeyNum := 3
KeyPressed := 1
%1000_0001 : KeyNum := 100 'This is the A Key
KeyPressed := 1
%0100_1000 : KeyNum := 4
KeyPressed := 1
%0100_0100 : KeyNum := 5
KeyPressed := 1
%0100_0010 : KeyNum := 6
KeyPressed := 1
%0100_0001 : KeyNum := 200 'This is the B Key
KeyPressed := 1
%0010_1000 : KeyNum := 7
KeyPressed := 1
%0010_0100 : KeyNum := 8
KeyPressed := 1
%0010_0010 : KeyNum := 9
KeyPressed := 1
%0010_0001 : KeyNum := 300 'This is the C Key
KeyPressed := 1
%0001_1000 : KeyNum := 600 'This is the * Key
KeyPressed := 1
%0001_0100 : KeyNum := 0
KeyPressed := 1
%0001_0010 : KeyNum := 500 'This is the # Key
KeyPressed := 1
%0001_0001 : KeyNum := 400 'This is the D Key
KeyPressed := 1
fds.str(string(13,"The BitPattern is: ")) 'Displaying various results
fds.bin(BitPattern,8)
fds.str(string(13,"The BitPattern as decimal is: "))
fds.dec(BitPattern)
fds.str(string(13, "The KeyNumber is: "))
fds.dec(KeyNum)
fds.str(string(13, "The current Total is: "))
fds.dec(KeyTotal)
waitcnt(clkfreq/2 + cnt)
IF KeyNum <10
KeyTotal:=(KeyTotal*10)+KeyNum 'The intent here is to convert 1-2-3-# into 123(one hundred twenty three)
IF KeyNum == 600
KeyTotal:=KeyTotal/10 'This acts as a backspace
result:=KeyTotal
fds.str(string(13, "The Final value is: ")) 'Display the end result
fds.dec(Result)
Pub Blink_LED
Dira[3]~~
Repeat 6
! Outa[3]
waitcnt(clkfreq/2+cnt)

Comments
Glad you like the board!
Paul