Advertisements

Archive for March 2nd, 2016

Raspberry Pi: USB Keypad Via evdev

The general idea is to use keystrokes plucked from a cheap numeric keypad to control mplayer, with the intent of replacing some defunct CD players and radios and suchlike. The keypads look about like you’d expect:

Numeric keypads

Numeric keypads

The keypad layouts are, of course, slightly different (19 vs 18 keys!) and they behave differently with regard to their NumLock state, but at least they produce the same scancodes for the corresponding keys. The black (wired) keypad has a 000 button that sends three 0 events in quick succession, which isn’t particularly useful in this application.

With the appropriate udev rule in full effect, this Python program chews its way through incoming events and reports only the key-down events that will eventually be useful:

Pressing the keys on the white keypad in an obvious sequence produces the expected result:

82 KEY_KP0
79 KEY_KP1
80 KEY_KP2
81 KEY_KP3
75 KEY_KP4
76 KEY_KP5
77 KEY_KP6
71 KEY_KP7
72 KEY_KP8
73 KEY_KP9
98 KEY_KPSLASH
55 KEY_KPASTERISK
14 KEY_BACKSPACE
74 KEY_KPMINUS
78 KEY_KPPLUS
96 KEY_KPENTER
83 KEY_KPDOT

Observations

  • KeyEvent(e).keycode is a string: 'KEY_KP0'
  • e.type is numeric, so just compare against evcodes.EV_KEY
  • KeyEvent(e).scancode is the numeric key identifier
  • KeyEvent(e).keystate = 1 for the initial press
  • Those KeyEvent(e).key_down/up/hold values don’t change

If you can type KEY_KP0 correctly, wrapping it in quotes isn’t such a big stretch, so I don’t see much point to running scancodes through ecodes.KEY[KeyEvent(e).scancode] just to compare the enumerations.

I’m surely missing something Pythonic, but I don’t get the point of attaching key_down/up/hold constants to the key event class. I suppose that accounts for changed numeric values inside inherited classes, but … sheesh.

Anyhow, that loop looks like a good starting point.

Advertisements

3 Comments