Debouncing an InterruptPort Input

Hi,

I have an issue with my hardware button connected to an InterruptPort of the FEZ Hydra. In prinicple it works, I do get the interrupt. But most of the time there are two interrupts when I press the button. This might be related to my poor hardware button, I don’t know…

Does anybody have the same issues? Can I solve them with a kind of debouce routine?
This is my initialization:

InterruptPort installedInterruptSwitch = new InterruptPort(FEZHydra.Pin.PC9, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh);

Thanks for your help!

its typically your switch, yes. Jack Ganssle has a great in-depth paper Debouncing Contacts and Switches but depending on your requirement and sensitivity, you can do lots of simple thing to address it in your handler.

1 Like

@ tester56723 - Sometimes you may need to adjust the NetMF supported glitch filter by running this line of code:



This is the global glitch filter and changes the default time span of the filter (I'm not sure what is the default filter setting).
1 Like

Use an input abstraction that lets you set the debounce period independently per pin, especially if you emulate any protocols in software.

The glitch filter did not work for me. No effect at all…

Now I use both the rising edge and falling edge interrupt to determine when a button was pressed. This works great. The strange thing here is that I always get two interrupts independent of the settings…

@ tester56723 - I have reported the exact same behavior some time ago. So you are not alone :wink: https://www.ghielectronics.com/community/forum/topic?id=15385

Just yesterday I had the button report multiple presses until I enabled the glitch filter then it started working correctly.

@ Gus - Did a test just a few minutes ago.

Dim myList As New ArrayList
Dim WithEvents button As New InterruptPort(DirectCast(24, Cpu.Pin), True, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth)

Sub Main()
	Cpu.GlitchFilterTime = New TimeSpan(0, 0, 0, 0, 100)
	Debug.Print("Ready")
	Thread.Sleep(-1)
End Sub

Private Sub button_OnInterrupt(port As UInteger, state As UInteger, time As Date) Handles button.OnInterrupt
	myList.Add(state & " " & time)
	If myList.Count = 50 Then
		button.DisableInterrupt()
		For i = 0 To myList.Count - 1
			Debug.Print(myList(i).ToString())
		Next
	End If
End Sub

[quote]0 06/01/2011 01:01:08
1 06/01/2011 01:01:08
1 06/01/2011 01:01:08
1 06/01/2011 01:01:09
1 06/01/2011 01:01:09
1 06/01/2011 01:01:09
1 06/01/2011 01:01:10
1 06/01/2011 01:01:10
1 06/01/2011 01:01:10
1 06/01/2011 01:01:11
1 06/01/2011 01:01:11
1 06/01/2011 01:01:11
1 06/01/2011 01:01:12
1 06/01/2011 01:01:12
1 06/01/2011 01:01:13
1 06/01/2011 01:01:13
1 06/01/2011 01:01:13
1 06/01/2011 01:01:14
1 06/01/2011 01:01:14
0 06/01/2011 01:01:14
1 06/01/2011 01:01:15
1 06/01/2011 01:01:16
1 06/01/2011 01:01:17
1 06/01/2011 01:01:17
1 06/01/2011 01:01:18
1 06/01/2011 01:01:19
1 06/01/2011 01:01:19
1 06/01/2011 01:01:19
1 06/01/2011 01:01:20
1 06/01/2011 01:01:20
1 06/01/2011 01:01:21
1 06/01/2011 01:01:21
1 06/01/2011 01:01:21
1 06/01/2011 01:01:22
1 06/01/2011 01:01:23
1 06/01/2011 01:01:23
1 06/01/2011 01:01:24
0 06/01/2011 01:01:25
1 06/01/2011 01:01:25
1 06/01/2011 01:01:25
1 06/01/2011 01:01:26
1 06/01/2011 01:01:27
1 06/01/2011 01:01:27
1 06/01/2011 01:01:27
1 06/01/2011 01:01:28
1 06/01/2011 01:01:28
1 06/01/2011 01:01:28
1 06/01/2011 01:01:29
1 06/01/2011 01:01:30
1 06/01/2011 01:01:31[/quote]

:’(

@ iamin - I do not think the glitch filter works with double edge. I think that was always the case. Do you see it with a single edge?

Then it is a drawback.

No. But that does not explain why in double edge mode we get multiple 1s or 0s in a row. Isn’t that supposed to be strictly 1010101010…10101010 sequence?

UPDATE: I found this explanation on MSDN: “Level interrupts, which are either InterruptEdgeLevelHigh or InterruptEdgeLevelLow interrupts, are dispatched when the value on a pin matches the specified high value or low value, respectively. The system dispatches [em]only the first occurrence of a level interrupt[/em] until it is cleared by means of the ClearInterrupt method. With nonlevel interrupts, [em]every specified edge is dispatched[/em].”

I wonder why level interrupts are still not supported by GHI hardware :think:

@ Aron - default value for GlitchFilterTime is 7.68 ms: Cpu.GlitchFilterTime Property (Microsoft.SPOT.Hardware) | Microsoft Learn

@ iamin - I will dig into this later.

1 Like

@ iamin - Just to be sure before we test, does the most recent code you posted still show that behavior in the latest pre-release?

@ John - Yes.

@ iamin - I wasn’t able to reproduce it in the handful of tests I tried using your exact code. Even if I disabled the glitch filter, I didn’t get any duplicates. What does your hardware setup look like?

@ John - Cobra II + Button module connected to port #4.

Code:

Public Module Module1
	Dim myList As New ArrayList
	Dim WithEvents button As New InterruptPort(DirectCast(25, Cpu.Pin), True, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth)

	Sub Main()
		Cpu.GlitchFilterTime = New TimeSpan(0, 0, 0, 0, 100)
		Debug.Print("Ready")
		Thread.Sleep(-1)
	End Sub

	Private Sub button_OnInterrupt(port As UInteger, state As UInteger, time As Date) Handles button.OnInterrupt
		myList.Add(state & " " & time)
		If myList.Count = 50 Then
			button.DisableInterrupt()
			For i = 0 To myList.Count - 1
				Debug.Print(myList(i).ToString())
			Next
		End If
	End Sub
End Module

Result:

[quote]Ready
0 06/01/2011 00:07:18
1 06/01/2011 00:07:19
0 06/01/2011 00:07:19
1 06/01/2011 00:07:19
0 06/01/2011 00:07:19
1 06/01/2011 00:07:19
1 06/01/2011 00:07:20
1 06/01/2011 00:07:20
1 06/01/2011 00:07:20
0 06/01/2011 00:07:20
1 06/01/2011 00:07:20
0 06/01/2011 00:07:21
1 06/01/2011 00:07:21
0 06/01/2011 00:07:21
0 06/01/2011 00:07:21
0 06/01/2011 00:07:21
1 06/01/2011 00:07:21
0 06/01/2011 00:07:22
1 06/01/2011 00:07:22
0 06/01/2011 00:07:22
1 06/01/2011 00:07:22
0 06/01/2011 00:07:23
1 06/01/2011 00:07:24
1 06/01/2011 00:07:24
0 06/01/2011 00:07:24
1 06/01/2011 00:07:25
0 06/01/2011 00:07:25
1 06/01/2011 00:07:26
0 06/01/2011 00:07:27
1 06/01/2011 00:07:28
0 06/01/2011 00:07:28
0 06/01/2011 00:07:28
0 06/01/2011 00:07:28
0 06/01/2011 00:07:28
0 06/01/2011 00:07:29
0 06/01/2011 00:07:29
0 06/01/2011 00:07:29
1 06/01/2011 00:07:29
0 06/01/2011 00:07:30
1 06/01/2011 00:07:30
1 06/01/2011 00:07:30
1 06/01/2011 00:07:30
1 06/01/2011 00:07:31
0 06/01/2011 00:07:31
1 06/01/2011 00:07:31
0 06/01/2011 00:07:31
1 06/01/2011 00:07:31
0 06/01/2011 00:07:32
1 06/01/2011 00:07:32
0 06/01/2011 00:07:32
[/quote]

@ iamin - I was able to reproduce it on the Cobra II, we will take a look.

@ iamin - This should be improved for the next SDK on the G120.

1 Like

If you really want to get rid of button noise you should connect a flip flop or latch ( Q output) to the interrupt line and use a form C contact tied to the direct set and direct reset inputs of the latch/flip flop.

1 Like

Thanks for that! I had to learn more and found this video that explains the circuit nicely.

1 Like

@ Cowboy, @ ianlee74 - you are talking about hardware debouncing and I am talking about software debouncing. I prefer the later one.