{"id":26871138,"url":"https://github.com/codeadamca/ev3-python-ps4","last_synced_at":"2025-05-07T06:29:18.380Z","repository":{"id":115327714,"uuid":"280762212","full_name":"codeadamca/ev3-python-ps4","owner":"codeadamca","description":"Using Python to connect the LEGO EV3 brick to a PS4 controller.","archived":false,"fork":false,"pushed_at":"2025-01-26T22:26:52.000Z","size":28,"stargazers_count":11,"open_issues_count":1,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T07:18:30.199Z","etag":null,"topics":["bluetooth","ev3","ev3dev","lego","ps4-controller","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codeadamca.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-19T00:17:24.000Z","updated_at":"2025-01-26T22:26:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"14dd905d-7ab5-4693-80fb-f1d0682c7f4c","html_url":"https://github.com/codeadamca/ev3-python-ps4","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeadamca%2Fev3-python-ps4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeadamca%2Fev3-python-ps4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeadamca%2Fev3-python-ps4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codeadamca%2Fev3-python-ps4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codeadamca","download_url":"https://codeload.github.com/codeadamca/ev3-python-ps4/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252826485,"owners_count":21810120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bluetooth","ev3","ev3dev","lego","ps4-controller","python"],"created_at":"2025-03-31T07:18:33.876Z","updated_at":"2025-05-07T06:29:18.362Z","avatar_url":"https://github.com/codeadamca.png","language":"Python","readme":"# LEGO® Mindstorms® EV3, Pthon, and a PS4 Controller\n\nA basic snippet to use vanillia Python to react to a PS4 controller events.\n\nThis code was written to connect a LEGO EV3 Brick to a PS4 controller. The EV3 is running [ev3dev](https://www.ev3dev.org/) and running a version of Python called [Pybricks](https://github.com/pybricks/pybricks-micropython). However, the code reacting to the PS4 controller events and the mapping of different buttons should apply to any Python/PS4 project.\n\nThis code assumes that the PS4 controller has already been paired. \n\n## Event Files\nWhen 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). \n\nUsing 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:\n\n* /dev/input/event2 (touchpad events)\n* /dev/input/event3 (controller movement, like tilting, shaking, etc...)\n* /dev/input/event4 (buttons, sticks, etc...)\n\nEach event provides five values, but we only need the event ID, code, and value. Here is a list of all events I could map:\n\n## Button and Stick Events\n\nWith 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.\n\n\u003ctable\u003e\n\u003ctr\u003e\u003cth\u003eEvent\u003c/th\u003e\u003cth\u003eID\u003c/th\u003e\u003cth\u003eCode\u003c/th\u003e\u003cth\u003ePossible Values\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eX Button\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e304\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eCircle Button\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e305\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTriangle Burron\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e307\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eSquare Button\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e308\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eShare Button\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e314\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eOptions Button\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e315\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003ePS Button\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e316\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eLeft Stick Push\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e317\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eRight Stick Push\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e318\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eL1\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e310\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eR1\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e311\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eL2\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e312\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eR2\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e313\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eLeft Stick Horizontal Axis\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e0 to 255\u003c/td\u003e\u003ctd\u003e0 Left/127 Middle/255 Right\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eLeft Stick Vertical Axis\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e0 to 255\u003c/td\u003e\u003ctd\u003e0 Top/127 Middle/255 Bottom\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eL2 Axis\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e0 to 255\u003c/td\u003e\u003ctd\u003e0 Released/255 Completely Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eRight Stick Horizontal Axis\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e0 to 255\u003c/td\u003e\u003ctd\u003e0 Left/127 Middle/255 Right\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eRight Stick Vertical Axis\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e0 to 255\u003c/td\u003e\u003ctd\u003e0 Top/127 Middle/255 Bottom\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eR2 Axis\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e0 to 255\u003c/td\u003e\u003ctd\u003e0 Left/127 Middle/255 Right\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eDirectional Pad Horizontal\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e16\u003c/td\u003e\u003ctd\u003e-1, 0 or 1\u003c/td\u003e\u003ctd\u003e-1 Right/0 Released, 1 Left\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eDirectional Pad Vertical\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e17\u003c/td\u003e\u003ctd\u003e-1, 0 or 1\u003c/td\u003e\u003ctd\u003e-1 Right/0 Released, 1 Left\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\nNote 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. \n\n## Controller Movement\n\nMovement events were found in /dev/input/event3.\n\nThese 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. \n\n\u003ctable\u003e\n\u003ctr\u003e\u003cth\u003eEvent\u003c/th\u003e\u003cth\u003eID\u003c/th\u003e\u003cth\u003eCode\u003c/th\u003e\u003cth\u003ePossible Values\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eLeft/Right Tilt\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e8192 to -8192\u003c/td\u003e\u003ctd\u003e8192 Tilted as Far Left/0 No Tilt/-8192 Tilted As Far Right\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTowards/Away Tilt\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e8192 to -8192\u003c/td\u003e\u003ctd\u003e8192 Tilted as Far Towards/0 No Tilt/-8192 Tilted As Far Away\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTowards/Away Tilt\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e8192 to -8192\u003c/td\u003e\u003ctd\u003e8192 Tilted as Far Towards/0 No Tilt/-8192 Tilted As Far Away\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eVertical Speed\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003eAny Number\u003c/td\u003e\u003ctd\u003eNegative is Down, Positive is Up\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eAccelleration\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003eAny Number\u003c/td\u003e\u003ctd\u003eNegative is Slowing Down, Positive is Speeding Up\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTimer\u003c/td\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003eAny Positive Number\u003c/td\u003e\u003ctd\u003eThis seems to be the time in micro seconds that the controller has been turned on\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n## Touch Pad Events\n\nMovement events were found in /dev/input/event2.\n\nThese 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.\n\n\u003ctable\u003e\n\u003ctr\u003e\u003cth\u003eEvent\u003c/th\u003e\u003cth\u003eID\u003c/th\u003e\u003cth\u003eCode\u003c/th\u003e\u003cth\u003ePossible Values\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTouchpad Press\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e272\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Released/1 Pressed\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTouchpad Touch\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e325\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Finger Removed/1 Finger Touched\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTouchpad Touch\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e330\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Finger Removed/1 Finger Touched\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTwo Finger Touch\u003c/td\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e333\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Second Finger Removed/1 Second Finger Touched\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTwo Finger Touch\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e47\u003c/td\u003e\u003ctd\u003e0 or 1\u003c/td\u003e\u003ctd\u003e0 Second Finger Removed/1 Second Finger Touched\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTouchpad X\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e53\u003c/td\u003e\u003ctd\u003e1 to 1919\u003c/td\u003e\u003ctd\u003eHorizontal location of the finger, 0 Left/1919 Right\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTouchpad Y\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e54\u003c/td\u003e\u003ctd\u003e1 to 941\u003c/td\u003e\u003ctd\u003eVertical location of the finger, 0 Top/941 Bottom\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eTouch Counter\u003c/td\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e57\u003c/td\u003e\u003ctd\u003eAny Positive Number\u003c/td\u003e\u003ctd\u003e0+ The number of times the touch pas has been touched/-1 Not currently touched\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n## Sample Code\n\nReacting to an event would look like this:\n\n```python\n# If a button was pressed or released\nif ev_type == 1:\n\n    # React to the X button\n    if code == 304 and value == 0:\n        print(\"The X button was released\")\n    elif code == 304 and value == 1:\n        print(\"The X button was pressed\")\n```\n\nThis is assuming the events file has been opened and a while loop has been initiated (see [main.py](main.py) or [tank.py](tank.py)).\n\n---\n\n## Repo Resources\n\n- [Pybricks](https://docs.pybricks.com/en/latest/ev3devices.html)\n- [Python for EV3](https://education.lego.com/en-us/product-resources/mindstorms-ev3/teacher-resources/python-for-ev3)\n\n\u003cbr\u003e\n\u003ca href=\"https://codeadam.ca\"\u003e\n\u003cimg src=\"https://cdn.codeadam.ca/images@1.0.0/codeadam-logo-coloured-horizontal.png\" width=\"200\"\u003e\n\u003c/a\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeadamca%2Fev3-python-ps4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodeadamca%2Fev3-python-ps4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodeadamca%2Fev3-python-ps4/lists"}