How to: Get multiple digits using PCF8574 and 4x4 Keypad
SteveWoodrough
Posts: 190
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