MBC Servo6 6-Port Servo Expander (for LEGO® SPIKE™) × Pybricks

Control 6 servos with MicroPython in three steps

A Pybricks program always goes in this order: first import the library, then create an object and give the expander a name, and only then use that name to call functions. Work through the steps on the left, and the program on the right grows with you. The servo arms on the simulated expander turn as the program says. You can also drag an arm with the mouse and see what the program prints.

Your hub:
This expander only works with SPIKE Prime (Pybricks firmware v4.0 or later). EV3 cannot use it.
1

Import the library

The first thing in the program tells Pybricks: "I want to use the Servo6 library." Without this line, the hub does not understand MBC_SERVO6 later on, and you get a NameError.

  1. Download the library (save the file and keep its name): MBC_servo6_Lib.py. The file name is MBC_servo6_Lib.py.
  2. In Pybricks Code, click "Import a file" in the file area on the left. Add it to the same project.
  3. Do not rename the file, and do not put it in a subfolder.
  4. Go back to the main program. Write these lines at the very top (marked ① in the program on the right).

The hub needs Pybricks firmware v4.0 or later. Older firmware cannot power the servos. The library file is about 25 KB, so uploading takes a little longer when you press run.

2

Create an object: name the expander

A robot may have several expanders and sensors, so you "create an object". It tells the program which hub port the expander is plugged into, and gives it a name. From then on, every time you turn a servo or read the current, you use that name.

Which hub port is the expander plugged into?

Turn on multitasking?

The 3 in the program is the hub port. On SPIKE, 1 to 6 = A to F, so 3 means Port C. Only a number works here. Do not write Port.C.

The first time you run it, the computer asks Custom electronics may damage your LEGO hub ... Press Y to proceed. Press Y (only once; the hub remembers). This lets the hub power the servos through the port. If you press N, the servos get no power.

3

Use the functions

Every function is written as "servo6.function_name(servo, …)": the name, a dot, then the function. The first number in the brackets is the servo port 1 to 6 on the expander (printed CN1 to CN6 on the board). It is not the same as the hub port. Click a function, and the program and output switch to its example.

Simulated expander (one servo on each of the 6 servo ports): watch the program turn the arms, or drag an arm with the mouse

The simulator is only a sketch: turning speed and current are simplified, and real numbers depend on the servo model. Servos 1 and 3 to 6 are standard 180-degree servos. Servo 2 is a 360-degree continuous rotation servo (this one needs 1520 µs to stop). Orange arm = active (pushing), grey = released, red = stalled. Drag an active arm and the servo pushes back, so the current goes up; let go and it turns back. A released arm stays wherever you drag it.

Examples for every function

15 functions, each with an example you can put straight into your program. Press "Try it" to jump to step 3. The program and output on the right switch to that example, and the simulated expander runs it too.

Full examples

Grip 3 times (servo 1 as a gripper)

        

!Only change the "Change these" part at the top. Not gripping tight enough? Make CLOSE bigger. Big current and a hot servo when it grips? Make it a little smaller. A normal program must always end with stop_all().

Multitask version (advanced)

        

!When you create the object, write True as the second value. Create the object outside run_task(), and put await in front of every function. Import the library's run_task on the line under pybricks.tools. Then all 6 servos release by themselves when the program ends, hits an error, or you press the stop button.

Move 6 servos one by one

        

!Moving them one at a time keeps the total current from jumping too high (the expander's power protection limits the current at about 750 mA). Do not plug a 360-degree servo into the ports this example uses: an angle command makes it spin forever.

Good to know

  1. Unplugging does not stop the program. When the expander cannot be read, the reading functions return 0 or False (for the first 0.4 seconds after unplugging, they still give the last value). Servo commands are skipped. The console first prints [SERVO6] Port C … / Servo board disconnected, then "No servo board detected" at most once a second (the library prints each message in Chinese and English). Plug it back in and it reconnects by itself (it prints "Servo board reconnected"). It also sends your servo_calibrate() and servo_stall_config() settings again. To check the connection, read servo6.connected (True or False; no brackets after it, and no await in multitask). Programs that only send commands and never read values work the same way: before each command, the library checks that the expander is still there, so it reconnects and resends the settings when you plug it back in. While unplugged, servo_wait() moves on after about 0.4 seconds instead of getting stuck. Tick "Unplug the expander" on the right to see all this.
  2. Release the servos before the program ends. The expander has no watchdog, so after the program ends, the servos stay at their last angle. In a normal program, call stop_all() at the end. In a multitask program, write from MBC_servo6_Lib import MBC_SERVO6, run_task instead (on the line under pybricks.tools). Then the servos release when the program ends, hits an error, or you press the stop button.
  3. The exact same command only counts once. The expander skips a command that is exactly the same as the one before, so sending the same angle again and again in a loop is fine. But after a servo stalls and is released automatically, sending the same angle in the loop does not make it push again. Send a different angle, or call servo_release() first and then send it.
  4. Only speed 1 to 99 turns slowly. The servo turns "speed × 6" degrees per second. No speed, or 100, turns there at the servo's top speed. The first angle command at the start, or after this port was released, always jumps straight there (the expander does not know where the arm was). is_moving() and servo_wait() use the expander's own count of the progress. The servo has no position sensor, so it cannot tell if it is blocked.
  5. Power: the servos get their power from the hub, through the expander. All 6 together are limited at about 750 mA. When many servos move at once, or one is stalled, check get_total_current() and is_power_fault(). Servo port 1 is on the far left of the expander (on the simulator too).