Skip to content
Advertisement

Reading and debouncing multiple controller keys with evdev

I have an 8bitdo NES controller that I have hooked up to a Raspberry Pi and am using it to interact with some various demos I’m working on.

I’m trying to figure out a good way to grab multiple keypresses with evdev while debouncing so that a single keypress doesn’t trigger twice. I could set a flag and check the next loop, but thought this might be taken care of with the library.

I’m using the active_keys function to get a list of all keypresses as using the for event in device.read_loop(): call appears to be blocking and only grabs a single key per loop.

This is where I’m currently at:

# define key values
KEY_L = 294

while not done:
  keys = gamepad.active_keys()
  if KEY_L:
    # handle L bumper
  ...

As I mentioned, I could set a flag per key to handle a debounce which would get quickly redundant and thought there was a more elegant way to handle this. I didn’t notice it in the API documentation though.

Advertisement

Answer

I can see in the evdev source that there is a debounce class, but it doesn’t appear to be accessible from the Python interface.

A flag per key with a pause and a re-read is a simple and widely used method you appear to be familiar with. You can do it somewhat elegantly with Python’s set intersection:

def active_keys_debounced(debounce_delay=10):
    """Return a list of all debounced keys. Debounce delay is in ms."""
    keys = gamepad.active_keys()
    time.sleep(debounce_delay/1000)
    return list(set(keys).intersection(gamepad.active_keys()))

A more sophisticated method could be to use an integrator.

Alternatively, you could also try using events or async events if you really want it to be fast. These may be automatically debounced, but I’m not sure:

>>> from evdev import InputDevice, categorize, ecodes
>>> dev = InputDevice('/dev/input/event1')

>>> print(dev)
device /dev/input/event1, name "Dell Dell USB Keyboard", phys "usb-0000:00:12.1-2/input0"

>>> for event in dev.read_loop():
...     if event.type == ecodes.EV_KEY:
...         print(categorize(event))
... # pressing 'a' and holding 'space'
key event at 1337016188.396030, 30 (KEY_A), down
key event at 1337016188.492033, 30 (KEY_A), up
key event at 1337016189.772129, 57 (KEY_SPACE), down
key event at 1337016190.275396, 57 (KEY_SPACE), hold
key event at 1337016190.284160, 57 (KEY_SPACE), up
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement