MBC Ranger 8-Way × LEGO SPIKE App (Python)

Read the Ranger 8-Way with SPIKE App Python in three steps

The LEGO SPIKE App (Education) runs Python too, with no hub firmware change. In the App the Ranger is a color sensor, and the App cannot import your own files, so the order is: first paste the reading helper at the top, then create an object and name the sensor, then call update() once per loop and call its functions with that name. Work down the steps on the left and watch the program grow on the right; drag the obstacle's direction and distance under the simulated sensor to see what the program prints.

1

Paste the reading helper

A SPIKE App Python project is a single file and cannot import your own .py, so paste the whole "reading helper" at the very top (its first lines say so: copy it as is). Without it the hub does not know Laser8App and stops with NameError.

  1. Open the LEGO SPIKE App (Education, yellow SPIKE Prime hub), create a project and choose "Python".
  2. Paste the program marked ① on the right at the top (only the first helper line shows; press "Show helper" to see it all, and "Copy program" always copies everything). The helper alone: MBC_laser8_App_helper.py (open it in a text editor and copy all; the file has Chinese and English comments).
  3. Plug the Ranger into any port A–F; the hub powers it. Use the same port as in step 2.

The helper splits the numbers the App reads for you (the same conversion as the SPIKE App blocks page):

What the App readsWhat it holdsHelper function
color_sensor.color() (color)sensor 1 (far left)ch(1)
color_sensor.reflection() (reflection)sensor 2 (front-left 60°)ch(2)
color_sensor.rgbi() item 1 (raw red)sensor 3 + sensor 4 × 256ch(3), ch(4) (remainder and whole part of ÷ 256)
rgbi() item 2 (raw green)sensor 5 + sensor 6 × 256ch(5), ch(6)
rgbi() item 3 (raw blue)sensor 7 + sensor 8 × 256ch(7), ch(8)
2

Create the object: name the sensor

A robot can have several sensors, so you "create an object": tell the helper which port the Ranger is on (port.C comes from from hub import port) and give it a name. You use that name for every reading.

Which port is the Ranger on?
3

update() every loop, then use a function

App programs go in async def main(): and runloop.run(main()) starts them; wait with await runloop.sleep_ms(100) (not Pybricks' wait()). Each loop first reads once with .update(), then uses "name + dot + function". Pick a function and the program and output switch 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

Every function has an example you can drop into main() (port C). "Try it" jumps to step 3 and the program and output on the right switch to it.

Full examples

Press "Copy" for the whole program (helper included).

Simple obstacle avoidance (left wheel E, right wheel F)

        

!Only change SPEED and STOP_CM. It hits things before stopping: raise STOP_CM or lower SPEED; it turns too much or too little: change the number in sleep_ms(400).

Values the SPIKE App cannot read

The App only reads the Ranger's "combined data" (the 8 distances in cm), so the functions below are out of reach. For them use Pybricks MicroPython, Pybricks blocks (the hub needs the Pybricks firmware) or the MBC Blocks website.

Function (Pybricks library)Why not / what to use
min_direction()The sensor's own "nearest direction" (averaged when two sensors see it) is not readable; this page compares the 8 sensors with nearest() + direction(k), which can be one step off.
max_direction(), max_distance()The most open direction and its distance are not readable; compare the 8 sensors yourself (the full example compares the three on each side).
nearest_mm(), front_mm(), nearest_dir()Millimetre distances are not readable; the App only gets centimetres.
is_ok(), init_status(), fault_status()Per-sensor OK / fault is not readable; a failed sensor keeps reading 120, which looks like "nothing there" (tick "Sensor 3 faulty" in the simulator).
device_id(), firmware_version(), sensor_ok()Device ID, firmware version and "is it connected" are not readable; what the App does when the cable is pulled is not yet tested, so the simulator has no unplug option.

Tips

  1. Call update() every loop. All helper functions split the 8 numbers from the last update(); without it the values never change (they start as all 0, which looks like something touching every sensor).
  2. This is SPIKE App 3 style, not Pybricks. Ports are port.C from from hub import port (not Port.C), and waiting is await runloop.sleep_ms() (not wait()), so Pybricks programs cannot be pasted in. Python in the Robot Inventor (home) App is not verified yet; this page is for the Education App.
  3. The App readings are not yet checked one by one on a real hub. Especially sensor 1 (color()) and sensor 2 (reflection()): the App may only accept 0–10 and 0–100. If ch(1) or ch(2) look wrong wherever your hand is, use the MBC Blocks website or Pybricks.
  4. 120 = nothing that way (or farther than 120 cm, the first 2–4 s after power-on, or that sensor failed). Black, shiny and clear things are harder to measure; keep distance checks within 60 cm.
  5. Directions: looking forward from behind the robot, left is negative and right is positive; sensor 1 points far left, 4 and 5 straight ahead, 8 far right. direction(k) = sensor number × 2 − 9 (sensor 1 −7, 4 −1, 5 +1, 8 +7).