+ Reply to Thread
Results 1 to 8 of 8

Thread: Vertical Counters for keyboard debouncing.

  1. #1
    Help us help you blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent blueroomelectronics Excellent
    Join Date
    Jan 2007
    Location
    Toronto, Canada
    Posts
    10,711
    Blog Entries
    5

    Default Vertical Counters for keyboard debouncing.

    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.
    Vertical Counters with a PIC

    I've yet to use the vertical method myself but thought it would make good food for thought.
    Bill
    Smart Kits build Smart People

    http://www.blueroomelectronics.com/


  2. #2
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,815

    Default

    Quote Originally Posted by blueroomelectronics View Post
    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.
    Vertical Counters with a PIC

    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.

    Mike.

  3. #3
    Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent Mike, K8LH Excellent
    Join Date
    Jan 2005
    Location
    Michigan, USA
    Posts
    2,522

    Default

    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

  4. #4
    August Treubig Good August Treubig Good
    Join Date
    Nov 2007
    Location
    Arkansas
    Posts
    94

    Smile Code I sent you

    Bill,

    Go look at the push button code that I sent you. It uses Scott's code.


    August
    August Treubig
    AG5AT

  5. #5
    dave_b Newbie
    Join Date
    Feb 2009
    Posts
    1

    Default

    Quote Originally Posted by Pommie View Post
    ...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!)

  6. #6
    Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent Pommie Excellent
    Join Date
    Mar 2005
    Location
    Brisbane Australia
    Posts
    6,815

    Default

    Quote Originally Posted by dave_b View Post
    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.

  7. #7
    Gayan Soyza Excellent Gayan Soyza Excellent Gayan Soyza Excellent Gayan Soyza Excellent Gayan Soyza Excellent Gayan Soyza Excellent
    Join Date
    Oct 2006
    Location
    Colombo
    Posts
    1,664
    Blog Entries
    1

    Default

    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 by Gayan Soyza; 9th March 2009 at 06:15 AM.

  8. #8
    atferrari Good atferrari Good atferrari Good
    Join Date
    Oct 2003
    Location
    Buenos Aires - Argentina
    Posts
    573

    Default What difference it actually makes?

    Quote Originally Posted by Pommie View Post
    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?

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

    Intrigued.
    Last edited by atferrari; 10th March 2009 at 09:30 AM. Reason: Omitted a word.
    Agustín Tomás
    In theory, there is no difference between theory and practice. In practice, however, there is.

+ Reply to Thread

Similar Threads

  1. Lateral vs. Vertical Mosfet construction
    By speakerguy79 in forum General Electronics Chat
    Replies: 1
    Latest: 28th May 2008, 02:35 AM
  2. debouncing??
    By Bavananth in forum Electronic Projects Design/Ideas/Reviews
    Replies: 12
    Latest: 11th May 2008, 03:18 PM
  3. Simple Coax Antenna Gain & Vertical Bandwidth
    By Nutmegzzzz in forum General Electronics Chat
    Replies: 6
    Latest: 28th December 2007, 08:27 PM
  4. LCD Vertical Scrolling with PIC16F877A
    By jinchang in forum Micro Controllers
    Replies: 13
    Latest: 2nd June 2007, 04:03 PM
  5. IC testing, how can I tell if vertical IC is bad?
    By Robert Morris in forum General Electronics Chat
    Replies: 6
    Latest: 23rd October 2003, 03:55 PM

Tags for this Thread