A basic snippet to use vanillia Python to react to a PS4 controller events.
This code was written to connect a LEGO EV3 Brick to a PS4 controller. The EV3 is running ev3dev and running a version of Python called Pybricks. However, the code reacting to the PS4 controller events and the mapping of different buttons should apply to any Python/PS4 project.
This code assumes that the PS4 controller has already been paired.
When the PS4 is paried with the device it creates three event files. These files are updated when the PS4 controller experiecnes an event (such as a button press).
Using a terminal check out the contents of the /dev/input folder before and after you pair the Bluetooth device. You should notice three new event files. On my device these files where:
- /dev/input/event2 (touchpad events)
- /dev/input/event3 (controller movement, like tilting, shaking, etc...)
- /dev/input/event4 (buttons, sticks, etc...)
Each event provides five values, but we only need the event ID, code, and value. Here is a list of all events I could map:
With my device, the button and stick events were found in /dev/input/event4. If you're working on a PS4 project, these are probably the events you're looking for.
Event | ID | Code | Possible Values | Description |
---|---|---|---|---|
X Button | 4 | 304 | 0 or 1 | 0 Released/1 Pressed |
Circle Button | 4 | 305 | 0 or 1 | 0 Released/1 Pressed |
Triangle Burron | 4 | 307 | 0 or 1 | 0 Released/1 Pressed |
Square Button | 4 | 308 | 0 or 1 | 0 Released/1 Pressed |
Share Button | 4 | 314 | 0 or 1 | 0 Released/1 Pressed |
Options Button | 4 | 315 | 0 or 1 | 0 Released/1 Pressed |
PS Button | 4 | 316 | 0 or 1 | 0 Released/1 Pressed |
Left Stick Push | 4 | 317 | 0 or 1 | 0 Released/1 Pressed |
Right Stick Push | 4 | 318 | 0 or 1 | 0 Released/1 Pressed |
L1 | 4 | 310 | 0 or 1 | 0 Released/1 Pressed |
R1 | 4 | 311 | 0 or 1 | 0 Released/1 Pressed |
L2 | 4 | 312 | 0 or 1 | 0 Released/1 Pressed |
R2 | 4 | 313 | 0 or 1 | 0 Released/1 Pressed |
Left Stick Horizontal Axis | 3 | 0 | 0 to 255 | 0 Left/127 Middle/255 Right |
Left Stick Vertical Axis | 3 | 1 | 0 to 255 | 0 Top/127 Middle/255 Bottom |
L2 Axis | 3 | 2 | 0 to 255 | 0 Released/255 Completely Pressed |
Right Stick Horizontal Axis | 3 | 3 | 0 to 255 | 0 Left/127 Middle/255 Right |
Right Stick Vertical Axis | 3 | 4 | 0 to 255 | 0 Top/127 Middle/255 Bottom |
R2 Axis | 3 | 4 | 0 to 255 | 0 Left/127 Middle/255 Right |
Directional Pad Horizontal | 3 | 16 | -1, 0 or 1 | -1 Right/0 Released, 1 Left |
Directional Pad Vertical | 3 | 17 | -1, 0 or 1 | -1 Right/0 Released, 1 Left |
Note that the left and right sticks often trigger ongoing events if the controller has any drift. My controller would continuously send events for left horizontal stick movememt alternating between 127 and 128.
Movement events were found in /dev/input/event3.
These events are triggered by physically moving or tilting the controller. I'm not as confident with these. I could not tell the difference with codes one and two.
Event | ID | Code | Possible Values | Description |
---|---|---|---|---|
Left/Right Tilt | 3 | 0 | 8192 to -8192 | 8192 Tilted as Far Left/0 No Tilt/-8192 Tilted As Far Right |
Towards/Away Tilt | 3 | 1 | 8192 to -8192 | 8192 Tilted as Far Towards/0 No Tilt/-8192 Tilted As Far Away |
Towards/Away Tilt | 3 | 2 | 8192 to -8192 | 8192 Tilted as Far Towards/0 No Tilt/-8192 Tilted As Far Away |
Vertical Speed | 3 | 3 | Any Number | Negative is Down, Positive is Up |
Accelleration | 3 | 4 | Any Number | Negative is Slowing Down, Positive is Speeding Up |
Timer | 4 | 5 | Any Positive Number | This seems to be the time in micro seconds that the controller has been turned on |
Movement events were found in /dev/input/event2.
These events are triggered by using or pressing the touchpad on the PS4 controller. I could not figure out the difference between codes 252 and 230 or 333 and 47.
Event | ID | Code | Possible Values | Description |
---|---|---|---|---|
Touchpad Press | 1 | 272 | 0 or 1 | 0 Released/1 Pressed |
Touchpad Touch | 1 | 325 | 0 or 1 | 0 Finger Removed/1 Finger Touched |
Touchpad Touch | 1 | 330 | 0 or 1 | 0 Finger Removed/1 Finger Touched |
Two Finger Touch | 1 | 333 | 0 or 1 | 0 Second Finger Removed/1 Second Finger Touched |
Two Finger Touch | 3 | 47 | 0 or 1 | 0 Second Finger Removed/1 Second Finger Touched |
Touchpad X | 3 | 53 | 1 to 1919 | Horizontal location of the finger, 0 Left/1919 Right |
Touchpad Y | 3 | 54 | 1 to 941 | Vertical location of the finger, 0 Top/941 Bottom |
Touch Counter | 3 | 57 | Any Positive Number | 0+ The number of times the touch pas has been touched/-1 Not currently touched |
Reacting to an event would look like this:
# If a button was pressed or released
if ev_type == 1:
# React to the X button
if code == 304 and value == 0:
print("The X button was released")
elif code == 304 and value == 1:
print("The X button was pressed")
This is assuming the events file has been opened and a while loop has been initiated (see main.py or tank.py).