Yet another switch debounce problem ...

joeyd999

Joined Jun 6, 2011
5,283
Last edited:

Thread Starter

cmartinez

Joined Jan 17, 2007
8,253
@cmartinez, everyone is going to disagree with me -- but you don't need to debounce a mechanical encoder. I've posted solutions that work here:

https://forum.allaboutcircuits.com/threads/another-pic-trick-quadrature-rotary-encoders.64318/

and here:

https://forum.allaboutcircuits.com/threads/pretty-good-weekend-effort.147311/post-1274688

Edit: The whole point of Gray Code is that only one bit switches (potentially with noise) at a time. A quadrature encoder has a two bit Gray coded output.
thank you very much for your help, Joey ... it's always thoroughly appreciated
 

olphart

Joined Sep 22, 2012
114
Ok, here's the code of what I intend to do. I haven't tested it yet, but the general idea is to use an Xor instruction to compare the current reading vs the previous one. If the readings were the same, the result will always be zero, if they were different then the result is non-zero. And when the latter happens, the sampling counter is reset back to its original value (in this case, 4) so as to start sampling anew. It is only when four identical readings in a row are made that the pin's state is considered to be stable and the sampling loop is exited.

Keep in mind that this code is running within the interrupt servicing routine.

Code:
          ;------------------------- START OF SWITCH DEBOUNCING CODE -------------------------
         
          ;at 32.768 kHz each instruction takes 0.0001220703125 to execute, so if
          ;we want to test for a 3ms stability, we need a cycle of at least 25 instructions
          ;while watching that pins ENC_A_PIN and ENC_B_PIN of PORTA have become stable
          
          ;first, seed ENC_SAMP_A with the current reading
          MovLf low  ENC_SAMP_A, FSR0L ;ENC_SAMP_A and ENC_SAMP_B lie in a different bank from
          MovLf high ENC_SAMP_A, FSR0H ;bank 0, that's why we're using an indirect pointer
         
          banksel PORTA                ;bank 0
          movf PORTA, w                ;load w with PORTA's current state
          andlw nENCODER_FILTER        ;filter only the two pertinent bits
          movwi 0[FSR0]                ;store the filtered reading in ENC_SAMP_A

          ;in the following loop, FSR1L will be used as a downcounter because its original value
          ;will be restored immediately after exiting this interrupt servicing routine, this because
          ;of the automatic context saving feature of the PIC16LF1825
          call Load_FSR1L_Downcounter  ;specify the number of equal samples in a row necessary to
Stability_Loop:                         ;qualify as a stable reading
            movf PORTA, w              ;load w with PORTA's current state
            andlw nENCODER_FILTER      ;filter only the two pertinent bits
            movwi 1[FSR0]              ;store the filtered value in ENC_SAMP_B (FSR0 is NOT incremented)
            xorwf INDF0, w             ;if this reading is different from the previous one, w will
            btfss STATUS, Z            ;result in a non-zero value
             call Load_FSR1L_Downcounter ;reset the downcounter if the two readings didn't match
            moviw 1[FSR0]              ;copy the current sample (ENC_SAMP_B) into
            movwi 0[FSR0]              ;ENC_SAMP_A for the next iteration
           decfsz FSR1L, f             ;decrement the downcounter
          goto Stability_Loop

          moviw 0[FSR0]                ;load w with the stable reading to continue with the analysis
         
          ;--------------------------- END OF SWITCH DEBOUNCE LOGIC --------------------------

I write a different ASM, so: what you have looks to be really half of a fully robust software debouncer.
Write the other half for the reverse situ, since you've done one, the opposite should be easy.
Gives you full control over all you'd want. G.H <<<)))
 

MisterBill2

Joined Jan 23, 2018
18,502
doing the debounce without any code is easy, if the encoder does not reverse. use two set/reset flipflops (CD4013) Each reed switch closure sets the one FF and resets the other one. so the number of bounces are all ignored until after the other reed switch closes. Use the "Q" outputs of the two FFs as "A" and "B". One IC that draws less than a mA at that speed.
 
Last edited:

Thread Starter

cmartinez

Joined Jan 17, 2007
8,253
I write a different ASM, so: what you have looks to be really half of a fully robust software debouncer.
Write the other half for the reverse situ, since you've done one, the opposite should be easy.
Gives you full control over all you'd want. G.H <<<)))
Would you mind elaborating what you mean by "the reverse situ" ?
 

MisterBill2

Joined Jan 23, 2018
18,502
It is indeed possible to do it in code. The first closure of switch "A" sets the "A" flag true and resets the "B" flag, the first closure of the "B" switch sets the "B" flag and resets the "A" flag. The first rising edge of the "A" input with the "B" input Low latches the "CW" flag and resets Rising edge of "A"while the "B" input is high sets the "CCW" flag and resets the "CW "flag.
This is based on the contact bounce time being less than the time between changes. Foe a system usin reed switches that is usualy the case.
 

olphart

Joined Sep 22, 2012
114
It is indeed possible to do it in code. The first closure of switch "A" sets the "A" flag true and resets the "B" flag, the first closure of the "B" switch sets the "B" flag and resets the "A" flag. The first rising edge of the "A" input with the "B" input Low latches the "CW" flag and resets Rising edge of "A"while the "B" input is high sets the "CCW" flag and resets the "CW "flag.
This is based on the contact bounce time being less than the time between changes. Foe a system usin reed switches that is usualy the case.
Yup, but I use count instead of flag. <count> number of same state samples is new stable state. <count> is enough that # samples > worst case bounce.
 

ThePanMan

Joined Mar 13, 2020
793
Does anybody make an oil filled reed switch containing a viscus oil? That would severely restrict the speed in which the switch could operate, but it would virtually eliminate bounce. No?
 

crutschow

Joined Mar 14, 2008
34,428
What sort of swtch bounces on opening?? I have never come across that before, except with really cheap junk switches.
My understanding is that any mechanical switch can bounce on opening, especially if it has a wiping action.
Do you have information that states otherwise?
 

MisterBill2

Joined Jan 23, 2018
18,502
Sliding switches with wiping-action contacts can have intermittent contact openings as they slide, but that is different from "contact bounce". So the mechanism for creating the momentary openings is rather different from the mechanism that causes contact bounce, although the effect may tend to be just as unwanted. And certainly the method of triggering on the first opening occurrence is still a valid solution. But it will be more complex to trigger on both opening and closing, and thus more effective to use a better quality switch.
 

MisterBill2

Joined Jan 23, 2018
18,502
The TS states in post #1 that the encoder uses reed switches that can not be replaced. The edge triggered flip flops will certainly work for those, and reed switches do not bounce on opening. That software approach should work as well if the TS is able to implement it. The FFs will certainly work at the speeds described, and possibly even with a small capacitance shunting the contacts.
 
Top