MBC Ranger 8-Way (TOF8) × Pybricks

Read the Ranger 8-Way in MicroPython in three steps

A Pybricks program always goes in this order: first import the library, then create an object and give the sensor a name, and only then use that name to call a function. Follow the steps on the left and the program on the right grows with you. Drag the obstacle's direction and distance under the simulated sensor to see what the program prints.

Your hub:
1

Import the library

The first thing in the program tells Pybricks "I want to use the Ranger 8-Way library". Without this line the hub does not know what MBC_LASER8 means, and you get a NameError.

Pick one library (both work the same way; only the import line is different):

  1. Download the library (save the file and keep its name): MBC_laser8.py (only this sensor) or MBC_sensors.py (the all-in-one library). You picked MBC_laser8.py.
  2. In Pybricks Code, click "Import a file" in the file area on the left and import it into the same project.
  3. Do not rename the file, and do not put it in a sub-folder.
  4. Go back to your main program and type these lines at the very top (marked ① on the right).
2

Create an object: give the sensor a name

A robot can have several sensors, so you "create an object": tell the program which port the sensor is plugged into and give it a name. Every time you want a reading, you use this name.

Which port is the sensor plugged into?

Turn on multitasking?

The 3 in the program is the port number: SPIKE 1~6 = A~F. You can also write Port.C, but then you also need from pybricks.parameters import Port.

3

Use a function

You always write "laser8.function_name()": the name + a dot + the function. Click a function and the program and output change to its example.

Simulated sensor (seen from above, robot facing up): drag the obstacle and watch the output on the right

The simulation is only a sketch: direction and distance come from a simple position-based estimate, so a real sensor may differ by a step or two. Red sector = that sensor sees something; grey sector = it reads 120 (nothing that way). Sensors 4 and 5 both face straight ahead.

An example for every function

16 functions, each with a short example you can put straight into a loop. Click "Try it" to jump to step 3; the program and output on the right change to that example.

Full examples

Simple obstacle avoiding (SPIKE, left motor A, right motor B)

        

!Only change the "settings to change" at the top. It hits things before stopping: make STOP_CM bigger or SPEED smaller. It turns too much or too little: change the number in wait(400). The robot drives backwards: move Direction.COUNTERCLOCKWISE to the other motor.

Multitasking (advanced)

        

!Write True as the 2nd argument when you create the object, and create the object outside run_task(). Put await in front of every function.

Use it with other MBC sensors

        

!Switch to the shared library: change only the import line and import MBC_sensors.py. Do not import both libraries at the same time.

Good to know

  1. Unplugging does not stop the program. If it cannot read the sensor, it returns the last value it read (or None if it never read one) and prints one warning line on the computer. Plug it back in and it carries on by itself. Use sensor_ok() to check the connection. Tick "Unplug the sensor" on the right to see this. Careful: if the cable comes out while avoiding obstacles, the robot keeps driving on the last distance.
  2. A reading of 120 can mean 4 things: nothing that way, the object is more than 120 cm away, the sensor has just been switched on (wait 2–4 s after power-on), or that sensor is faulty. Use is_ok() to spot a faulty one. Black, shiny or see-through objects are harder to measure, so keep distance checks within 60 cm.
  3. Direction: stand behind the robot and look forward: left is negative, right is positive. Sensor 1 points straight left, sensors 4 and 5 point straight ahead, sensor 8 points straight right. When something is seen, the direction is −7 ~ +7 (−7 straight left, −5 front-left 60°, −3 front-left 30°, −1 ~ +1 straight ahead). ±8 = nothing around (it keeps the side where it last saw something; −8 after power-on). So check "is anything there?" with min_distance() >= 120, and "is it straight ahead?" with abs(direction) <= 1.
  4. Try to use one group in the same loop: on SPIKE, distances(), ch(), min_direction(), min_distance(), max_direction(), max_distance(), is_ok(), init_status(), fault_status(), read_all() are one group (the most used one); nearest_mm(), front_mm(), nearest_dir() are another group; put device_id() and firmware_version() outside the loop. Switching group costs a few tens of milliseconds. On EV3, distances() and ch() are one group; min_direction(), min_distance(), max_direction(), max_distance() are one group; nearest_mm() and nearest_dir() are one group; front_mm() is on its own. Switching group takes about 0.5 s.
  5. The millimetre functions need new firmware: nearest_mm(), front_mm(), nearest_dir(), device_id() and firmware_version() need sensor firmware from 2026-10 or later; older firmware gives other numbers. The distances themselves update about every 0.1 s, so wait(20) ~ wait(50) in the loop is enough.