Using Xbox One Controller with MicroPython on EV3 - hugbug/ev3 GitHub Wiki

This article has become possible thanks to the blog post How to use a PS3 Gamepad with MicroPython on the EV3 brick by Anton Vanhoucke.

You should have the Xbox One Controller connected to the EV3 brick already. Please see Connecting Xbox One Controller to EV3 (EV3DEV or LEGO MicroPython) for details.

An example script to control a typical tank robot with two motors can be found in tank.py.

The script reads controller events from the virtual file /dev/input/event2:

# Find the Xbox Controller :
# /dev/input/event2 is the usual file handler for the gamepad.
# look at contents of /proc/bus/input/devices if it doesn't work.
infile_path = "/dev/input/event2"
 
# open file in binary mode
in_file = open(infile_path, "rb")

Each event consists of five integer fields. Two first fields have the time stamp and the three other fields contain the info we need:

# Read from the file
# long int, long int, unsigned short, unsigned short, long int
FORMAT = 'llHHl'
EVENT_SIZE = struct.calcsize(FORMAT)

event = in_file.read(EVENT_SIZE)
(tv_sec, tv_usec, ev_type, code, value) = struct.unpack(FORMAT, event)

Each button or stick on the controller produce a unique combination of ev_type and code. The parameter value indicates wether the button is pressed or the position of the analog stick. For example the left thumb stick produces events with ev_type set to 3 and code set to 0 for X-axis movements. Our code which checks both X- and Y-axis of the left thumb stick:

if ev_type == 3 and code == 0:
    left_stick_x = value
elif ev_type == 3 and code == 1:
    left_stick_y = value

The range of the value-parameter depends on button/stick. For analog sticks that range is 0..65535. For X-axis the value 0 means the stick is at leftmost position, value 65535 is for the rightmost position and the middle position is represented by the middle value of the range which is somewhat near 32768. Why not exactly? The sticks are very sensitive and they never return to the exact middle position. We should take this into account, our example tank script has a threshold for the stick movements.

Xbox One Controller Event Scheme

The following map shows how buttons generate events.

Of the three numbers:

  1. The first number is what we get in parameter ev_type;
  2. The second number is what we get in parameter code;
  3. The third part represents the range for the value.

For buttons the range 0..1 means the value 1 is generated when the button is pressed and value 0 when it is depressed. Analog sticks have large range 0..65535. Triggers have range 0..1023. Buttons of the D-Pad behave like analog sticks with very small range -1..1. In the code it's easier to check them like buttons though, with up and left buttons having non-standard value -1 for pressed.

Xbox One Controller Event Scheme

Another example is the program xbox-info.py which detects all buttons and prints their names along with values.

Further reading

Reading gamepad events and doing other work at the same time in MicroPython on EV3.