flyte / mqtt-io

Expose GPIO modules (Raspberry Pi, Beaglebone, PCF8754, PiFace2 etc.) and digital sensors (LM75 etc.) to an MQTT server for remote control and monitoring.
MIT License
465 stars 157 forks source link

Raspberry Pi GPIO interrupt debouncing not great #85

Open flyte opened 4 years ago

flyte commented 4 years ago

I've given the interrupts a test, and while they work, I get pretty bad bouncing on a simple switch (no hardware debouncing), which triggers the interrupt on almost every 'release' as well as each 'press'.

bounce

I've configured the software with interrupt: rising which should (and does) trigger when I press the button, however it also triggers quite often when I release the button. You can see why in the waveform above. The Pi's GPIO lib doesn't seem to be adequately protective of this, given that it should really discard the rising edge if it occurs within bouncetime of a falling edge.

I wonder if there's a neat way we can protect against this, which will work regardless of debounce implementations offered by the GPIO libs we use?

@BenjiU

BenjiU commented 4 years ago

Do you have a pullup/down configured? I have the switch on a light bulb here and it works with the 100ms default bounce time, no double trigger.

digital_inputs:
  - name: LichtSchalterLinks
    module: raspberrypi
    pin: 17
    interrupt_payload: "1"
    pullup: yes
    pulldown: yes
    interrupt: both
flyte commented 4 years ago

Yep, it's configured with a pulldown.

  - name: button3
    module: raspberrypi
    pin: 18
    interrupt_payload: trigger
    interrupt: rising
    bouncetime: 600
    on_payload: "ON"
    off_payload: "OFF"
    pulldown: yes
flyte commented 4 years ago

I wonder if it's because you have interrupt: both, which will probably take into account the debouncing of both rising and falling edges. In which case, we'd need a way to establish whether the trigger was a rising or falling one in order to be useful.

BenjiU commented 4 years ago

That's the problem, I guess: the library doesn't support, what interrupt occured... Then we would have to register to both interrupts (although only rising is configured) and try to recognize the interrupt level (with sleeps?!) and only transmit rising interrupts ...