For a lot of Pi projects it’s nice to have some kind of handheld controller.
Our goal was to create a simple Meccano crane that we could control with one of the game controllers that we had around the house.
There are some options like PyGame that offer a keyboard and joystick interface, but we found the evdev library to be a little simpler and more straight-forward.
The Python evdev Libraray
The Python evdev library offers is a simple way to connect up almost any USB keypad type device, the libary is installed by:
sudo apt-get install python-evdev
A simple monitoring program
The first step is to figure out what the PS2, PS3 or Xbox button codes are. The code below will show you the keycodes and key descriptions for your key presses:
from evdev import InputDevice, categorize, ecodes gamepad = InputDevice('/dev/input/event0') for event in gamepad.read_loop(): if event.type == ecodes.EV_KEY and event.value == 1: try: keyevent = categorize(event) print (keyevent) # comment to remove key messages except: print ("Problem key pressed...")
The output will appears something like:
key event at 1488557515.714249, 295 (BTN_BASE2), down key event at 1488557517.491448, 294 (BTN_BASE), down key event at 1488557519.594712, 293 (BTN_PINKIE), down
Once you’ve got the required keycode then you’re ready to start your main project.
Generic Keypad
There are many low cost generic pads that can be used. Below is a picture of a generic gamepad with some sample code to pick up its keys. (Note: the joystick keys are not addressed in this project).
from evdev import InputDevice, categorize, ecodes gamepad = InputDevice('/dev/input/event0') for event in gamepad.read_loop(): if event.type == ecodes.EV_KEY and event.value == 1: try: keyevent = categorize(event) if keyevent.keycode == "BTN_THUMB": print ("Right - 'A' button") if keyevent.keycode == "BTN_THUMB2": print ("Bottom - 'B' button") if 'BTN_TRIGGER' in keyevent.keycode: # ['BTN_JOYSTICK', 'BTN_TRIGGER'] print ("Top - 'X' button") if keyevent.keycode == "BTN_TOP": print ("Left - 'Y' button") if keyevent.keycode == "BTN_TOP2": print ("Left shoulder button") if keyevent.keycode == "BTN_PINKIE": print ("Right shoulder button") if keyevent.keycode == "BTN_BASE3": print ("SELECT button") if keyevent.keycode == "BTN_BASE4": print ("START button") print (keyevent) # comment to remove key messages except: print ("Problem key pressed...")
PS2 Controller
The PS2 key mapping is not the same as a generic keypad. Some issues that we found using PS2 controllers:
- the PS2 controller may require the “PS” key to be pushed before the controller is active
- the right “triangle”, “circle” and “X” are not directly supported in the keyevent.keycode.
Below is some Python code to pick up the PS2 keys.
from evdev import InputDevice, categorize, ecodes gamepad = InputDevice('/dev/input/event0') for event in gamepad.read_loop(): if event.type == ecodes.EV_KEY and event.value == 1: try: keyevent = categorize(event) if 'BTN_TRIGGER_HAPPY1' in keyevent.keycode: #'BTN_TRIGGER_HAPPY', 'BTN_TRIGGER_HAPPY1' print ("Playstation button") if keyevent.keycode == "BTN_TOP2": print ("Top D-Pad button") if keyevent.keycode == "BTN_BASE": print ("Bottom D-Pad button") if keyevent.keycode == "(BTN_BASE2": print ("Left D-Pad button") if keyevent.keycode == "(BTN_PINKIE": print ("Right D-Pad button") if keyevent.keycode == "BTN_BASE5": print ("Left top shoulder button") if keyevent.keycode == "BTN_BASE6": print ("Right top shoulder button") if keyevent.keycode == "BTN_BASE3": print ("Left bottom shoulder button") if keyevent.keycode == "BTN_BASE4": print ("Right bottom shoulder button") if "BTN_TRIGGER" in keyevent.keycode: #'BTN_JOYSTICK', 'BTN_TRIGGER' print ("SELECT button") if keyevent.keycode == "BTN_TOP": print ("START button") if keyevent.keycode == "BTN_DEAD": print ("SQUARE button") print (keyevent) # comment to remove key messages except: print ("Problem key pressed...")
Wireless Keyboards
We found that evdev also worked well with wireless keyboards. One of the advantages of evdev is that it will get the key stroke directly and you don’t need to do an “Enter”.
We used a wireless keyboard to drive and control a mobile missile launcher.