[CCC DEV] More on debounce - probable bug

Steve Pretty steve.g.pretty at btinternet.com
Wed Jan 26 23:11:50 GMT 2011


As you know, I was looking at plumbing debounce and suggested a change 
the other day.

Well, the reason I was looking at it was because I have been getting 
some unexpected results when using it.  I created an "instrumented" 
version of debug (i.e. stuffed it with print statements etc), and 
managed to capture an example of the problem:

0001   HIGH sent to out
0002   LOW sent to out   LOW was last int
0001   HIGH sent to out
0001   LOW sent to out
0001   HIGH sent to out
0002   HIGH sent to out   LOW was last int
0001   HIGH sent to out
0002   HIGH sent to out   LOW was last int
0001   HIGH sent to out
0001   LOW sent to out
0001   HIGH sent to out
0001   LOW sent to out
0001   HIGH sent to out
0001   LOW sent to out

The first number is the number of messages received on in? during a 
debounce.  A lot of the time it is 1 - which means no additional bounce 
interrupts occurred.  The line continues by saying what LEVEL was sent 
to out, and then if there were debounce messages, what was the last 
value received in? (i.e. the final value of your valuable any).

In the test I am pushing a buttton on pin 3, which lights LED on pin 13 
when pressed, and it should go out when the button is released. So what 
you should see is a simple HIGH LOW HIGH LOW . . . .   Well, in 
practice, that happens a lot of the time, but not always.  You can see 
that I actually got two presses in a row where I got HIGH HIGH HIGH HIGH 
HIGH.  Note in each case that the last int value received was the 
correct value.

I have experienced the problem with two different types of switch. 
Changing the length of the debounce timer has no effect.

Here is what I believe is happening. Then the button state changes, an 
interrupt is generated and digital.input gets called to handle it. It 
immediately does a digital.read. This LEVEL is then passed to debounce, 
and then on to the client. BUT the digital.read is happening immediately 
after the state change, when the signal will be most noisy - and we 
trust this reading and pass it on unchanged through debounce.  So 
basically, that means debounce does not work properly - all it is doing 
is ensuring there is a single message to the client about an event, 
rather than several.

Now, I suspect you have not experienced this problem, because as we have 
discussed, your current version of digital.input has a "feature" where 
it can only ever send HIGH - so debounce only ever sends HIGH - so no 
problem to see.

I have thought of three possible solutions:

1. Eliminate debounce at source - The input pins have schmitt trigger 
inputs, so one could add additional capacitor and resistor to the 
switch. Not too happy with this, as it adds to circuit complexity and it 
would be a bit of a black art to get just the right values!

2. Add a 50 ms delay into digital.input before doing the digital.read  - 
effectively doing the debounce in there.  Dont like that one - it rather 
specialises digital.input. What it I am connecting to a reliable digital 
input that needs a low latency response?

3. Take another look at debounce - I believe if a bounce does occur, we 
can be much more confident in accepting the LAST value received - which 
should reflect the final stable state of the button, than trusting that 
initial value.

I have now changed debounce to look like:

PROC debounce (CHAN LEVEL in?, out!)
   LEVEL v:
   WHILE TRUE
     TIMER tim:
     INT t:
     SEQ
       in ? v
       tim ? t
       t := t PLUS DEBOUNCE.TIME
       INITIAL BOOL ignoring IS TRUE:
       WHILE ignoring
         ALT
           in ? v
             SKIP
           tim ? AFTER t
             ignoring := FALSE
       out ! v
:

So the out is back at the end. the variable "any" has gone. If we do get 
a bounce message, it updates v, so that it is the last v received that 
is sent to out.

Tests on this approach look solid so far

(It is a shame that I will have to press my button an infinite number of 
times to be sure this new version of debounce never emits the wrong value!)


Regards

Steve








More information about the developers mailing list