MBC Ranger 2-Way (TOF2) × LEGO SPIKE App (Python)

Read the Ranger with SPIKE App Python in three steps

The LEGO SPIKE App (Education) runs Python too, with no 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 left and right obstacle distances 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 Laser2App 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_laser2_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. The App sees it as a color sensor, so there is nothing to install.

The helper reads three of the App's color sensor values and converts them the same way as the SPIKE App blocks page:

App valueHoldsHelper function
Raw red rgbi()[0]left distance × 256left(): ÷ 256, whole number → 0 to 120 cm
Raw green rgbi()[1]right distance × 256right(): ÷ 256, whole number → 0 to 120 cm
Raw blue rgbi()[2]average distance × 256average(): ÷ 256, whole number → 0 to 120 cm
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 sensor on?

In the App, ports are port.A–port.F: not Pybricks' Port.C and not a number.

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 laser2.update(), then uses "name + dot + function". Click a function to switch the program and output to its example.

Sensor simulator (seen from above, front of the robot facing up): drag the left and right obstacle distances and watch the output on the right change

The simulator is only a picture: the distance comes straight from where the obstacle is on the screen. A real laser can be off by 1 to 2 cm and only updates about every 0.1 seconds. 120 = nothing in front (or farther than 120 cm).

An example for every function

Every function has an example you can drop into async def main(): (name laser2). "Try it" jumps to step 3 and switches the program and output on the right to that example.

What the helper cannot read: the App only reads the sensor's combined data (mode 0). distances in mm, laser OK / start-up / fault bits, device ID, firmware version and sensor connected are not in it. For these, use Pybricks MicroPython (the hub needs the Pybricks firmware) or Pybricks blocks.

Complete examples

Press "Copy" for the whole program (helper included) and paste it into a SPIKE App Python project. Downloads: ex01_avoid.py, ex02_stop_at_wall.py.

Avoid obstacles (left wheel E, right wheel F)

        

!When the nearer distance is below NEAR it spins toward the clearer side, otherwise it drives straight; the display shows the nearer distance.

Stop 20 cm in front of a wall

        

!P control on the average distance: too far drives forward, too near backs up, and it slows down near TARGET. Face the wall squarely.

Good to know

  1. Verified on hardware (2026-11-03, SPIKE Prime Education, SPIKE App 3): raw red, green and blue ÷ 256 = left, right and average distance; color() = left and reflection() = right, neither is clipped to 10 / 100.
  2. Call update() every loop. All helper functions split the values from the last update(); without it they never change (they start as all 0).
  3. This is SPIKE App 3 style, not Pybricks. Ports are port.C from from hub import port (not Port.C or a number), and waiting is await runloop.sleep_ms() (not wait()), so Pybricks programs cannot be pasted in. This page is for the Education App. Python in the Robot Inventor (home) App is written differently (hub.port.C.device); tested, its readings match Education: get_rgb_intensity() = (left, right, average) × 256, so ÷ 256 gives centimetres.
  4. 120 can mean four things: nothing in front, something farther than 120 cm, the laser is still starting up (about 1–2 s after power-on), or that laser is broken. Black, shiny or clear objects are harder to measure; black ones are often lost beyond about 30–50 cm.
  5. Direction: left and right are as seen from behind the sensor, looking the way it faces (left = J5, right = J3); left() is the left laser and right() the right one; negative diff() = left is nearer. The helper only uses raw red, green and blue.