PIC Microcontroler based Keyboards

4x4 Keypad with 1 A/D pin:

Dennis Crawley says:

The diagram below shows how this can be done, by connecting the row/column lines of the keypad to resistors so that each key (the X's in the diagram below) results in a different resistance value. This resistance is connected, along with a load resistor (the 22K shown below), in a voltage divider between Vcc and ground; each key gives a different voltage, thus a different A/D reading.

Observations:

  1. It requires 1% resistors, but it could be tested with normal 20% tolerance.
  2. It's very stable with voltage fluctuations.
  3. Since keyboards come with some resistance 80-100 ohms, and they tend to grow, the soft need some calibration as well as keyboard change over the time,...

Basically, the program transmit each key pressed to a terminal, so the programmer can see the key real value. Once he/she *calibrate* the range the pic is ready to use.

;**********************************************
        LIST    P=PIC16F873,F=INHX8M,R=DEC
        #INCLUDE P16F873.INC
        __CONFIG _HS_OSC&_WDT_OFF&_CP_OFF&_PWRTE_ON&_BODEN_ON&_LVP_OFF
        ERRORLEVEL 1,-302
;**********************************************
;Fosc 16Mhz
;First commented on PicList by Dave Dilatush
;Sat, 9 Feb 2002 20:43:39 GMT                                   
;Re: [PIC]: CHALLENGE: 4x4 keyboard and LCD with 1 port = 8 bits
;
;  X-------X-------X-------X----------+--Vcc      
;  |       |       |       |          |           
;  |       |       |       |          |           
;  X-------X-------X-------X---4.7K---+           
;  |       |       |       |          |           
;  |       |       |       |          |           
;  X-------X-------X-------X---10K----+           
;  |       |       |       |          |           
;  |       |       |       |          |           
;  X-------X-------X-------X---15K----+           
;  |       |       |       |                      
;  |     1.2K    2.4K    3.6K                     
;  |       |       |       |                      
;  +-------+-------+-------+--> To PIC A/D Input  
;                          |                      
;                         22K                     
;                          |                      
;                         GND                     
;
         CBLOCK 0X070            ;
BUFFER                           ;
LOOPS                            ;
LOOPS2                           ;
NIBBLE1                          ;
NIBBLE2                          ;
NIBBLE3                          ;
FILTER1                          ;
FILTER2                          ;
FILTER3                          ;
VECES                            ;
BUFFERKEY                        ;
        ENDC                     ;


        ORG     00               ;
        GOTO    INIT             ;
                                 ;
;Delay. @4Mhz-1ms.
RETARDO                          ;
        MOVWF   LOOPS            ;
TOP2    MOVLW   D'110'           ;
        MOVWF   LOOPS2           ;
TOP     NOP                      ;
        NOP                      ;
        NOP                      ;
        NOP                      ;
        NOP                      ;
        NOP                      ;
        DECFSZ  LOOPS2           ;
        GOTO    TOP              ;
        DECFSZ  LOOPS            ;
        GOTO    TOP2             ;
        RETURN                   ;

;ADC                                 
CONVER  BSF     ADCON0,GO        ;
CONSU   BTFSC   ADCON0,GO        ;
        GOTO    CONSU            ;
        RETURN                   ;
                                 
;Resistors and  Keys Resistances 
;may vary over the time 
;so we established ranges for
;each converted value with:
;addlw 255 - Hi                  
;addlw (Hi - Lo) + 1             
;for a good explanation go to:
;http://www.piclist.com/techref/microchip/rangechk.htm
;********************************;
PARSER                           ;
       CLRF   BUFFERKEY          ;Split de hexa into
       MOVLW  .3                 ;two nibbles. Test for
       XORWF  FILTER1,W          ;Hi nibble, If = 3
       BTFSS STATUS,Z            ;Test the low nibble
       GOTO   TWO                ;otherwise jump.
;3FC ---> real value got it from TOASCII routine                      
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X0FE        ;
       ADDLW  (0X0FE - 0X0E8)+1  ;
       MOVLW  "1"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;3C4                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X0C8        ;
       ADDLW  (0X0C8 - 0X0BF)+1  ;
       MOVLW  "2"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;39E                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X0A2        ;
       ADDLW  (0X0A2 - 0X09A)+1  ;
       MOVLW  "3"                ;
       BTFSC  STATUS,C           ;
       GOTO   SAVEKEY            ;
;363                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X067        ;
       ADDLW  (0X067 - 0X05E)+1  ;
       MOVLW  "S"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;345                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X049        ;
       ADDLW  (0X049 - 0X041)+1  ;
       MOVLW  "4"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;31F                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X023        ;
       ADDLW  (0X023 - 0X01B)+1  ;
       MOVLW  "5"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;305                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X09         ;
       ADDLW  (0X009 - 0X01)+1   ;
       MOVLW  "6"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;

TWO                              ;Values with hi nibble
                                 ;equal to 2
;2DB 
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X0E1        ;
       ADDLW  (0X0E1 - 0XD7)+1   ;
       MOVLW  "U"                ;U for UP
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;2BE
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X0C2        ;
       ADDLW  (0X0C2 - 0XBA)+1   ;
       MOVLW  "7"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;2A3
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X0A7        ;
       ADDLW  (0X0A7 - 0X9F)+1   ;
       MOVLW  "8"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;28E  
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X092        ;
       ADDLW  (0X092 - 0X8A)+1   ;
       MOVLW  "9"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;271                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X075        ;
       ADDLW  (0X075 - 0X06D)+1  ;
       MOVLW  "D"                ;D for Down
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;25C                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X060        ;
       ADDLW  (0X060 - 0X058)+1  ;
       MOVLW  "P"                ;P for Program
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;248                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X04C        ;
       ADDLW  (0X04C - 0X044)+1  ;
       MOVLW  "0"                ;
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;238                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X03C        ;
       ADDLW  (0X03C - 0X34)+1   ;
       MOVLW  "B"                ;B for Backspace
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;
;222                       
       MOVFW  FILTER2            ;
       ADDLW  255 - 0X026        ;
       ADDLW  (0X026 - 0X1E)+1   ;
       MOVLW  "E"                ;E for Enter
       BTFSC STATUS,C            ;
       GOTO   SAVEKEY            ;

KEYBERROR2                       ;If some keys have      
       MOVLW  "#"                ;changed their values   
SAVEKEY                          ;the soft could handled 
       MOVWF  BUFFERKEY          ;the error              
       RETURN                    ;

;********************************;
TOASCII                          ;When is active,
        MOVF    FILTER1,W        ;this routine take the
        MOVWF   NIBBLE1          ;hex value and convert it
        MOVLW   30H              ;into three ascii values
        ADDWF   NIBBLE1          ;Basically check for
                                 ;ABCDEF1234567890
        MOVF    FILTER2,W        ;
        MOVWF   BUFFER           ;
        ANDLW   0FH              ;
        MOVWF   NIBBLE3          ;
        MOVLW   0AH              ;
        SUBWF   NIBBLE3,0        ;
        MOVLW   37H              ;
        BTFSS   STATUS,C         ;
        MOVLW   30H              ;
        ADDWF   NIBBLE3          ;
        SWAPF   BUFFER,0         ;
        ANDLW   0FH              ;
        MOVWF   NIBBLE2          ;
        MOVLW   0AH              ;
        SUBWF   NIBBLE2,0        ;
        MOVLW   37H              ;
        BTFSS   STATUS,C         ;
        MOVLW   30H              ;
        ADDWF   NIBBLE2          ;
        RETURN                   ;

;********************************;This routine add
FILTRO  CLRF    FILTER1          ;the converted value
        CLRF    FILTER2          ;into 3 registers.
        CLRF    FILTER3          ;256 times.
        CLRF    VECES            ;then divide by 256
REPEAT                           ;ignoring filter3.
        CALL    CONVER           ;ex:for 3FB 
        BSF     STATUS,RP0       ;filter1=0x003
        MOVF    ADRESL,W         ;filter2=0x0fb
        BCF     STATUS,RP0       ;
        ADDWF   FILTER3,1        ;
        BTFSS   STATUS,C         ;
        GOTO    FILT2            ;
        MOVLW   D'1'             ;
        ADDWF   FILTER2,1        ;
        BTFSS   STATUS,C         ;
        GOTO    FILT2            ;
        MOVLW   D'1'             ;
        ADDWF   FILTER1,1        ;
FILT2                            ;
        MOVF    ADRESH,W         ;
        ADDWF   FILTER2,1        ;
        BTFSC   STATUS,C         ;
        INCF    FILTER1          ;
        DECFSZ  VECES,1          ;
        GOTO    REPEAT           ;
                                 ;
        RETURN                   ;
                                 ;
                                 ;
                                 ;
TRASMI  BTFSS   PIR1,TXIF        ;
        GOTO    TRASMI           ;
        MOVWF   TXREG            ;
        NOP                      ;
TRASMI2 BTFSS   PIR1,TXIF        ;last bit is sent
        GOTO    TRASMI2          ;
        RETURN                   ;


;Main
INIT    BSF     STATUS,RP0       ;
        MOVLW   0FFH             ;
        MOVWF   TRISA            ;
        MOVWF   TRISB            ;
        MOVLW   B'11111111'      ;
        MOVWF   TRISC            ;
        MOVLW   B'00100110'      ;
        MOVWF   TXSTA            ;
        MOVLW   D'103'           ;16mhz crystal
        MOVWF   SPBRG            ;9600bps. If 4mhz is used,
        MOVLW   B'10000010'      ;change spbrg to (dec)25
        MOVWF   ADCON1           ;
        BCF     STATUS,RP0       ;
        MOVLW   B'10000001'      ;Fosc/32
        MOVWF   ADCON0           ;
        BSF     PIR1,TXIF        ;
        BCF     PIR1,RCIF        ;
        MOVLW   B'10010000'      ;
        MOVWF   RCSTA            ;
                                 ;
        MOVLW   "T"              ;welcom screen on pc
        CALL    TRASMI           ;
        MOVLW   "X"              ;
        CALL    TRASMI           ;
        MOVLW   " "              ;
        CALL    TRASMI           ;
        MOVLW   "O"              ;
        CALL    TRASMI           ;
        MOVLW   "K"              ;
        CALL    TRASMI           ;
        MOVLW   D'13'            ;
        CALL    TRASMI           ;
        MOVLW   D'10'            ;
        CALL    TRASMI           ;
                                 ;
                                 ;
CICLO                            ;
        CALL    FILTRO           ;check for pushed keys
        MOVLW   2                ;> than 2 in filter1
        SUBWF   FILTER1,W        ;
        BTFSS   STATUS,C         ;
        GOTO    CICLO            ;
                                 ;
        MOVLW   .83              ;almost 20 ms. 
        CALL    RETARDO          ;if 4mhz is used,
        CLRF    VECES            ;change to (dec)20
        CALL    FILTRO           ;
        MOVLW   2                ;
        SUBWF   FILTER1,W        ;
        BTFSS   STATUS,C         ;
        GOTO    CICLO            ;
;        CALL    TOASCII         ;un-comment this to see the 
        CALL    PARSER           ;key real value, so range can
RELEASE                          ;be adjusted
        CALL    FILTRO           ;check if key was released
        MOVLW   0X02             ;
        SUBWF   FILTER1,W        ;
        BC     RELEASE           ;
                                 ;
        MOVLW   ":"              ;
        CALL    TRASMI           ;
        MOVFW   BUFFERKEY        ;
        CALL    TRASMI           ;
;        MOVFW   NIBBLE1         ;un-comment to send keys
;        CALL    TRASMI          ;values to pc screen
;        MOVFW   NIBBLE2         ;
;        CALL    TRASMI          ;
;        MOVFW   NIBBLE3         ;
;        CALL    TRASMI          ;
        MOVLW   D'13'            ;
        CALL    TRASMI           ;
        MOVLW   D'10'            ;
        CALL    TRASMI           ;
                                 ;
        GOTO    CICLO            ;
                                 ;
        END

See also:

Comments: