The Button module sometimes fires the wrong event, 1 out of 10. I investigated the problem and I could reproduce it using a very simple program using just the FEZ Spider II and a Button module.
When I press the button the LED will sometimes not turn on, and when I release the button the LED will sometimes not turn off. I used ILSpy to investigate “NETMF 4.3\GTM.GHIElectronics.Button.dll” assembly to see what the Button class does and there is a interrupt handler that calls this:
this.input.Read()
The value is used to handle switching the LED and calling the ButtonPressed and ButtinReleased event, which is sometimes incorrect. When I implement a timer that calls button.Pressed property, the value seems OK. Almost seems like a sequence problem where the button state is stored after the interrupt is fired?
I used FEZ Config 4.3.8.1 to update both the Loader (TinyBooter) and the firmware (TinyCLR) to version 4.3.8.1.
I started with two buttons on the FEZ Spider II and they had the same behavior. I also tried different ports. Same behavior. Then I used one of the buttons on the FEZ Reaper where I didn’t have the problem.
the button driver code is doing something I do not recommend.
There is a delay between the occurrence of an interrupt and its appearance at the interrupt handler. The event queue thread handling causes this delay.
the driver is reading the live value of the input port, instead of using the bool value passed to the interrupt handler, which is the input value which caused the interrupt. this can result in a race condition, and unexpected results.
with a faster cpu a problem is less likely to occur.
The contacts of a mechanical switch bounce when they are triggered/released. An interrupt will catch the initial change of state but the actual input signal will alternate between hi/low several times before settling. If you read the state of the input right after the interrupt is generated you have a good chance of reading the bounce.
Generally for a mechanical switch you want to denounce the signal, wait about 10ms after the interrupt to read the switch state and compare to the original interrupt state. If they match it is a good input, if they don’t it was noise.
I noticed on my switch module that there is a spot for a capacitor. This may have been included for some analog filtering of the signal.
@ njbuch - interrupts and the event queue is a subject that used come up a lot. at my age I remember technical tidbits but have no idea when I learned them…
I tried it and it solved triggering the wrong event. But now I notice that 1 out of 20 button presses, an event pair (both ButtonPressed and ButtonReleased) is also missing. (And thus also no LED switching). The code change is still an improvement, I think, because it prevents receiving the wrong events.
I did some extra testing. I polled for the Pressed property and it does registers the button press, when there are no events. Also tried two buttons and different ports. All the same behavior. Then I also used the Joystick and its JoystickPressed and JoystickReleased events. It has the same behavior as the buttons. To be sure, I also tested with the original button driver and there also an event pair is missing occasionally (I just didn’t notice it previously).
@ Bas van der Linden - Good that its moving forward. Every year when this topic comes up again someone links to this: [url]http://www.eng.utah.edu/~cs5780/debouncing.pdf[/url] which might give you some hints as to what is going on.
I discovered that G120/MF4.3 sometimes misses external interrupts. In my application the external interrupt is generated by an 8 bit micro controller and i could easily create a work around by generating a number of pulses. But of coarse thats not possible with just a simple button ???