Shop OBEX P1 Docs P2 Docs Learn Events
How to: Get multiple digits using PCF8574 and 4x4 Keypad — Parallax Forums

How to: Get multiple digits using PCF8574 and 4x4 Keypad

SteveWoodroughSteveWoodrough Posts: 190
edited 2013-03-10 16:48 in General Discussion
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. I’m 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, it’s 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

Sign In or Register to comment.