PicBasic Pro, PicBasic, BASIC Stamp, Microchip PIC, 8051, and Remote Control Projects

CROSS-POINT SWITCH INTERFACE
by: Bill Whitehead  whw-pjw@worldnet.att.net  c2002

Cross-point switches are easily connected to computers and are available in several configurations. Typically they are arranged in columns and rows as 3X4 or 4X4 matrices. Pressing a switch makes a connection between a row and a column.

EIGHT WIRE KEYBOARD INTERFACE

Easily the most popular cross-point switch interface uses eight terminals on the computer chip. The recognition program puts a signal on each "input" in turn and looks for the signal on each of the four "outputs". Programming is straight-forward and simple, but it does require eight pins on the chip. (See code example below.)


Circuit by: Bill Whitehead  whw-pjw@worldnet.att.net  c2002

FOUR WIRE KEYBOARD INTERFACE

This interface requires eight additional diodes and more complex programming to decode the key press, but requires only four input/output pins. The recognition program puts a signal on each "input" in turn and looks for the signal on all of the other three "outputs". The program is longer than the eight-wire program, but saves the entire "C" register for other uses. (See code example below.)

The Code

'************************************************
'*  Name    : kp_8.BAS                          *
'*  Author  : Bill Whitehead                    *
'*  Notice  : Copyright (c) 2002 by FlexEd      *
'*          : All Rights Reserved               *
'*  Date    : 4/11/2002                         *
'*  Version : 1.0                               *
'*  Notes   : configured for 4X20 LCD.          *
'*             (uses ~700 words)                *
'*     Generic for 4X4 crosspoint switch        *
'*     utilizing 8 pins.                        *
'************************************************
DEFINE ONINT_USED 1'required to save space for bootloader
'Include "modedefs.bas"   'required to include definitions
'set parameters for keypress:
    kp       VAR BYTE                  'define a variable
    kpx      VAR BYTE                  'define a variable
    kp1      VAR BYTE                  'define a variable
'   kp2      var byte                  'define a variable

'set parameters for other lcd's
'(use only to deviate from norm)
    DEFINE  LCD_DREG    PORTB
    DEFINE  LCD_DBIT    4
    DEFINE  LCD_RSREG   PORTB
    DEFINE  LCD_RSBIT   2
    DEFINE  LCD_EREG    PORTB
    DEFINE  LCD_EBIT    3
'    DEFINE  LCD_RWREG  PORTB
'    DEFINE LCD_RWBIT   2
'    DEFINE LCD_BITS    4
'    DEFINE LCD_LINES   4
'    DEFINE LCD_COMMAND 2000
'    DEFINE LCD_DATA    50
'for 4-line LCD:
    'start of line 1:  LCDOUT 254,128,etc...147
    'start of line 2:  LCDOUT 254,192,etc...206
    'start of line 3:  LCDOUT 254,148,etc...167
    'start of line 4:  LCDOUT 254,212,etc...231
'for 2-line LCD:
    'start of line 1:  LCDOUT 254,128,etc...151
    'start of line 2:  LCDOUT 254,192,etc...215  
'***************************************************
start:
    LCDOUT $FE, 1                               'clear LCD
    PAUSE 100                              'let LCD settle
    kp=16
    kp1=0
    kpx=0
      LCDOUT 254,128,"welcome to key press"
      PAUSE 100
main:
    GOSUB key_press8  
    IF kpx<>0 THEN LCDOUT 254,128,"key ",#kpx," was pressed    "
    IF kp<>16 THEN LCDOUT 254,148,"number= ",#kp,"   "
    PAUSE 100
    GOTO main
END
'************************************************
key_press8:
    kp1=0                                 'preset variable                   
    kpx=0                                 'preset variable                   
    trisb= %11110000         'set PORTb, 1=input, 0=output
    trisc= %00000000         'set PORTc, 1=input, 0=output
'column 4
     portc=%01110000                   'put "0" on portC.7
     kp1=(portb&%11110000)/16
     IF kp1=7 THEN kpx=4
     IF kp1=11 THEN kpx=8
     IF kp1=13 THEN kpx=12
     IF kp1=14 THEN kpx=16
     IF kp1<>15 THEN GOTO debounce
'column 3
     portc=%10110000                   'put "0" on portC.6
     kp1=(portb&%11110000)/16
     IF kp1=7 THEN kpx=3
     IF kp1=11 THEN kpx=7
     IF kp1=13 THEN kpx=11
     IF kp1=14 THEN kpx=15
     IF kp1<>15 THEN GOTO debounce
'column 2      
     portc=%11010000                   'put "0" on portC.5
     kp1=(portb&%11110000)/16
     IF kp1=7 THEN kpx=2
     IF kp1=11 THEN kpx=6
     IF kp1=13 THEN kpx=10
     IF kp1=14 THEN kpx=14
     IF kp1<>15 THEN GOTO debounce
'column 1
     portc=%11100000                   'put "0" on portC.4
     kp1=(portb&%11110000)/16
     IF kp1=7 THEN kpx=1
     IF kp1=11 THEN kpx=5
     IF kp1=13 THEN kpx=9
     IF kp1=14 THEN kpx=13
     IF kp1<>15 THEN GOTO debounce
     GOTO kp_exit
'bail out
 debounce:
    IF portb.7=0 THEN GOTO debounce
    IF portb.6=0 THEN GOTO debounce
    IF portb.5=0 THEN GOTO debounce
    IF portb.4=0 THEN GOTO debounce    
'FOR ACT or GRAYHILL switch use:
      LOOKUP kpx,[16,1,4,7,13,2,5,8,0,3,6,9,14,10,11,12,15],kp
'FOR VELLEMAN switch use:
'      lookup kpx,[16,1,2,3,10,4,5,6,11,7,8,9,12,13,0,14,15],kp
kp_exit:
    RETURN
'*********************************************************



'************************************************
'*  Name    : kp_4.BAS                          *
'*  Author  : Bill Whitehead                    *
'*  Notice  : Copyright (c) 2002 by FlexEd      *
'*          : All Rights Reserved               *
'*  Date    : 4/12/2002                         *
'*  Version : 1.0                               *
'*  Notes   : configured for 4X20 LCD.          *
'*             (uses ~1000 words)               *
'*     Program to cycle crosspoint switch       *
'*              and 4-wire adapter.             *
'*     Configured to run on portb.7654          *
'************************************************

DEFINE ONINT_USED 1     'required to save space for bootloader
'set parameters for keypress1:
    kp       VAR BYTE                       'define a variable
    kpx      VAR BYTE                       'define a variable
    kp1      VAR BYTE
    kp2      VAR BYTE                       'define a variable
    q0       VAR portb.4                    'define a variable
    q1       VAR portb.5                    'define a variable
    q2       VAR portb.6                    'define a variable
    q3       VAR portb.7                    'define a variable
'set parameters for LCD
    '(use only to deviate from norm)
    DEFINE  LCD_DREG    PORTB
    DEFINE  LCD_DBIT    4
    DEFINE  LCD_RSREG   PORTB
    DEFINE  LCD_RSBIT   2
    DEFINE  LCD_EREG    PORTB
    DEFINE  LCD_EBIT    3
'    DEFINE  LCD_RWREG  PORTB
'    DEFINE LCD_RWBIT   2
'    DEFINE LCD_BITS    4
'    DEFINE LCD_LINES   4
'    DEFINE LCD_COMMAND 2000
'    DEFINE LCD_DATA    50
'for 4-line LCD:
    'start of line 1:  LCDOUT 254,128,etc...147
    'start of line 2:  LCDOUT 254,192,etc...206
    'start of line 3:  LCDOUT 254,148,etc...167
    'start of line 4:  LCDOUT 254,212,etc...231
'for 2-line LCD:
    'start of line 1:  LCDOUT 254,128,etc...151
    'start of line 2:  LCDOUT 254,192,etc...215  
'***************************************************
start:
    LCDOUT $FE, 1                                   'clear LCD
    PAUSE 100                                  'let LCD settle
    kp1=0
    kpx=0
      LCDOUT 254,128,"welcome to key press"
      PAUSE 100
'***************************************************
main:
    GOSUB key_press4
    IF kpx<>0 THEN LCDOUT 254,128,"key ",#kpx," was pressed    "
    IF kp<>16 THEN LCDOUT 254,148,"number= ",#kp,"   "
    PAUSE 100
    GOTO main
END
'************************************************
key_press4:
  kp1=0                                        'preset variable
  kpx=0                                        'preset variable
    trisb= %11100000              'set PORTB, 1=input, 0=output
      q0=0                                       'set Q0 to "0"
      PAUSE 1                                'let system settle
      kp1=(q1*2)+(q2*4)+(q3*8)       'calculate keypress
      IF kp1<>14 THEN GOTO kp_row1             'is key pressed?
    trisb= %11010000              'set PORTB, 1=input, 0=output
      q1=0                                       'set Q1 to "0"
      PAUSE 1                                'let system settle
      kp1=(q0*1)+(q2*4)+(q3*8)              'calculate keypress
      IF kp1<>13 THEN GOTO kp_row2             'is key pressed?
    trisb= %10110000              'set PORTB, 1=input, 0=output
      q2=0                                       'set Q2 to "0"
      PAUSE 1                                'let system settle
      kp1=(q0*1)+(q1*2)+(q3*8)              'calculate keypress
      IF kp1<>11 THEN GOTO kp_row3             'is key pressed?
    trisb= %01110000              'set PORTB, 1=input, 0=output
      q3=0                                       'set Q3 to "0"
      PAUSE 1                                'let system settle
      kp1=(q0*1)+(q1*2)+(q2*4)              'calculate keypress
      IF kp1<>7 THEN GOTO kp_row4              'is key pressed?
    GOTO kp_return                   'if key released, continue
  kp_row1:
    IF kp1=12 THEN kpx=16             'configure for key number
    IF kp1=8  THEN kpx=15             'configure for key number
    IF kp1=2  THEN kpx=14             'configure for key number
    IF kp1=6  THEN kpx=13             'configure for key number
      row1_l00p:
      kp2=(q0*1)+(q1*2)+(q2*4)+(q3*8)       'calculate keypress    
      IF kp2<>14 THEN GOTO row1_l00p           'is key pressed?    
    GOTO kp_return                   'if key released, continue
  kp_row2:
    IF kp1=12 THEN kpx=12             'configure for key number
    IF kp1=9  THEN kpx=11             'configure for key number
    IF kp1=1  THEN kpx=10             'configure for key number
    IF kp1=4  THEN kpx=9              'configure for key number
      row2_l00p:
      kp2=(q0*1)+(q1*2)+(q2*4)+(q3*8)       'calculate keypress
      IF kp2<>13 THEN GOTO row2_l00p           'is key pressed?
    GOTO kp_return                   'if key released, continue
  kp_row3:
    IF kp1=8  THEN kpx=8              'configure for key number
    IF kp1=9  THEN kpx=7              'configure for key number
    IF kp1=3  THEN kpx=6              'configure for key number
    IF kp1=2  THEN kpx=5              'configure for key number
      row3_l00p:
      kp2=(q0*1)+(q1*2)+(q2*4)+(q3*8)       'calculate keypress
      IF kp2<>11 THEN GOTO row3_l00p           'is key pressed?
    GOTO kp_return                   'if key released, continue
  kp_row4:
    IF kp1=4  THEN kpx=4              'configure for key number
    IF kp1=1  THEN kpx=3              'configure for key number
    IF kp1=3  THEN kpx=2              'configure for key number
    IF kp1=6  THEN kpx=1              'configure for key number
      row4_l00p:
      kp2=(q0*1)+(q1*2)+(q2*4)+(q3*8)       'calculate keypress
      IF kp2<>7 THEN GOTO row4_l00p            'is key pressed?
  kp_return:
                           'convert keypress to match keyboard:
                                'use this for ACT and GRAYHILL:
' lookup kpx,[16,1,4,7,13,2,5,8,0,3,6,9,14,10,11,12,15],kp  
                                        'use this for VELLEMAN:
  LOOKUP kpx,[16,1,2,3,10,4,5,6,11,7,8,9,12,13,0,14,15],kp  
  RETURN                           'go back to original program
'************************************************

For questions concerning this project - please contact: by: Bill Whitehead  whw-pjw@worldnet.att.net

Until the next project - have fun - and don't blow anything up...;o]

Regards,

-Bruce


Back to the PicBasic Projects Section

Copyright © 1999-2008 Reynolds Electronics

| Contact Information |