Main Site Documentation

Button debouncing


#1

I am having a button debouncing issue. I have tried Button module, I have tried my own button using InterruptPort(with internal and external resistor, with and without cap, with enabled and disabled glitch filter).


Sub ButtonP(ByVal sender As Button, ByVal state As Button.ButtonState) Handles button.ButtonPressed
	Debug.Print(state & " " & DateTime.Now)
	button.TurnLEDOn()
End Sub

Sub ButtonR(ByVal sender As Button, ByVal state As Button.ButtonState) Handles button.ButtonReleased
	Debug.Print(state & " " & DateTime.Now)
	button.TurnLEDOff()
End Sub

Result:

I expect it to be a nice sequence of 1 0 1 0 1 0 …


#2

Show the complete code with the glitch filter setting so we can test and reply on this.


#3

You can try my provided code with Button module. You should see if debouncing issue is there by pressing button at different speeds.

[line]

Test case 1
External button with debouncing cap and pull resistor.


Private WithEvents Button As New InterruptPort(Pin.P0_16, False, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth)

Sub Button_OnInterrupt(port As UInteger, state As UInteger, time As Date) Handles Button.OnInterrupt
    Debug.Print(state & " " & time)
End Sub

Slow:

Fast:

[line]

I have also tried and got similar results with these:


Private WithEvents Button As New InterruptPort(Pin.P0_16, True, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth)


Private WithEvents Button As New InterruptPort(Pin.P0_16, True, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth)


#4

debug.print is slow. try very slow press and release.


#5

as Mike said Debug.Print is slow… try tracking your clicks with a variable…

cheers,
Jay


#6
  1. WHAT? :open_mouth: [em]Debug.Print[/em] is not printing all the requested data, you cannot trust it. That is just crazy. Is there any to fix that? I want to see every [em]Debug.Print[/em] no matter what is happening.
    I am not getting all 300 values printed in my Immediate Window:

For i = 1 To 300
	Debug.Print(i.ToString())
Next

  1. Leaving [em]Debug.Print[/em] apart, how can you explain that this code still shows the presence of debouncing issue:

Dim MyList As New ArrayList
Dim WithEvents MyTimer As New Timer(15000)

Public Sub ProgramStarted()
	MyTimer.Start()
	Debug.Print("Program Started")
End Sub

Sub ButtonP(ByVal sender As Button, ByVal state As Button.ButtonState) Handles button.ButtonPressed
	MyList.Add(state & " " & DateTime.Now)
End Sub

Sub ButtonR(ByVal sender As Button, ByVal state As Button.ButtonState) Handles button.ButtonReleased
	MyList.Add(state & " " & DateTime.Now)
End Sub

Private Sub MyTimer_Tick(timer As Timer) Handles MyTimer.Tick
	For i = 0 To MyList.Count - 1
		Debug.Print(MyList(i).ToString())
	Next
End Sub

  1. Even in the simplest form it is not working as expected (not every press is registered):

Sub ButtonP(ByVal sender As Button, ByVal state As Button.ButtonState) Handles button.ButtonPressed
   button.TurnLEDOn()
End Sub

Sub ButtonR(ByVal sender As Button, ByVal state As Button.ButtonState) Handles button.ButtonReleased
   button.TurnLEDOff()
End Sub


#7

Bump.


#8

Hi IAMIN,

Is there any reason (ie hi processor demands, or timing issues), that you can’t simply manually filter out the dbouncing issues.
I may not be using the correct convention with the “exit sub”, as most of my programming is done to solve a problem. Open to suggestions of a more elegant solution from others on the forum.

ie

Dim btnStatus As Boolean = False

Sub ButtonP(ByVal sender As Button, ByVal state As Button.ButtonState) Handles Button.ButtonPressed
If btnStatus = True Then
Exit Sub
Else
btnStatus = True
End If
Debug.Print(state & " " & DateTime.Now)
Button.TurnLEDOn()
End Sub

    Sub ButtonR(ByVal sender As Button, ByVal state As Button.ButtonState) Handles Button.ButtonReleased
        If btnStatus = False Then
            Exit Sub
        Else
            btnStatus = False
        End If
        Debug.Print(state & " " & DateTime.Now)
        button.TurnLEDOff()
    End Sub

I also agree that the “Debug.Print” command tends to be of limited value when trying to stream large values of data, your better off to create an array, dump the values into it, then call a timer periodically, (ie, every few seconds, dump the array & start over). \

Also, another possibility, is if the debouncing is mechanical in nature, and the application isn’t required to respond immediately, you could possibly just put the thread to sleep for a few milliseconds to give the contact time to stop bouncing… Just a thought, but is application specific.

Michael.

[code=vb][/code