MBC EXP6 6-Port Motor Expander (for LEGO® SPIKE™) × LEGO SPIKE App

Control EXP6 with Python in the LEGO SPIKE App in three steps

A Python program in the LEGO SPIKE App always goes in this order: first import the library, then create an object and give EXP6 a name, and only then use that name to call functions (turn motors, read sensors). Work through the steps on the left and the program on the right grows with you. On the simulated EXP6, choose what is plugged into each expansion port to see how the motors turn and what the program prints.

Your hub: SPIKE Prime with the official App, Education edition (SPIKE 3). The App's word blocks only control LEGO's own parts, so EXP6 uses Python. EXP6 only works with SPIKE Prime (not EV3) and needs its own battery, or the motors will not move.
1

Import the library

The official App cannot import files the way Pybricks does, so you install the EXP6 library on the hub once; after that every Python project just needs three import lines at the top. Without them the hub does not know what MBC_EXP6 means and you get an ImportError or NameError.

  1. Download install_exp6_lib.llsp3 (the installer). The library it installs is called MBC_exp6_SPIKE_App_Lib.
  2. Connect the hub to the official SPIKE App by USB or Bluetooth, choose File → Open, pick this file and press ▶ once. When the console says "Installation Successful!", it is installed.
  3. You only do this once. After you reinstall or update the hub firmware the library is wiped, so run it again. To remove it, run Uninstall_MBC_exp6_Lib.py from the download pack.
  4. Make a new Python project and type the three lines below at the very top (marked ① in the program on the right).

First time? Step-by-step version (you can also copy and paste Install_MBC_exp6_Lib.py): Education install guide.

2

Create an object: give EXP6 a name

Now you "create an object": you tell the program which hub port the EXP6 Host cable is plugged into, and you give it a name. From then on, you use this name every time you turn a motor or read a sensor. The official App version has no multitasking: the program runs line by line and waits with time.sleep().

Which hub port is the EXP6 Host cable plugged into?

The port.C in the program is the hub port: port.A to port.F (the official App uses letters; only Pybricks writes the number 3). The first number inside the brackets of the functions later is the expansion port on EXP6, 1 to 6. Do not mix them up.

3

Use the functions

You always write "exp6.function_name(expansion port, …)": the name, a dot, then the function. The first number in the brackets is usually the expansion port on EXP6, 1 to 6. Click a function and the program and output switch to its example. The motors on the simulated EXP6 move to match.

Simulated EXP6 (seen from above): choose what is plugged into each expansion port, then watch the motors turn and see what is printed on the right

At the start, expansion ports 1 and 2 have motors, port 4 a colour sensor, port 5 an ultrasonic sensor and port 6 a force sensor, the same ports the examples use. The simulation is only an illustration: 1% motor speed counts as 10 degrees per second (a real motor depends on its model), and the sensor values are simplified. The red pointer shows which way the motor shaft points; ↻ = clockwise. The official App version has no watchdog: when the program ends (or you press stop), the motors keep doing the last command, so end your program with exp6.stop_all(1). Colours follow the official App library, which works them out from red, green and blue (green is 5 and "no colour" is 0, unlike Pybricks); the ultrasonic sensor reads -1 when nothing is in front.

An example for every function

33 functions (everything in the official App library; the Pybricks-only connected and run_task are not here), each with a short example. Actions such as turning or stopping a motor usually go outside the loop and run once. Readings go inside the loop and are read again and again. Click "Try it" to jump to step 3; the program and output on the right switch to that example.

Complete examples

Two-wheel car drives a square (left wheel port 1, right wheel port 2)

        

!Only change the "Things to change" part at the top. Turns less than 90 degrees: make TURN a bit bigger; turns too far: make it smaller. Sides too long or too short: change SIDE (720 degrees is about 35 cm). Car drives backwards: change the 1 in set_motor_inverted(1, True) to 2.

Fastest: 5 ready-made official App projects (.llsp3)

!Install the library first, then open the file with File → Open in the official App and press ▶ (EXP6 Host cable in hub port C, EXP6 battery connected). Each example's explanation, wiring and "what you will see" are on the EXP6 SPIKE beginner examples page; every command is explained in the official App section.

MBC sensors on the EXP6 (Line Follower, Laser Ranger, Controller, SharpShot)

When you run out of hub ports, plug MBC sensors straight into EXP6 ports 1–6, just as you would into the hub; there is nothing to set up. The EXP6 needs firmware dated 2026-11-03 or later. In the official App the one library installed above already includes the MBC sensors; there are no product files to add. Same three steps as above: pick the sensor, pick the EXP6 port it is in, pick a function, and the program on the right follows along.

1

Import

Which sensor is on the EXP6?

The official App library MBC_exp6_SPIKE_App_Lib already includes the MBC sensors. Once it is installed on the hub, every project just needs the three lines at the top (from hub import port, import time, from MBC_exp6_SPIKE_App_Lib import MBC_EXP6).

    2

    Create the objects: EXP6 first, then the sensor

    Which EXP6 port is the sensor in?

    3

    Use the functions: same names as on the hub

    Send commands to an MBC sensor: cmd(), wait_done(), cmd_state()

    Line Follower 8-ch: change the binarisation threshold (E4)

    Besides reading values, you can send commands to an MBC sensor through EXP6, with the same codes and parameters as when the sensor is on the hub (for the Line Follower 8-ch see the command reference). cmd(code, params…): code 0xE0 to 0xEE, up to 5 parameters (-9999 to 9999), returns a number for the command; the same command with the same parameters is not sent again unless you add again=True. wait_done(): waits for the result, True = done, False = failed, rejected or timed out (10 seconds by default); cmd_state(): 0 done, 1 busy, 2 failed (bad parameter), 3 rejected (this sensor has no such command); busy(): True while it is not finished. Each command takes about 0.1 to 0.2 seconds to come back.

    from hub import port
    import time
    from MBC_exp6_SPIKE_App_Lib import MBC_EXP6
    
    exp6 = MBC_EXP6(port.C)
    line8 = exp6.line8(5)          # Line Follower 8-ch in EXP6 port 5
    
    seq = line8.cmd(0xE4, 60)      # binarisation threshold to 60 (1 to 99; back to 50 on power-up)
    if line8.wait_done():          # wait for the sensor: True = done
        print("Threshold changed, number", seq)
    else:
        print("Did not work, state", line8.cmd_state())   # 2 failed, 3 rejected
    print("Black/white:", line8.bin_raw())
    line8.cmd(0xE4, 50)            # back to the default 50
    line8.wait_done()

    !Black/white calibration E2 / E3 and the 5-second calibration E7 are saved in the sensor, so do not send them while practising; E4 and E9 go back to default on power-up. So far only the Line Follower 8-ch has been tested with commands. Failed and rejected commands are shown in the download pack example 10 (examples/10_MBC_Commands.py).

    Things to know

    1. Always connect the EXP6 battery. Every motor on the expansion ports runs on EXP6's own battery (a 2S LiPo is recommended). With only the Host cable and no battery, nothing moves. The EXP6 ports take LEGO motors, the LEGO SPIKE colour, ultrasonic and force sensors, and MBC sensors too (see "MBC sensors on the EXP6" above).
    2. Do not mix up the two kinds of port. The port.C in MBC_EXP6(port.C) is the hub port. The 1 in exp6.motor_run(1, 50) is the expansion port on EXP6 (the 1 to 6 printed on the board).
    3. There is no watchdog, so stop the motors yourself. If the program ends or crashes, or you press stop, the motors keep doing the last command. End every program with exp6.stop_all(1). Wait with time.sleep(); keep_alive_wait() and keep_alive() only exist so Pybricks-style code also runs.
    4. A turn command moves on right away and does not wait for the turn to finish. After motor_run_degrees() or motor_track_target(), wait a little, or keep reading the angle until it gets there. Right after power-on, the motors need about 1 to 2 seconds to get ready, so start your program by waiting until get_device_id(port) == 5.
    5. Before switching to another way of programming, power the EXP6 off once (turn off the hub or unplug the Host cable). Once EXP6 has run a Pybricks program it keeps talking the Pybricks way until it restarts, and the official App cannot connect.