4x4
KEYPAD
CONTROLLER
P1 4x4 Keypad
 

This project uses a 4x4 keypad to control 4 remote devices. It will control up to 16 devices but our micro will only allow up to 4 devices.
Keypads are available from many different manufacturers and some are available as a kit. See the range on eBay where the prices are the lowest and postage is FREE.
The items we have chosen to switch ON and OFF are: a LED, globe, piezo buzzer and motor.
Only the first 4 keys are used and they toggle each item ON and OFF.
To make the project more-compact, you can reduce the keys to 4 and only fit the 47k resistors. The keys are 1, 2, 3 and 4 and when you are initially programming the key-values into EEPROM, you simply push 1, 2, 3, 4 and repeat key 4 until the LED flashes.
The keys toggle each item and this allows 4 items to be controlled via two wires.
We are limited to 4 items as we are using a very small 8-pin micro with 5 outputs. One output is already used for the keypad .
This project is another in our series MAKE YOUR OWN CHIPS where we show how to write a program for a microcontroller and produce a project using a single 8-pin micro to take the place of a number of regular IC’s.
You need to refer to our previous project 4x4 Keypad to see how it can be connected to a microcontroller via a single line (plus 0v rail). This project provides an application where a number of keys are needed to provide data for a project – such as an alarm, game or data collection.
Once you have studied the keypad detection program in the previous project, you are ready to add sub-routines to toggle 4 of the outputs.
 


4x4 keypad connected to a microcontroller and controlling 4 devices


The interface board using surface-mount components


The interface board using through-hole components


The wiring viewed from top


The 4 Devices controlled by the 4x4 Keypad

SOLVING PROGRAMMING PROBLEMS
One of the problems with this type of project is inference from the devices being turned ON and OFF. As more devices are activated, the supply voltage will alter and this will change the timing for the keypad detection.
To keep the voltage on the keypad timing absolutely stable, we have introduced three features.
 -The voltage to the chip is regulated by a 5v regulator.
- The voltage on the timing capacitor cannot rise above 4v7 due to the 4v7 zener and
- thirdly, the output of the chip is momentarily turned off during the timing so the load on the port (the 220R resistors to the base of the driver transistors) does not alter the detection-point for the input-line GP5.
Keys 1,2, 3 and 4 have been chosen because they require the longest timing and any fault with the timing will be most-pronounced because these keys have the highest number of timing-loops.
Even though the timing for a key may be 15h loops, it may be actually 14.1 loops and a slight change in the value of the timing capacitor may create a result of 14 loops. To cover this possibility, the program looks at 14 loops, 15 loops and 16 loops. This gives a small degree of variation or tolerance to make the program more reliable.

 GOING FURTHER
This project can be extended to provide all sorts of communication-features via "two lines."
You can toggle 2 devices ON and OFF by using separate keys.
You can also provide timing for a device to turn it on for a period of time via one of the keys or a different time by using another key.
You can use two outputs to control a motor in forward-reverse via an "H-Bridge."

 

INSTRUCTIONS TO SET THE KEY-VALUES
Turn the project OFF.
Push key16 and keep pressed.
Turn ON project.
Release key16.
Push key1  - LED will flash briefly
Push key2 to key16. slowly
 - LED will flash briefly
after key 16, LED will flash ON-OFF-ON-OFF
Key-values are now in EEPROM.
Turn project OFF
Turn Project ON. Push key1 and LED will turn ON
Push key 2 and globe will turn ON
Push key 3 and piezo buzzer will sound
Push key 4 and motor will turn ON.
Push 1 - 4 and the device will turn OFF.

The files:
4x4KeyPadController.asm
4x4KeyPadController.txt
4x4KeyPadController.hex

		
;*******************************
;4x4 KeypadController.asm
;
;4x4 keypad connected to 4 devices
;  22-7-2013 
;*******************************


	list	p=12F629
	radix	dec
	include	"p12f629.inc"
	
	errorlevel -302	; Dont complain about BANK 1 Registers during assembly

	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  

;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin 

;****************************************************************
; variables - names and files
;****************************************************************

		Cblock  20h
temp1		;used in delays
temp2		;used in delays
temp3		;used in delays
temp4           ;used to generate key value
temp16          ;16 keys
flashes		;LED flashes to indicate key number
loops 
SwFlags      

        endc

;****************************************************************
;Equates
;****************************************************************
status		equ	0x03
rp1		equ	0x06
rp0		equ	0x05
GPIO 		equ 	0x05
			

status		equ	03h
option_reg	equ 	81h


		; bits on GPIO
				
pin7		equ	0	;GP0  LED - flashes to indicate key number
pin6	 	equ	1	;GP1  Relay
pin5		equ	2	;GP2  Piezo Buzzer 
pin4		equ	3	;GP3  not used
pin3		equ	4	;GP4  Motor
pin2		equ	5	;GP5  4x4 Keypad switches   
 

		;bits
				
rp0		equ	5	;bit 5 of the status register



;****************************************************************
;Beginning of program
;****************************************************************
	org	0x00
	nop
	nop
	nop
	nop
	nop			
SetUp	bsf	status, rp0 	;Bank 1			
       	movlw	b'11001000'	;Set TRIS GP0,1,2,4,5 out   GP3 not used
	movwf	TRISIO	
	bcf	status, rp0	;bank 0
	movlw   07h         	;turn off Comparator ports
        movwf   CMCON       	;must be placed in bank 0  
	clrf 	GPIO       	;Clear GPIO of junk - turn off all devices	
	movlw	4Fh             ;start of GPR's
	movwf	fsr
	call    NoKey           ;see if a switch is pressed
	btfss   SwFlags,1       ;test bit1 for switch pressed
	goto    SetUp2          ;load 50h to 5Fh from EEPROM
	call    GenKeyvalue     ;to see if key16 is pressed before start-up.
	movlw   0CFh             ;Put a value into W and perform SUBWF
	subwf   loops,1         ;Carry flag is CLEAR if W is greater than file value 
        btfsc   03,c            ;Test carry flag 
	goto    SetUp2		
	movlw   .16
	movwf   temp16          ;for 16 keys
		
	call    NoKey           ;test bit1 for switch pressed 
	btfsc   SwFlags,1       ;detect no key pressed for debounce	
	goto    $-2             ;
	bsf     gpio,0          ;Key not pressed - flash LED briefly
	call    _10mS
	bcf     gpio,0
	call    _10mS
		
	call    NoKey           ;test bit1 for switch pressed 
	btfss   SwFlags,1       ;detect key pressed for debounce	
	goto    $-2
			
	call    GenKeyvalue     ;Key pressed  - get number of loops 
					
    	incf	fsr,f	        ;fsr starts at file 50h   Store 16 key-values
	movf    loops,w         ;move number of loops into w
	movwf	indf	        ;put loops into file 50h to 5Fh
	decfsz	temp16,f
	goto    $-.15
		
	call    toEEPROM        ;put 16 values into EEPROM
		
	bsf     gpio,0          
	call    _500mS
	bcf     gpio,0
	call    _500mS
	goto    $-4            ;keeps flashing - turn off project        
		
		 

         ;load files 50h to 5Fh with key values from EEPROM
         

SetUp2  
	bsf	status,rp0	;select bank1	
	clrf	eeadr		;start EEPROM at location 0
	bcf	status,rp0	;select bank0		
	movlw   .16
	movwf   temp16      	;for 16 keys
	movlw	4Fh         	;start of GPR's
	movwf	fsr
	incf	fsr,f	    	;fsr starts at file 50h	
	bsf	status,rp0							
	bsf	EECON1,0	;starts EEPROM read operation  - result in EEDATA
	movf	EEDATA,w	;move read data into w
	bcf	status,rp0				
	movwf	indf	    	;put EEPROM data into file 50h to 5Fh
	bsf	status,rp0	;select bank1	
	incf	eeadr,1						
	bcf	status,rp0	;select bank0
	decfsz	temp16,f
	goto	$-.10
	goto    Main		
		

;********************
;* Delays 	    *
;********************

_uS     movlw   7h
        movwf   temp1
	decfsz 	temp1,f
        goto 	$-1			
	retlw 	00
		
		
		
_10mS	movlw	0Ah
	movwf	temp2
_10	nop
	decfsz 	temp1,f
	goto 	_10
	decfsz 	temp2,f
	goto 	_10	
	retlw 	00		
		


_100mS	movlw	.100
	movwf	temp2
_100	nop
	decfsz 	temp1,f
	goto 	_100
	decfsz 	temp2,f
	goto 	_100	
	retlw 	00	
		
		

		
_500mS	movlw   5			
	movwf   temp3
	call	_100mS		
	decfsz  temp3,1
	goto    $-2
	retlw   00

;****************************
;* Sub Routines 	    *
;****************************
	
	
Device1
	movlw 	01h
        xorwf   gpio,1  ;XOR 01 with gpio, lowest line (GP0) 
        retlw   00      ;toggles line gpio,0
	
Device2
	movlw 	02h
        xorwf   gpio,1  ;XOR 01 with gpio, lowest line (GP1) 
        retlw   00    ;toggles line gpio,1

Device3
	movlw 	04h
        xorwf   gpio,1  ;XOR 01 with gpio, lowest line (GP2) 
        retlw   00    ;toggles line gpio,2

Device4
	movlw 	10h
        xorwf   gpio,1  ;XOR 01 with gpio, lowest line (GP4) 
        retlw   00    ;toggles line gpio,4

	
	
  
        ;detect key16 at start-up to generate key-loops for storage in EEPROM
	    ;this sub-routine also detects a pressed-key and
	    ;returns with a value in "loops"
			
GenKeyvalue				
	clrf    loops      	
	bsf	status, rp0 	;Bank 1	    	
	bcf 	TRISIO,5	;clear bit GPIO,5 as output to charge cap.
	bcf	status, rp0	;bank 0
	bsf	gpio,5		;make pin2 HIGH to charge cap. 
	call	_10mS           ;charge cap	
	call	_10mS           ;charge cap	
	call	_10mS           ;charge cap	
			
	bsf	status, rp0 	;Bank 1			
       	bsf 	TRISIO,5	;set TRIS GP0,5 to detect discharged cap
	bcf	status, rp0	;bank 0	
	movf    gpio,w
	movwf   temp3
	clrf    gpio            ;turn off outputs while detecting	
	call	_uS		
	incf    loops,1
	btfsc   gpio,5
	goto	$-3  
	movf    temp3,w
	movwf   gpio            ;re-instate output port         
	retlw   00              ;return with value in loops
	
	
	;Key_Yes returns SwFlags,7 when file 50h to 5Fh is correct key 
	;temp4 will already contain file 50h to 5Fh
	;GenKeyvalue  generates current loops value and compares with
	;files 50h to 5Fh
		
		
Key_Yes		
	bcf     SwFlags,7
	call    GenKeyvalue     ;value of key in loops
	movf    loops,w         ;put loops into w
	xorwf   temp4,w
	btfsc   03,z
	goto    bb              ;key found
	incf    temp4,f         ;try one value higher
	movf    loops,w         ;put loops into w again
	xorwf   temp4,w
	btfsc   03,z
	goto    bb 
	decf    temp4,f         ;try one value lower
	decf    temp4,f  
	movf    loops,w         ;put loops into w again
	xorwf   temp4,w
	btfss   03,z
	retlw   00              ;key not found		
bb	bsf     SwFlags,7
        retlw   00


		
		
		
		
	;NoKey - detect no key pressed 
	
	
NoKey	bcf     SwFlags,1
	bsf	status, rp0 	;Bank 1	 (see if switch is pressed)    	
	bcf 	TRISIO,5	;clear bit GPIO,5 as output to charge cap.
	bcf	status, rp0	;bank 0
	bsf	gpio,5		;make pin2 HIGH to charge cap. 
	call	_10mS           ;charge cap		
	bsf	status, rp0 	;Bank 1			
       	bsf 	TRISIO,5	;set TRIS GP0,5 to detect discharged cap
	bcf	status, rp0	;bank 0			
	call	_10mS		
	btfsc   gpio,5
        retlw	00		;no switch pressed
        bsf     SwFlags,1
	retlw	00	        key pressed - bsf SwFlags,1
		
		
	;ShowKey shows the key value via LED flashes
ShowKey		
	bsf     gpio,0          ;
	call    _500mS
	bcf     gpio,0
	call    _500mS
	decfsz  flashes,1
	goto    $-5            ;
	goto    Main
		
		
	;TestKeys is a test routine that flashes the key number
		
TestKeys

        clrf    loops
        clrf    flashes
        movlw	50h             ;start of GPR's
	movwf 	fsr
aa     	incf    flashes,1
	call    GenKeyvalue     ;value of key in loops
	movf    indf,w          ;put contents of 50h into w
	movwf   temp4
	xorwf   loops,w
	btfsc   03,z
	goto    ShowKey	        ;flashes = 1
	decf    temp4,f          ;try one value less
	movf    temp4,w
	xorwf   loops,w
	btfsc   03,z
	goto    ShowKey	        ;flashes = 1
	incf    temp4,f          ;try one value higher
	incf    temp4,f 
	movf    temp4,w
	xorwf   loops,w
	btfsc   03,z
	goto    ShowKey
	incf    fsr		
	movlw   16
	xorwf   flashes,w
	btfsc   03,z
	goto    aa
	retlw   00
			
		    
		
	;after 16 keys  . . . .
	;put number of loops in 50h to 5Fh into EEPROM	
				
		
toEEPROM
	bsf	status,rp0	;select bank1	
	clrf	eeadr		;start EEPROM at location 0	
	bcf	status,rp0	;select bank0		
	movlw   .16
	movwf   temp16      	;for 16 keys
	movlw	4Fh         	;start of GPR's
	movwf	fsr
	incf	fsr,f	    	;fsr starts at file 50h
	movf	indf,w	    	;retreive data in file 50h to5Fh
	bsf	status,rp0	;select bank1	
	movwf	eedata		; 
	bcf	status,rp0	;select bank0
	call 	write
	bsf	status,rp0	;select bank1	
	incf	eeadr,1						
	bcf	status,rp0	;select bank0
	decfsz	temp16,f
	goto	$-10
	retlw   00
		
		
write	bsf	status,rp0	;select bank1	
	bsf	eecon1,wren	;enable write		
	movlw	55h 		;unlock codes
	movwf	eecon2
	movlw	0aah
	movwf	eecon2
	bsf	eecon1,wr	;write begins
	bcf	status,rp0	;select bank0		
writeA	btfss	pir1,eeif	;wait for write to complete
	goto	writeA
	bcf	pir1,eeif
	bsf	status,rp0	;select bank1
	bcf	eecon1,wren	;disable other writes
	bcf	status,rp0	;select bank0	
	retlw	00			
		
	

;************************************
;* Main 			    *
;************************************

Main	
	call    NoKey           ;test SwFlags,1 for switch pressed 
	btfss   SwFlags,1       ;detect key pressed for debounce	
	goto    $-2				;key not pressed
	
	movf    50h,w           ;is key 1 pressed?
	movwf   temp4	        ;set-up temp4 for Key_Yes 
	call    Key_Yes
	btfsc   SwFlags,7 
	call    Device1		;LED	
				
		
	movf    51h,w           ;is key 2 pressed?
	movwf   temp4	        ;set-up temp4 for Key_Yes 
	call    Key_Yes
	btfsc   SwFlags,7 
	call    Device2		;globe	
		
		
	movf    52h,w           ;is key 3 pressed?
	movwf   temp4	        ;set-up temp4 for Key_Yes 
	call    Key_Yes
	btfsc   SwFlags,7 
	call    Device3		;piezo buzzer	
	
	movf    53h,w           ;is key 4 pressed?
	movwf   temp4	        ;set-up temp4 for Key_Yes 
	call    Key_Yes
	btfsc   SwFlags,7 
	call    Device4		;motor	
	call    NoKey           ;test bit1 for switch pressed 
	btfsc   SwFlags,1       ;detect key pressed for debounce	
	goto    $-2				;key  pressed		
		
	goto    Main            
	      
	   	    
		
;****************************************************************
;*EEPROM     						*
;****************************************************************
								
	org		2100h	;16 locations 00 to 0F		
							
					
							
		END		



ooo00000oooo

22-7-2013