Main Site Documentation

Glitch Filter and Cpu.GlitchFilterTime - testing and optimising with hardware


#1

Hi there,

does anyone have any pointers on testing and optimising bounce behaviour of mechanical switches?

I know based on Ganssle’s testing (ref http://www.ganssle.com/debouncing.pdf) that the mechanical switch bounce time can vary greatly, so even though I nominally have 3x switches of the same manufacturer I can expect a variation.

Perhaps part of my understanding gap is what the expected interrupt behaviour should be as I vary the Cpu.GlitchFilterTime. Let me explain my setup.

I am using the following code to set up the interrupt and handler:
InterruptPort KeyDigitalUp = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di0, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
KeyDigitalUp.OnInterrupt += new NativeEventHandler(pushbutton_OnInterrupt);

I have a simple momentary contact pushbutton switch with a pulldown resistor connected to the IO port. My handler is currently processing 3 switches and using a switch/case for picking which one to do and then setting flags and altering values (hopefully minimal processing, although i am doing string handling at the moment while debugging - bad I know - but it’s only doing debug.print of a string value at the moment).

Often times, I’ll see the handler invoked twice in a row with the same state value of 1 (in my case that’s the key pressed state). I can’t really get my mind around what that might be - is it a distinct bounce between de-glitch reads, perhaps the 2nd interrupt fires (on trailing edge) and the handler doesn’t get the right state value? Does anyone have any other alternatives on what might happen there? I don’t see a single push generate 4 interrupts (ie a classic bounce situation) but I do see this “state doesn’t change” a lot.

If I change the Cpu.GlitchFilterTime setting I’m assuming that the internal filter will require a signal to settle for at least the value of Cpu.GlitchFilterTime before signalling an interrupt, is that correct? I’ve tried testing by altering the Cpu.GlitchFilterTime between 5 and 20 ms, even tried in the 200-500 range as well - this double-signal of state=1 has not really reduced.

thoughts, guidance, or a lifeline appreciated !


#2

Not sure what is happening but you can help glitches by adding a capacitor on the pin


#3

I think glitchfilter does not work correctly with interrupts on both edges, you need to specify high or low only.


#4

Would you suggest a more reliable edge interrupt to use? InterruptEdgeLevelHigh or InterruptEdgeHigh? Are either more suitable for use on real-hardware push-button type arrangements?


#5

You need to use edge interrupts, level interrupts are currently not supported.


#6

What I am wondering about is why you leave your interrupt port floating with this Port.ResistorMode.Disabled Wouldn’t it be better to pull the port to a known state?


#7

because

[quote]
I have a simple momentary contact pushbutton switch with a pulldown resistor connected to the IO port.[/quote]
so it is in a known state :slight_smile:


#8

Sorry Brett, I did not see that :slight_smile:
But for the sake of argument, have you tried setting the ResistorMode to pulldown?


#9

:slight_smile:

yeah i have.

To recap my original issue:
When using InterruptEdgeBoth, I was seeing consecutive iterations through the device handler that were signalling STATE=1.

I never intended to use InterruptEdgeBoth, I was simply testing; I only care about one interrupt on keypress (key release doesn’t matter).

I’m now using:
InterruptPort KeyDigitalUp = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di0, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeHigh);

and

       Cpu.GlitchFilterTime = new TimeSpan(0,0,0,0,50);

Now I see some other things I can’t explain. I do occasionally see double-interrupts on a single button press. So I’m now back to tuning glitch filter time to make those less evident (I don’t have o-scope to look more at the signal pattern)

Mike, kind of a repeat question for ya if I may.

How exactly does the glitch filter work - specifically, with the above setting, does it require the edge to be stable for 50msec before the interrupt will fire? If I change that to 500msec, does it need half a second of it being pressed before it’ll fire?

I ask because when I try with 500msec in the filter time, it works pretty well at getting rid of all double interrupts, especially those when you quickly press the button - I would have expected some of those presses to be ignored if the 500msec needed to be stable, since I’m sure there’s enough jitter on the button that would stop that. In fact, I suspect it’s more like “it needs to be at the chosen level for more than 50% of the time” to trigger the interrupt, since when I bumped the time to 900msec I would often miss the quicker press/release signals.

The other thing that is interesting with this quite large time setting (which isn’t that sustainable in general) is that the time I see an interrupt fire unexpectedly is when releasing the button from a longer press & hold.

test code below… wire up a button and press & hold for 2 secs then release, I get
20 1 01/01/2009 00:07:14 // the first interrupt as pressed
20 1 01/01/2009 00:07:16 // a trailing interrupt on release


    public class Program
    {
        public static void Main()
        {
            Cpu.GlitchFilterTime = new TimeSpan(0, 0, 0, 0, 900);
            InterruptPort KeyDigitalUp = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di0, true, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeHigh);
            KeyDigitalUp.OnInterrupt += new NativeEventHandler(pushbutton_OnInterrupt);
            Thread.Sleep(Timeout.Infinite);
        }
        static void pushbutton_OnInterrupt(uint port, uint state, DateTime time)
        {
            Debug.Print(" " + port + " " + state + " " + time);
        }

Time to go back to Ganssle to find a hardware solution :slight_smile:


#10

Have you tried a different switch?


#11

I wonder if microsoft.spot is also monitoring this pin… It used by them as one of the default buttons?

I would explain the ghosting of an interrupt!!

Just a thought… may be wrong.

Cheers Ian


#12

Most button applications use a pullup resistor, and pull the signal to ground when pressed.

Can you try that and see what happens?


#13

I have the same issue, but I need InterruptEdgeBoth. I tried various sized caps and all sorts of time spans for the filter, but I still get the double handler events fired and often the wrong pin state is registered. Has anyone had this issue and overcome it yet?

I am using a unique magnetic micro switch that is pretty “bouncy”, but nothing I would think a decent filter can’t sort out.

Intersting note: When I disable the glitch filter I get multiple interrupts (no surprise) so I can see the bounce of the switch, but at least the state is registered accurately and consistently. With the filter on I will almost always get the wrong pin state when the event handler is fired.

Looks like I may need to write my own filter?

-AP


#14

I had similar problems, so I decided to write my own glitch filter. It doesn’t use interupts though.


#15

Glitch filter is not supported on EdgeBoth.


#16

That answers it.

So I could just use 2 pins and set one for EdgeLow and the EdgeHigh and use the built-in glitch filter right?

-AP


#17

Yes that can be an option