Gpiozero: Button bounce_time throwing error

Created on 9 Jan 2020  路  10Comments  路  Source: gpiozero/gpiozero

Operating system: Raspbian Buster
Python version: 3.7.3
Pi model: Raspberry Pi Zero W Rev 1.1
GPIO Zero version: 1.5.0
Pin factory used: gpiozero.pins.pigpio.PiGPIOFactory

I've built a little box with a Pi + a 16x2 LCD + a few push buttons. It's hooked up to my discogs record collection and it essentially is just a "random record generator" to help me decide which record to listen to. It works fine, I use it every day, and have for almost a year, BUT the push buttons are old and have some jitter or bounce or whatever, so I decided to see if I could improve on that a bit. I was in the middle of figuring out my own solution when I just stumbled upon the bounce_time argument which looked exactly like what I need. However, when I add bounce_time=0.5 or bounce_time=1 (or any other value I've tried), I get this error:

Traceback (most recent call last):
  File "randomboye/randomboye.py", line 12, in <module>
    main()
  File "randomboye/randomboye.py", line 8, in main
    pi = RaspberryPiIODiagnoser()
  File "/home/pi/dev/randomboye/randomboye/raspi_io_diagnoser.py", line 45, in __init__
    bounce_time=1,
  File "/home/pi/.local/lib/python3.7/site-packages/gpiozero/devices.py", line 124, in __call__
    self = super(GPIOMeta, cls).__call__(*args, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/gpiozero/input_devices.py", line 432, in __init__
    bounce_time=bounce_time, pin_factory=pin_factory)
  File "/home/pi/.local/lib/python3.7/site-packages/gpiozero/mixins.py", line 383, in __init__
    super(HoldMixin, self).__init__(*args, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/gpiozero/input_devices.py", line 184, in __init__
    self.pin.bounce = bounce_time
  File "/home/pi/.local/lib/python3.7/site-packages/gpiozero/pins/__init__.py", line 379, in <lambda>
    lambda self, value: self._set_bounce(value),
  File "/home/pi/.local/lib/python3.7/site-packages/gpiozero/pins/pigpio.py", line 318, in _set_bounce
    self.factory.connection.set_glitch_filter(self.number, int(value * 1000000))
  File "/home/pi/.local/lib/python3.7/site-packages/pigpio.py", line 4094, in set_glitch_filter
    return _u2i(_pigpio_command(self.sl, _PI_CMD_FG, user_gpio, steady))
  File "/home/pi/.local/lib/python3.7/site-packages/pigpio.py", line 970, in _u2i
    raise error(error_text(v))
pigpio.error: 'bad filter parameter'

Any help would be greatly appreciated!

Most helpful comment

Thanks for the info @joan2937 !

@bennuttall / @waveform80 It might be worth checking for this and displaying a more user-friendly error message from the "gpiozero level" rather than the "pigpio level" ?

All 10 comments

You seem to be using pigpio as a back end. The maximum debounce time allowed by pigpio is 0.3 seconds. Perhaps try something in the milliseconds or tens of milliseconds range.

http://abyz.me.uk/rpi/pigpio/python.html#set_glitch_filter

Thanks for the info @joan2937 !

@bennuttall / @waveform80 It might be worth checking for this and displaying a more user-friendly error message from the "gpiozero level" rather than the "pigpio level" ?

Thanks @joan2937! I did some analysis on the jitter of my buttons and found them to typically be done jittering after 300-400 milliseconds, which was why I wanted to do 0.5. I'll try 0.3 to see if that works for most of the cases. Thanks for getting back to me so quickly!

...I could also try to get better buttons but I really don't want to desolder and resolder my little setup, but maybe i'll have to bite the bullet...

If you're happy with soldering, an alternative might be to add a capacitor to debounce in hardware rather than software? :slightly_smiling_face:

This first article on that search was really good. I even think I have some 40106s lying around to do it "the right way" and I'm sure I can find room on my board for it. Good idea, thank you @lurch!

@claussoegaard What sort of button? That seems to be an awfully long time to settle. It might take 300-400 ms to settle but that does not mean you need a 400 ms glitch filter. Try something like 10 ms (i.e. 0.01 seconds). The glitch filter ignores any edges shorter than the filter time. Contact bounce is when the switch changes rapidly when it is opened or closed. There may be many short bounces during the opening/closing period. E.g. say there were 50 bounces taking 19 ms each you would need a filter of 20 ms not of 950 ms. The RPi.GPIO bounce time works differently, it ignores all changes during the bounce time.

@joan2937 they are some older push buttons i found in their original packaging (from the 60s or 70s or something?) and I just thought they looked cool, but they're probably terrible. :) But your explanation is super helpful. I assumed the bounce_time was the time from the first press/release, until things had settled. You are right! I found that 0.05 was a good amount. I pressed both buttons like 100 times and every single time just registered a single press and single release in my logs. Thanks so much!

I guess I thought it was a bug because the only gpiozero docs said "..., this is the length of time (in seconds) that the component will ignore changes in state after an initial change."

Either way, thanks a lot, got it to work!

Yeah, I guess the "glitch filter" used by pigpio and the "debounce" used by RPi.GPIO work slightly differently, and GpioZero attempts to smooth over these differences (and present a uniform API) by pretending they're the same thing :wink:

I just created #828 so that this doesn't get forgotten about :slightly_smiling_face:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

e28eta picture e28eta  路  4Comments

m-reiter picture m-reiter  路  3Comments

lurch picture lurch  路  5Comments

bennuttall picture bennuttall  路  9Comments

pcs3rd picture pcs3rd  路  6Comments