Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Vertical Counters for keyboard debouncing.

Status
Not open for further replies.

blueroomelectronics

Well-Known Member
After reading Pommies excellent post on a 2 key roll-over keyboard with RS232 out, I thought it would be interesting to post a link to vertical counters for keyboard denouncing as opposed to time delay denouncing.
**broken link removed**

I've yet to use the vertical method myself but thought it would make good food for thought.
 
After reading Pommies excellent post on a 2 key roll-over keyboard with RS232 out, I thought it would be interesting to post a link to vertical counters for keyboard denouncing as opposed to time delay denouncing.
**broken link removed**

I've yet to use the vertical method myself but thought it would make good food for thought.

I hate time delay debounce, vertical counters is time delay debounce and the worst kind, the kind that has a delay after the button is pressed. The beauty of the way I do debounce is that when a button is pressed it is immediately acted upon and not after some debounce delay. I have buttons in my car that are debounced using a delay, I can press them fast enough that they don't register. You can't do that with the code I posted. clicky.

For anyone not familiar with the method I use, it is rather simple, if the button wasn't pressed 10mS ago and is now pressed then it's registered as a new key press. It effectively detects rising edges.

BTW, I've never denounced anyone.:D

Mike.
 
Variations of Scott Dattalo's method of using vertical counters as eight independent debounce timers provide amazing and extremely versatile parallel switch debounce/management solutions. The time and effort it takes to understand vertical counters and parallel switch state logic is a good investment.

For example, here's Scott's basic 2 bit vertical counter debounce code with a few additional instructions for parallel switch state management that provides a pretty complete interrupt driven debounce solution for up to eight switches using only 14 words of program memory;

Code:
;
; Scott Dattalo's debounce method for up to 8 switches uses a 2
; bit vertical counter as eight independent debounce timers.  A
; few instructions have been added for parallel switch state
; management.
;
; a switch is "debounced" (both press and release states) when it
; has been sampled four times at the same state spanning a 24 msec
; period (using 8 msec sampling intervals).
;
; vcbit1 ^= vcbit0;             // inc counters (unconditionally)
; vcbit0 = ~vcbit0;             //
; vcmask = ~portb ^ slatch;     // changes (press or release)
; vcbit0 &= vcmask;             // clear inactive counters
; vcbit1 &= vcmask;             //
; vcmask = ~vcmask;             // check for timed-out counters
; vcmask |= vcbit0;             //
; vcmask |= vcbit1;             //
; vcmask = ~vcmask;             // any 1's are timed-out counters
; slatch ^= vcmask;             // update debounced switch state
; vcmask &= slatch;             // filter out "new release" bits
; sflags ^= vcmask;             // update switch flags for Main
;
test_0                          ; 14 words
        movf    vcbit0,W        ; inc counters unconditionally    |B0
        xorwf   vcbit1,F        ; inc bit 1 vertical counter      |B0
        comf    vcbit0,F        ; inc bit 0 vertical counter      |B0
        comf    PORTB,W         ; sample active low switches      |B0
        xorwf   slatch,W        ; changes (press or release)      |B0
        andwf   vcbit0,F        ; clear inactive bit 0 counters   |B0
        andwf   vcbit1,F        ; clear inactive bit 1 counters   |B0
        xorlw   0xFF            ; check for timed-out counters    |B0
        iorwf   vcbit0,W        ;                                 |B0
        iorwf   vcbit1,W        ; any '0' is a timed-out counter  |B0
        xorlw   0xFF            ; any '1' is a new press/release  |B0
        xorwf   slatch,F        ; update debounced switch state   |B0
        andwf   slatch,W        ; filter out "new release" bits   |B0
;       skpz                    ; a "new press"? no, skip, else   |B0
;       bsf     beeper,5        ; task a "new press" beep         |B0
        xorwf   sflags,F        ; update switch flags for Main    |B0
;
This routine filters out the "new release" switch state and only passes on the "new press" switch state. Your Main program simply needs to test and clear a switch flag bit in the sflags variable for "momentary" type switches, or simply test a switch flag bit for momentary switches that you want to emulate a "toggle" switch (press the switch to toggle the flag bit from on-to-off or from off-to-on).

I should also mention that since the slatch variable contains the real-time debounced switch state (plus debounce delay), it's relatively easy to implement "repeat" key functionality on-the-fly as needed in Main using this variable. There are examples of this in my Charlie Clock in the Projects Forum where I use "repeat" key capability for the <up> and <down> arrow keys to adjust the hours, minutes, or seconds display group only when in "Set" mode. When in "Display" or "Run" mode the <up> and <down> arrow keys are used to select the display (Clk, Tmr, Cal, or display off) and the keys do not "repeat".

Have fun guys.

Mike
 
...vertical counters is time delay debounce and the worst kind, the kind that has a delay after the button is pressed. The beauty of the way I do debounce is that when a button is pressed it is immediately acted upon and not after some debounce delay.

So, you're not accounting for noise that could false trigger? I posed a similar solution a few years back (I think on the Piclist) and was told the delay was needed as part of that filtering process. In reality, I'm not sure how much of an issue it is.

Dave
(new guy, by the way. Hi everyone!)
 
So, you're not accounting for noise that could false trigger? I posed a similar solution a few years back (I think on the Piclist) and was told the delay was needed as part of that filtering process. In reality, I'm not sure how much of an issue it is.

Dave
(new guy, by the way. Hi everyone!)

Hi Dave,

The way I deal with debounce is by only reading the keys every 10mS. I keep a copy of the previous reading and if the new reading says pressed and the old says released then a new key press has occurred. The only way key bounce can cause a double read is if the bounce last longer than 20mS which does not occur with anything better than a paper clip and thumb tack.

Nearly forgot, welcome to the forum.

Mike.
 
Vertical counter are awesome.I'm doing a vertical counter method in my 16 channel knight rider project to generate PWM function.

Code:
_PWM_Update        
		movfw	L_VC0           ; AND all lower 5 bits of vertical counter
              	andwf   L_VC1,W
              	andwf   L_VC2,W
              	andwf   L_VC3,W
              	andwf   L_VC4,W
              	andwf   L_VC5,W
              	iorwf	copyPORTB,F   	; then OR bits with copyPORTB lower byte
              	;                                         	                                          	
		movf	H_VC0,W		; AND all higher 5 bits of vertical counter
		andwf	H_VC1,W
		andwf	H_VC2,W  
		andwf	H_VC3,W
		andwf	H_VC4,W  
		andwf	H_VC5,W  
		iorwf	copyPORTA,F	; then OR bits with copyPORTB higher byte
                ;
		movf	copyPORTA,W
		movwf	PORTA                  
		movf	copyPORTB,W    
		movwf	PORTB   
                ;                         		  
; ----------------------------------------
; Do 2^6 bit lower byte vertical counter
		;
_VC64		movf	L_VC4,W
		andwf	L_VC3,W
		andwf 	L_VC2,W
		andwf	L_VC1,W
		andwf	L_VC0,W
		xorwf	L_VC5,F
	        ;
		movf	L_VC3,W
		andwf	L_VC2,W
		andwf	L_VC1,W
		andwf	L_VC0,W
		xorwf	L_VC4,F
	        ;
		movf	L_VC2,W
		andwf	L_VC1,W
		andwf	L_VC0,W
		xorwf	L_VC3,F
	        ;	         
		movf	L_VC1,W
		andwf	L_VC0,W
		xorwf	L_VC2,F
	        ;
		movf	L_VC0,W
		xorwf	L_VC1,F
	        ;
		comf	L_VC0,F
		;
; ----------------------------------------
; Do 2^6 bit higher byte vertical counter
		;	         
	        movf	H_VC4,W
		andwf	H_VC3,W
		andwf 	H_VC2,W
		andwf	H_VC1,W
		andwf	H_VC0,W
		xorwf	H_VC5,F
	         ;
		movf	H_VC3,W
		andwf	H_VC2,W
		andwf	H_VC1,W
		andwf	H_VC0,W
		xorwf	H_VC4,F
	         ;
		movf	H_VC2,W
		andwf	H_VC1,W
		andwf	H_VC0,W
		xorwf	H_VC3,F
	         ;	         
		movf	H_VC1,W
		andwf	H_VC0,W
		xorwf	H_VC2,F
	         ;
		movf	H_VC0,W
		xorwf	H_VC1,F
	         ;
		comf	H_VC0,F
	        ;
; ---------------------------------------

              	decfsz  PWM_Count,F         	; decrement PWM counter
              	goto	Count_ISR     		; return if count != 0
              					; reset and reload PWM output / counter
              	movlw 	.63           		; reload PWM counter
              	movwf	PWM_Count              
              	clrf    copyPORTB     		; reset output port working variable
              	clrf	copyPORTA     		; reset output port working variable
           	;
              	movf	L_VC0_S,W
		movwf	L_VC0
		movf	L_VC0_S,W
		movwf	L_VC1
		movf	L_VC0_S,W
		movwf	L_VC2
		movf	L_VC0_S,W
		movwf	L_VC3
		movf	L_VC0_S,W
		movwf	L_VC4
		movf	L_VC0_S,W
		movwf	L_VC5
		;
		movf	H_VC0_S,W
		movwf	H_VC0
		movf	H_VC0_S,W
		movwf	H_VC1
		movf	H_VC0_S,W
		movwf	H_VC2
		movf	H_VC0_S,W
		movwf	H_VC3
		movf	H_VC0_S,W
		movwf	H_VC4
		movf	H_VC0_S,W
		movwf	H_VC5		
		;
Count_ISR	----
		----
 
Last edited:
What difference it actually makes?

I hate time delay debounce, vertical counters is time delay debounce and the worst kind, the kind that has a delay after the button is pressed.
Mike.

In actual use, what could you perceive, Pommie? :confused:

I use 25 ms since I started with this and I cannot say I feel any difference when pusshing any key.

Intrigued.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top