MBC Pathfinder 8-Way (Line8) × LEGO SPIKE App (Python)

Read the Pathfinder with SPIKE App Python in three steps

The LEGO SPIKE App (Education) runs Python too, with no firmware change. In the App, the Pathfinder 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 black line in the sensor simulator 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 Line8App 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_line8_App_helper.py (open it in a text editor and copy all; the file has Chinese and English comments).
  3. Plug the Pathfinder 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
Reflection reflection()line position + 8pos8(): minus 8 → −8 to +8
Raw red rgbi()[0]fine position + 100pos100(): minus 100 → −100 to +100
Color color()line width (channels on the line)width(): as is → 0 to 8, 0 = no line
2

Create the object: name the sensor

A robot can have several sensors, so you "create an object": tell the helper which port the Pathfinder 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 line8.update(), then uses "name + dot + function". Click a function to switch the program and output to its example.

Sensor simulator (looking from behind the robot): drag the black line and watch the output on the right

The simulator is only a picture. The maths is simpler than the real thing, so a real sensor may be off by a channel or two. Light value 0 = black, 100 = white. A red ring = that channel sees the line (light value below 50).

An example for every function

Every function has an example you can drop into async def main(): (name line8). "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). line segments, which channels are on the line, bitmap, device ID, firmware version and sensor connected are not in it; the channel readings are packed into raw green and blue as 4 bits each, but their channel order is not yet verified on hardware, so the helper does not split them. 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_line_follow.py, ex02_which_side.py.

Line following + stop at a crossroads (left wheel E, right wheel F)

        

!Only change the "👉" lines. Wobbling: lower KP; missing bends: raise it. When the line is lost the fine position stays at ±100, so the robot turns back to find it.

Show on the display where the line is

        

!The hub display shows L / R / |, or ? with a beep when there is no line. No motors needed: move the robot across the line by hand.

Good to know

  1. Call update() every loop. All helper functions split the values from the last update(); without it they never change (they start as all 0, so pos8() is −8).
  2. 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 reads differently (measured on hardware: fine position = get_rgb_intensity()[0] − 100, width = get_reflected_light()), so use the Robot Inventor helper on the official app guide. LEGO ended support for the Robot Inventor App on 2026-10-01.
  3. It remembers the last side: when the line leaves the sensor, pos8() is −8 or +8 and pos100() is −100 or +100, so a line follower needs no search code. To check for "really no line", use width() == 0.
  4. Crossroads: line width 6 or more (the whole row is on the line).
  5. Direction: looking forward from behind the robot, line on the left is negative, on the right positive; channel 1 is on the far left. These readings were checked on a hub in the Education SPIKE App 3 (2026-10-29, both Python and blocks passed); if the numbers look wrong, use Pybricks and let us know.
  6. Pasting code: when you paste Python into the SPIKE App 3 editor, it shortens the spaces before end-of-line # comments. That is just the editor's formatting; the program is unchanged.