In this project, we will show you how to control the LEGO® Technic Top Gear Rally Car (42109) with the Xbox Controller.

This is a fun way to drive the car around without having to look at your phone screen all time time. You can use all of the analog inputs to drive, which allows for smooth and precise control.

You can also use this setup to create your own remote-controlled cars with Pybricks.

Driving the LEGO® Technic Top Gear Rally Car (42109) with the Xbox Controller.
Driving the LEGO® Technic Top Gear Rally Car (42109) with the Xbox Controller.

Requirements

To follow this project, you will need the following:

See this overview for all compatible models.

Understanding the code

This Technic car has one steering motor on Port B and a drive motor on Port D. The program starts by setting up these motors accordingly.

This program lets you drive the LEGO® Technic Technic Top Gear Rally Car (42109)
  with the Xbox Controller. First, you set up the car, and then you can
  control the steering and power level using the analog inputs.
This program lets you drive the LEGO® Technic Technic Top Gear Rally Car (42109) with the Xbox Controller. First, you set up the car, and then you can control the steering and power level using the analog inputs.

The car setup block takes care of centering the steering motor and makes it easy to drive later on. Finally, we add the setup block for the Xbox Controller.

The main program is quite simple. There is an infinite loop that sets the steering and drive power based on the analog inputs.

Steering (-100% to 100%) is controlled with the left horizontal stick. The drive power is controlled with the right trigger minus the left trigger. This ranges the power level from -100% (reverse) if the left trigger is fully pressed, all the way to 100% (forward) if the right trigger is pressed.

Running the Pybricks program

This project uses Pybricks on your LEGO hub. Pybricks makes your creations come alive and helps you unlock the full potential of your LEGO Technic, City, MINDSTORMS, BOOST, or Spike sets.

If you haven’t already, install Pybricks on your hub as shown below, or check out our getting started guide for more details. You can go back to the LEGO firmware and apps at any time.

Install the Pybricks firmware.
settings
install

Now import the program you downloaded earlier, as shown below. Click to connect your hub and ▶ to start!

Import a Pybricks Code project.
files
import
open
connect
run

You can run imported block programs even if you’re not signed up. This is a great way to try out Pybricks and see how it works.

Pairing with the Xbox Controller

The very first time, you’ll need to pair the hub with your controller:

  1. Turn the controller on.
  2. Press and hold the pairing button on the back.
  3. Release after a few seconds. The controller light will start flashing more rapidly. This is pairing mode.
  4. Then start your program. Either using the Pybricks app, or using the green button on the hub if you’ve already loaded the program earlier.

The hub will start looking for your controller when the program starts. When the connection is successful, the controller light will stop flashing and stay on for as long as the program is running.

You can see this in the video below.

Connecting without pairing

The next time you use it, pairing is not required. Just turn the controller on. The hub will connect to it automatically when your program runs.

The Xbox controller remembers only one device. If you use the controller with another LEGO hub or your Xbox console, and then with this hub again, you’ll need to pair them again as above.

Updating the Xbox Controller

If you often use the Xbox Controller with your console, it is probably already up to date. If you have not used it for a while or if you bought one recently, you may need to update it.

To update the controller without a console, you can use the Xbox Accessories app on a Windows computer. Connect the controller via USB to the computer and follow the instructions in the app to click on “Update now”. If it is already at firmware version 5.17 or later, you don’t need to do anything.

Technic Hub limitations

Once you start your program, the Technic Hub will disconnect from your computer to free up the connection for the Xbox Controller. This means you can’t use the Pybricks app to stop the program or change the code while the Xbox Controller is connected.

To change your program, stop the program by pressing the green button on the hub. Then you can connect to the hub with the Pybricks app again, and change your program as needed.

The car in action

When you’re ready, you can drive the car as shown below!

Running it as a Python program

You can also run this project as a Python (MicroPython) program. The following code was generated from the block program above. To run it, create a new empty Python program in Pybricks and copy the code into it.

# pybricks blocks file:{"blocks":{"languageVersion":0,"blocks":[{"type":"blockGlobalSetup","id":"bjK,wS1MYO7aiYkFSwd{","x":150,"y":100,"deletable":false,"next":{"block":{"type":"variables_set_motor","id":"nhkv?*Y3-QJV4Z+Tt#d+","fields":{"VAR":{"id":"SU`hDwV#At|n9!oFWg#v"}},"inputs":{"PORT":{"shadow":{"type":"blockParametersPort","id":"/0#u@~g,*ptdJCfhe|xq","fields":{"NAME":"B"}}},"POSITIVE_DIRECTION":{"shadow":{"type":"blockParametersDirection","id":"5~PlzCIwDuAicW{XUIZ+","fields":{"SELECTION":"Direction.CLOCKWISE"}}}},"next":{"block":{"type":"variables_set_motor","id":"D~^vKe6!,tZ{RJJL-8jz","fields":{"VAR":{"id":"INn#0]HTW}^i_z6XS4t9"}},"inputs":{"PORT":{"shadow":{"type":"blockParametersPort","id":"0(mMpuc1-9Z=oGH}~v)Q","fields":{"NAME":"D"}}},"POSITIVE_DIRECTION":{"shadow":{"type":"blockParametersDirection","id":"izw*C70.Jio$i~ZDw?OW","fields":{"SELECTION":"Direction.CLOCKWISE"}}}},"next":{"block":{"type":"variables_set_car","id":"#rV!lgT{NpZt%%/6vqB{","extraState":{"optionLevel":0},"fields":{"VAR":{"id":"h|_rzGrJcAjmf5DhWuVH"}},"inputs":{"VAR":{"shadow":{"type":"variables_get_motor_device","id":"^jM(?YZ;`Kfq%)lKWq7_","fields":{"VAR":{"id":"SU`hDwV#At|n9!oFWg#v","name":"steering","type":"Motor"}}}},"VAR2":{"shadow":{"type":"variables_get_motor_device","id":"3}sczA=$fp{]m-sZQBKF","fields":{"VAR":{"id":"INn#0]HTW}^i_z6XS4t9","name":"drive","type":"Motor"}}}}},"next":{"block":{"type":"variables_set_xbox_controller","id":"xaS;h}}^I0RTY9-TX+TA","fields":{"VAR":{"id":"v66UJt;5uVDl+4$$JGHy"}}}}}}}}}}},{"type":"blockGlobalStart","id":"3tJe|AWl0baN(wH9a$@.","x":149,"y":396,"deletable":false,"next":{"block":{"type":"blockFlowWhile","id":".QC*kn8#o^lmSe+ca{Wj","fields":{"MODE":"WHILE"},"inputs":{"BOOL":{"shadow":{"type":"blockLogicTrue","id":"H?V+7C2Yt/q!G5_^#uxP"}},"DO":{"block":{"type":"blockComment","id":"ae|i%ztT$Wil=KQ{CiaU","fields":{"FIELDNAME":"Control steering using the left joystick."},"next":{"block":{"type":"blockCarSteer","id":"mk}3O#L,jV6LOb#^,M[E","inputs":{"VAR":{"shadow":{"type":"variables_get_car_device","id":"DcBHI9u-mg8?.QC4{m8I","fields":{"VAR":{"id":"h|_rzGrJcAjmf5DhWuVH","name":"car","type":"Car"}}}},"VALUE0":{"shadow":{"type":"unit_percent","id":"(k(CLFFjO!]V?VQF*$QB","fields":{"VALUE0":0}},"block":{"type":"blockJoystickValue","id":"AKbc/^]q[k2i19lbVD;(","fields":{"JOYSTICK":"XBOX_LJ_X"},"inputs":{"VAR":{"shadow":{"type":"variables_get_gamepad","id":"^zU{sz#g%Za(aQ|rjlnH","fields":{"VAR":{"id":"v66UJt;5uVDl+4$$JGHy","name":"xbox","type":"XboxController"}}}}}}}},"next":{"block":{"type":"blockComment","id":"0R7Ha;pYQ6nAi1}3z;2z","fields":{"FIELDNAME":"Control drive power using the trigger buttons."},"next":{"block":{"type":"blockCarDrive","id":"xR5bV#N.Bn@0r;h3vqjI","extraState":{"optionLevel":1},"fields":{"METHOD":"CAR_DRIVE_AT_POWER"},"inputs":{"VAR":{"shadow":{"type":"variables_get_car_device","id":"F-C}:0di1OE=1ee}ZV,g","fields":{"VAR":{"id":"h|_rzGrJcAjmf5DhWuVH","name":"car","type":"Car"}}}},"ARG0":{"shadow":{"type":"unit_percent","id":"{|~3ydq0!3phdQuYc9Tj","fields":{"VALUE0":50}},"block":{"type":"blockMathArithmetic","id":"iH%vu]G:0:C/q!@?iVNc","fields":{"OP":"MINUS"},"inputs":{"A":{"shadow":{"type":"blockMathNumber","id":"i/X;?/`OX;@+DzEguq+7","fields":{"NUM":1}},"block":{"type":"blockJoystickValue","id":"MR]G1RLjv}9*VBOG#KV`","fields":{"JOYSTICK":"XBOX_RT"},"inputs":{"VAR":{"shadow":{"type":"variables_get_gamepad","id":"*ApM3;|`B!6YMUaEPR#`","fields":{"VAR":{"id":"v66UJt;5uVDl+4$$JGHy","name":"xbox","type":"XboxController"}}}}}}},"B":{"shadow":{"type":"blockMathNumber","id":"dBo;pAwiVX4Y_vh?mk+@","fields":{"NUM":1}},"block":{"type":"blockJoystickValue","id":"etf4E}EF9dtK?De5{Mj^","fields":{"JOYSTICK":"XBOX_LT"},"inputs":{"VAR":{"shadow":{"type":"variables_get_gamepad","id":"5m/4xbV(bLY~%m,28z66","fields":{"VAR":{"id":"v66UJt;5uVDl+4$$JGHy","name":"xbox","type":"XboxController"}}}}}}}}}}},"next":{"block":{"type":"blockWaitTime","id":"]hb};S1^=sM%02uBZ|Tt","inputs":{"VALUE0":{"shadow":{"type":"unit_time","id":"3[2dhv]xj:gMOf*rn3Sr","fields":{"VALUE0":50}}}}}}}}}}}}}}}}}}]},"variables":[{"name":"red","id":"tY1NeadO^;%:Z-M{Q7g0","type":"ColorDef"},{"name":"orange","id":"f^@*I=s-_cu@rQ58T/%x","type":"ColorDef"},{"name":"yellow","id":"x.5bprt|!YOAA*oTvXQk","type":"ColorDef"},{"name":"green","id":"I_c*s!/ZlA{c_6SN-_BY","type":"ColorDef"},{"name":"cyan","id":"9Sf}f9aWUzV%Gp2(-)cN","type":"ColorDef"},{"name":"blue","id":"-wKLU0+M?#y[%R(sTM?]","type":"ColorDef"},{"name":"violet","id":"zyHO+E|G+U]juzKBeJm(","type":"ColorDef"},{"name":"magenta","id":"xJ+coHII1oCOKs=}I+[J","type":"ColorDef"},{"name":"white","id":"L6C+AWWM))j:pTk]Y%m[","type":"ColorDef"},{"name":"none","id":"Tk2LT|ldmhewOg8sER=[","type":"ColorDef"},{"name":"car","id":"h|_rzGrJcAjmf5DhWuVH","type":"Car"},{"name":"xbox","id":"v66UJt;5uVDl+4$$JGHy","type":"XboxController"},{"name":"steering","id":"SU`hDwV#At|n9!oFWg#v","type":"Motor"},{"name":"drive","id":"INn#0]HTW}^i_z6XS4t9","type":"Motor"}],"info":{"type":"pybricks","version":"1.2.2"}}
from pybricks.iodevices import XboxController
from pybricks.parameters import Direction, Port
from pybricks.pupdevices import Motor
from pybricks.robotics import Car
from pybricks.tools import wait

# Set up all devices.
steering = Motor(Port.B, Direction.CLOCKWISE)
drive = Motor(Port.D, Direction.CLOCKWISE)
car = Car(steering, drive)
xbox = XboxController()


# The main program starts here.
while True:
    # Control steering using the left joystick.
    car.steer(xbox.joystick_left()[0])
    # Control drive power using the trigger buttons.
    car.drive_power(xbox.triggers()[1] - xbox.triggers()[0])
    wait(50)

Python representation of the block program.