測距者 8 路 (TOF8) × SPIKE × Pybricks
這一頁只講 Pybricks(Python):在 SPIKE Prime/Robot Inventor 上用它讀測距者 8 路 (TOF8)的安裝步驟、每個值怎麼讀、能用的命令與範例。要換產品、主機或軟體,用上方的切換列。
安裝與設定
你需要
- 感應器:測距者 8 路 (TOF8)(SPIKE 版)。
- 主機:SPIKE Prime 或 Robot Inventor。
- 電腦:Chrome 瀏覽器,打開 code.pybricks.com 就能寫,不用安裝。
- 主機韌體:要先換成 Pybricks 韌體 v4.1(code.pybricks.com 正式版是 v4.1.1;MBC SPIKE 積木網站燒的 v4.1.0 也可以)。本站範例都照 v4.1 寫。
- 函式庫:
MBC_laser8_obj_Lib.py(要用「匯入函式庫」的寫法才需要)。自己寫新程式只要匯入MBC_sensors.py,一個檔適用全部 MBC 感應器。
注意
Pybricks 3.6.1 版的函式庫與範例已不再更新(2026 年新款 SPIKE Prime 也不能用 3.6.1)。還沒升級的主機,舊檔放在下載專區的「舊版(不再更新)」。
安裝軟體
- 用 Chrome 打開 code.pybricks.com。
- 主機換成 Pybricks 韌體:最簡單的方法是到 MBC SPIKE 積木網站 上方選單「SPIKE 主機 → 安裝/更新 Pybricks 韌體」,約 3 分鐘。
- 之後想回到樂高官方 App,用 SPIKE App 就能換回樂高原廠韌體。
讓軟體認得感應器
Pybricks 有兩種讀法,挑一種就好:
- 內建指令(不用函式庫):直接用 Pybricks 內建的感應器指令讀,不用載入額外檔案,最快上手。
- 匯入函式庫:下載 MBC_laser8_obj_Lib.py,拿到高解析位置、全部通道等更多資料。
匯入函式庫的步驟:
- 在 code.pybricks.com 左邊檔案區按「Import a file(匯入檔案)」。
- 範例檔和
MBC_laser8_obj_Lib.py兩個都要匯入,放在同一個專案列表裡。 - 點開範例,按 ▶ 執行。
重要
新專案用
MBC_sensors.py;舊專案只換掉原本那一個檔。MBC_sensors.py一個檔適用全部 MBC 感應器(EXP6、Servo6 擴充器的函式庫另外下載),寫法是from MBC_sensors import MBC_LINE8,類別名稱跟舊檔名裡的一樣。舊檔名(例如本頁範例用的MBC_laser8_obj_Lib.py)保留給舊程式:用新版的同名檔換掉原本那個檔就好,程式不用改。但每個舊檔名都是整份共用檔,一個程式匯入 3 個以上舊檔名,會超過 SPIKE 程式槽約 51 KB 的上限;要混用多款感應器,就只匯入MBC_sensors.py。
提示
檔名要跟程式裡
import的名字完全一樣,函式庫才載得進來,否則會出現ImportError。本站下載的函式庫檔名都沒有版本字尾,不用改名。
提示
函式庫建立物件時大多有
multitask參數:填False是一般模式,一行一行執行;填True是多工模式,每個呼叫前要加await,可以同時做很多件事。
接線
- 用連接線把感應器插在主機的 C 孔(A~F 任一孔都可以)。
- 程式裡的孔要選同一個:內建指令用
Port.A~Port.F;函式庫的port參數多半是1~6,對應 A~F。 - 接頭卡榫朝上,輕輕推進去。
開機要等 2~4 秒
測距者 8 路不用校準,插上去就能用;開機後要等 2~4 秒讓 8 顆雷射準備好,這段時間全部讀到 120(公分)。程式開頭先等幾秒再讀距離。
| 第幾路 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| 朝哪裡 | 正左邊 | 左前 60° | 左前 30° | 正前方 | 正前方 | 右前 30° | 右前 60° | 正右邊 |
上表是感應器正面朝前、元件面朝上的裝法。手放在機器人左邊,範例 1 應該顯示負的方向;顯示正的代表裝反了,範例裡的「左轉」「右轉」也要對調。
第一次測試
- 主機開機,在 code.pybricks.com 連上主機。
- 匯入並打開本頁的範例 1,按 ▶。
- 主控台印出的數字跟著感應器前方的東西變化,就是接好了。
常見問題
- 出現
ImportError? 函式庫沒有匯入到同一個專案,或檔名跟import的名字不同。把檔名改成MBC_laser8_obj_Lib.py再匯入一次。 - 範例跑不起來、指令不認得? 主機韌體太舊:本站範例照 Pybricks v4.1 寫,先把主機更新到 v4.1。3.6.1 已不再更新,舊版檔案在下載專區。
- 感應器拔線(或線鬆了)怎麼辦? 程式不會停下來:函式庫會回傳上一次讀到的值,並在主控台印一次提醒(中英並列:
MBC: Port C 讀不到感應器,先回傳上一次的值 / no sensor, using the last value);開機時就沒接上的話回傳None。要在程式裡檢查,用物件的sensor_ok():最近一次有讀到是True,讀不到是False(多工模式要寫await)。插回去後函式庫會繼續讀;如果是開機時就沒接上、又用多工模式,要重新執行程式。 - 標「只有 Pybricks 版」的範例讀到怪數字? 那個範例用的是感應器 2026-10 以後韌體的新模式,舊韌體讀到的會是別的數字。
- 換回官方 App 後連不上? 主機現在是 Pybricks 韌體:用 SPIKE App 換回樂高原廠韌體。
讀值
程式假設感應器插 A 孔。「MBC 函式庫」寫法要先把函式庫 .py 一起匯入 Pybricks。
最近距離 cm nearCm
| 範圍 | 意思 |
|---|---|
0~120 cm |
8 顆裡最小的距離 0~120 cm(失效那顆以 120 參與),120 = 四周沒東西 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
w = dev.read(9)[4]
nearCm = ((w >> 8) & 0xFF) # 最近距離 cm(高 byte)MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
nearCm = laser.min_distance()模式 2 byte 0;模式 3 byte 1;模式 4 v[0] hi;模式 7 v[2] 🔒;模式 9 v[4] hi 🔒。備註:[最近方向, 最近距離, 第 1 顆](第 4 byte 第 8 顆被描述表砍掉); Pybricks ambient() = int16[2]/100 = 最近 cm(INO:348-361)
最近方向 nearDir
| 範圍 | 意思 |
|---|---|
-8~+8 |
最近目標在哪個方向:−7(正左)~ +7(正右),0 = 正前方,負 = 左;±8 = 四周沒東西(沿用上次偏向側) |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
w = dev.read(9)[4]
nearDir = (w & 0xFF) - 8 # 最近方向(低 byte)MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
nearDir = laser.min_direction()模式 1 byte 0 −8;模式 3 byte 0 −8;模式 4 v[0] lo −8;模式 5 v[0] 🔒;模式 6 v[2];模式 9 v[4] lo −8 🔒。備註:原始方位 0~16(8 = 正前); Pybricks reflection() 編碼:x = 方位−8,負數 +6399,a = x/25、b = 10×(x mod 25)+9,3 個 int16 = a×256+b → reflection() 向零截斷 = −8~+8(INO:319-336); #67 新:HSV 3×int16 = [最近 mm, 正前方 mm, 最近方向 −8~+8]
最空曠距離 cm farCm
| 範圍 | 意思 |
|---|---|
0~120 cm |
8 顆裡最大的距離 0~120 cm(壞掉那顆永遠 120,會被當成最空曠) |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
w = dev.read(9)[5]
farCm = ((w >> 8) & 0xFF) # 最空曠距離 cm(高 byte)MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
farCm = laser.max_distance()模式 9 v[5] hi 🔒
最空曠方向 farDir
| 範圍 | 意思 |
|---|---|
-7~+7 |
最遠(最空曠)在哪個方向:−7 ~ +7,0 = 正前方,負 = 左;8 顆全 120 時 = 0 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
w = dev.read(9)[5]
farDir = (w & 0xFF) - 8 # 最空曠方向(低 byte)MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
farDir = laser.max_direction()模式 9 v[5] lo −8 🔒
最近距離 mm nearMm
| 範圍 | 意思 |
|---|---|
0~1200 mm |
8 顆 mm 的最小值 0~1200(失效那顆以 1200 參與),1200 = 四周沒東西 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
nearMm = dev.read(6)[0] # 最近距離 mmMBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
nearMm = laser.nearest_mm()模式 6 v[0]。備註:#67 新:[最近 mm, 正前方 mm, 方向]
初始化位元圖 initOk
| 範圍 | 意思 |
|---|---|
0~255 bit |
bit0 = 第 1 顆(最左)… bit7 = 第 8 顆,1 = 那顆開機初始化成功(8 顆約 2~4 秒,失敗不重試);255 = 全部好 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
w = dev.read(9)[6]
initOk = (w & 0xFF) # 初始化位元圖(低 byte)MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
initOk = laser.is_ok(1)模式 9 v[6] lo 🔒
故障位元圖 fault
| 範圍 | 意思 |
|---|---|
0~255 bit |
bit0 = 第 1 顆 … bit7 = 第 8 顆,1 = 那顆目前失效(I2C 讀失敗或 200 ms 沒更新);失效那顆距離回 120/1200 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
w = dev.read(9)[6]
fault = ((w >> 8) & 0xFF) # 故障位元圖(高 byte)MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
fault = laser.is_ok(1)模式 9 v[6] hi 🔒
正前方距離 mm frontMm
| 範圍 | 意思 |
|---|---|
0~1200 mm |
第 4、5 顆(正前方兩顆)平均,0~1200 mm;1200 = 前面沒東西。cm 版是 05 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
frontMm = dev.read(6)[1] # 正前方距離 mmMBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
frontMm = laser.front_mm()模式 6 v[1]。備註:#67 新:正前方 mm
第 1~8 顆距離 cm distCm
| 範圍 | 意思 |
|---|---|
0~120 cm |
第 1 |
from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port
dev = PUPDevice(Port.A) # 感應器插 A 孔
words = dev.read(9)[0:4]
distCm = []
for w in words:
distCm.append(w & 0xFF) # 奇數路
distCm.append((w >> 8) & 0xFF) # 偶數路MBC 函式庫
from pybricks.parameters import Port
from MBC_laser8_obj_Lib import MBC_LASER8
laser = MBC_LASER8(Port.A)
distCm = laser.distances() # list,第 1 路 = [0]模式 0 (edu) byte 0 🔒;模式 0 (toy) byte 0 🔒;模式 3 byte 2;模式 4 v[1];模式 8 v[0];模式 9 v[0] 🔒。備註:16 B = [第 1~8 顆, 0×8]:App 顏色 = 第 1 顆、反射光 = 第 2 顆、原始紅 = 第 3+256×第 4 …; byte0/1 = 第 1、2 顆 ×10/120(0~10);byte2~7 = 第 3~8 顆兩顆一組 4-bit 再查表編碼(spikeEncodeU8,INO:259-284); byte2 = 第 1 顆(byte3 = 第 8 顆被描述表砍掉); v1 = 第 1 顆 + 256×第 8 顆; 只送 4 B:v0 = 第 1+256×第 2、v1 = 第 3+256×第 4; 每 int16 兩顆:lo = 第 2k+1 顆、hi = 第 2k+2 顆(v0~v3 = 第 1~8 顆)
這個軟體讀不到:正前方 cm、第 1~8 顆距離 mm。要用這些值請改用 Arduino/mBlock/micro:bit。
範例
範例 1:最近的東西在哪個方向
這個範例會做什麼:主機螢幕顯示最近的東西在哪個方向(-7 ~ 7)。手放左邊顯示負的、放正前方顯示 0、放右邊顯示正的;四周都沒東西顯示 ✕。
要準備什麼
- SPIKE 主機 1 台
- 測距者 8 路 1 個
- 你的手(或一本書)
怎麼接:測距者 8 路插 C 孔。
下載程式
| Pybricks |
|---|
| ex01_nearest_direction.py+函式庫 |
Pybricks 程式碼
# 測距者 8 路 範例 1:最近的東西在哪個方向(螢幕顯示 -7 ~ 7,沒東西顯示 ✕)
# 接線:測距者 8 路 → C 埠
from pybricks.hubs import PrimeHub
from pybricks.parameters import Icon
from pybricks.tools import wait
from MBC_laser8_obj_Lib import MBC_LASER8
hub = PrimeHub()
laser8 = MBC_LASER8(3) # 3 = C 埠(1=A、2=B、3=C、4=D、5=E、6=F)
while True:
dist = laser8.min_distance() # 最近的東西有多遠(公分,0~120;120 = 四周都沒東西)
direction = laser8.min_direction() # 最近的東西在哪個方向:負的 = 左邊、0 = 正前方、正的 = 右邊
if dist >= 120:
hub.display.icon(Icon.FALSE) # 沒看到東西 → 顯示 ✕
else:
hub.display.number(direction)
print('方向', direction, ' 距離', dist)
wait(200) # 等 0.2 秒再讀下一次一步一步看懂程式
- 一直重複:下面的積木會一直做,直到你按停止。
- 讀最近的距離和方向:MBC 積木網站和 Pybricks 直接有「最近目標距離」「最近目標方向」。
官方 App 要自己做,分 3 段:
- 讀 8 路:照上面的表,把 5 個積木拆成「第1路」~「第8路」8 個變數。
- 一路一路比:先假設「最近距離」是 120、「最近第幾路」是 0;然後從第 1 路比到第 8 路,如果這一路比「最近距離」還近,就把它記下來。比完以後,「最近第幾路」就是最近的那一路(都沒東西的話還是 0)。
- 換成方向:方向=第幾路 × 2 - 9(第 1 路 → -7、第 4 路 → -1、第 5 路 → 1、第 8 路 → 7)。
- 如果 沒東西(MBC 積木網站和 Pybricks:最近距離 ≥ 120;官方 App:最近第幾路 = 0)→ 顯示 ✕。
- 否則 → 螢幕顯示方向。MBC 積木網站和 Pybricks 也會在電腦畫面印出方向和距離。
跑起來應該看到什麼
- 四周沒東西:✕。
- 手放在正左邊 30 公分:**-7;左前方:-5** 或 -3。
- 手放在正前方:0(官方 App 版會是 -1 或 1,因為它只挑一路,第 4、5 路都朝正前方)。
- 手放在右邊:正的數字。
常見問題
- 左右相反? → 你的感應器裝法跟表上相反(例如上下顛倒),後面範例的左右轉也要對調。
- 一直顯示 ✕? → 剛開機要等 2~4 秒;或手太遠(超過 120 公分)、東西是黑色/透明的。
- MBC 積木網站顯示偶數(例如 -6、-2)? → 正常。手剛好在兩路中間、兩路都看到時,方向會取平均。
- 手放哪裡都顯示同一個數字? → 可能有一路壞了或被擋住,一直讀到很小的數字。用 MBC 積木網站的「第 N 路正常」積木或 Pybricks 的
laser8.is_ok(1)~is_ok(8)檢查。
範例 2:有東西靠近就變燈號
這個範例會做什麼:8 個方向任何一個有東西靠近,主機燈號會變:50 公分內亮黃燈,20 公分內亮紅燈並嗶嗶叫,都沒有就亮綠燈。像倒車雷達一樣。
要準備什麼:同範例 1。
怎麼接:測距者 8 路插 C 孔。
下載程式
| Pybricks |
|---|
| ex02_near_light.py+函式庫 |
Pybricks 程式碼
# 測距者 8 路 範例 2:有東西靠近就變燈號(< 20 公分紅燈+嗶、< 50 公分黃燈、其他綠燈)
# 接線:測距者 8 路 → C 埠
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color
from pybricks.tools import wait
from MBC_laser8_obj_Lib import MBC_LASER8
hub = PrimeHub()
laser8 = MBC_LASER8(3) # 3 = C 埠
while True:
dist = laser8.min_distance() # 8 路裡最近的那個距離(公分)
if dist < 20: # 很近了!
hub.light.on(Color.RED)
hub.speaker.beep(880, 100)
elif dist < 50: # 有東西在附近
hub.light.on(Color.YELLOW)
else: # 50 公分內都沒東西
hub.light.on(Color.GREEN)
wait(100)一步一步看懂程式
- 讀最近的距離:官方 App 用範例 1 那段「讀 8 路+一路一路比」積木;另外兩種直接讀「最近目標距離」。
- 如果 最近距離 < 20 → 紅燈+嗶一聲。
- 否則,如果 最近距離 < 50 → 黃燈。
- 都不是 → 綠燈。
- 等 0.1 秒再檢查一次。
跑起來應該看到什麼:手從遠處慢慢靠近,燈號從綠 → 黃 → 紅(嗶嗶叫)。手從左邊、右邊靠近也一樣會變。
常見問題
- 為什麼要先檢查 < 20,再檢查 < 50? → 15 公分同時也「小於 50」。如果先檢查 < 50,就永遠不會亮紅燈了。條件要從最嚴格的開始寫。
- 手貼到感應器上反而變綠燈? → 貼太近(幾公分以內)雷射可能量不到,會讀成 120。留一點距離就好。
- 放在桌上一直是黃燈? → 側邊那幾路量到了桌上的其他東西,或感應器裝太低量到桌面。
範例 3:轉頭朝向最近的東西
這個範例會做什麼:機器人原地轉,讓車頭對準最近的東西(60 公分內)。手在左邊就往左轉、在右邊就往右轉,對準了就停。
要準備什麼
- 範例 1 的東西,再加上
- 兩輪小車(兩顆馬達當輪子)
怎麼接
- 測距者 8 路插 C 孔,裝在車頭,第 4、5 路朝正前方,離地至少 5 公分
- 左輪接 E、右輪接 F
下載程式
| Pybricks |
|---|
| ex03_turn_to_nearest.py+函式庫 |
Pybricks 程式碼
# 測距者 8 路 範例 3:原地轉頭,讓車頭朝向最近的東西(60 公分外的不理它)
# 接線:測距者 8 路 → C 埠(裝在車頭);左輪馬達 → E 埠;右輪馬達 → F 埠
from pybricks.parameters import Direction, Port
from pybricks.pupdevices import Motor
from pybricks.robotics import DriveBase
from pybricks.tools import wait
from MBC_laser8_obj_Lib import MBC_LASER8
laser8 = MBC_LASER8(3) # 3 = C 埠
left = Motor(Port.E, Direction.COUNTERCLOCKWISE) # 左輪:反過來裝,所以設成逆時針才是往前
right = Motor(Port.F) # 右輪
robot = DriveBase(left, right, wheel_diameter=56, axle_track=112) # 輪子直徑 56 mm、兩輪距離 112 mm
while True:
dist = laser8.min_distance()
direction = laser8.min_direction() # -7(最左)~ 0(正前方)~ 7(最右)
if dist > 60: # 太遠或沒東西 → 停著等
robot.stop()
elif direction < -1: # 東西在左邊 → 原地左轉
robot.drive(0, -90) # 不前進,每秒左轉 90 度
elif direction > 1: # 東西在右邊 → 原地右轉
robot.drive(0, 90)
else: # -1、0、1:已經在正前方 → 停
robot.stop()
wait(50)一步一步看懂程式
- 告訴主機輪子接在哪裡:官方 App 是「set movement motors to E+F」,速度 20%;MBC 積木網站和 Pybricks 是「移動底盤 左輪 E、右輪 F」。
- 讀最近的距離和方向(官方 App 是「最近第幾路」)。
- 如果 最近距離 > 60 → 太遠或沒東西 → 停著等。
- 否則,如果 東西在左邊(方向 < -1;官方 App:第 1~3 路)→ 原地左轉。
- 否則,如果 東西在右邊(方向 > 1;官方 App:第 6~8 路)→ 原地右轉。
- 都不是(正前方)→ 停。
跑起來應該看到什麼:手放在機器人左邊,它會轉過來面對你的手;手繞著它慢慢走,它會一直轉頭跟著你。
常見問題
- 轉過頭、在手的兩邊晃來晃去? → 轉太快了。MBC 積木網站和 Pybricks:把「90」改小(例如 60);官方 App:把速度 20% 改小(例如 15%)。
- 轉的方向相反、越轉越遠? → 回到範例 1 確認左右;或是馬達裝法相反(看範例 4 的常見問題)。
- 一直轉不停? → 旁邊的牆、桌腳比你的手還近,它就會去找牆。在空曠的地方玩。
範例 4:避障,往最空曠的地方走
這個範例會做什麼:機器人一直往前走。正前方 30 公分內有東西就停下來,看看哪一邊比較空曠,往那邊轉 45 度,再繼續走。
要準備什麼:同範例 3,再找一塊空地、放幾個盒子當障礙物。
怎麼接:測距者 8 路插 C 孔、裝在車頭;左輪接 E、右輪接 F。
下載程式
| Pybricks |
|---|
| ex04_avoid_open_side.py+函式庫 |
Pybricks 程式碼
# 測距者 8 路 範例 4:避障。一直往前走;正前方(第 4、5 路)小於 30 公分就停下,往最空曠的那一邊轉 45 度
# 接線:測距者 8 路 → C 埠(裝在車頭);左輪馬達 → E 埠;右輪馬達 → F 埠
from pybricks.parameters import Direction, Port
from pybricks.pupdevices import Motor
from pybricks.robotics import DriveBase
from pybricks.tools import wait
from MBC_laser8_obj_Lib import MBC_LASER8
laser8 = MBC_LASER8(3) # 3 = C 埠
left = Motor(Port.E, Direction.COUNTERCLOCKWISE)
right = Motor(Port.F)
robot = DriveBase(left, right, wheel_diameter=56, axle_track=112)
while True:
if laser8.ch(4) < 30 or laser8.ch(5) < 30: # 第 4、5 路都朝正前方,任何一個小於 30 公分 → 前面有東西
robot.stop()
if laser8.max_direction() < 0: # 最空曠的方向在左邊(負的)
robot.turn(-45) # 原地左轉 45 度
else:
robot.turn(45) # 原地右轉 45 度
else:
robot.drive(150, 0) # 每秒 150 mm 往前走
wait(50)一步一步看懂程式
- 設定輪子和速度:官方 App 速度 30%;另外兩種是每秒 150 mm。
- 一直重複:看正前方的第 4 路或第 5 路有沒有小於 30 公分。
- 如果 有 → 停車,然後找最空曠的方向:
- MBC 積木網站和 Pybricks 直接讀「最空曠方向」:負的(左邊比較空)→ 左轉 45 度,否則右轉 45 度。
- 官方 App 用跟範例 1 一樣的「一路一路比」,只是改成找最遠的那一路:第 1~4 路 → 左轉,第 5~8 路 → 右轉。官方 App 的轉 45 度是「以轉向 -100(或 100)移動 0.25 圈」,樂高標準小車大約轉 45 度。
- 否則 → 往前走。
跑起來應該看到什麼:小車往前走,快撞到盒子時停下、往比較空的那邊轉,再繼續走。走到牆角也會一直轉,直到找到出路。
常見問題
- 撞上去才停? → 太快了,或障礙物是黑色、透明的。把速度調低,或把「30」改大。
- 擦到旁邊的東西? → 這個範例只看正前方兩路。想更安全,可以把第 3、6 路也加進「或」裡面一起檢查。
- 轉的方向跟空曠的那邊相反? → 回到範例 1 確認左右;左右相反的話,把左轉、右轉對調。
- 小車往後退、方向相反? → 馬達的裝法跟樂高標準小車相反。官方 App:請照樂高「標準驅動底盤」的方向裝馬達;MBC 積木網站:「移動底盤」積木裡左右輪的「正轉」方向都換成另一個;Pybricks:左輪改成
Direction.CLOCKWISE、右輪改成Motor(Port.F, Direction.COUNTERCLOCKWISE)。 - 某一路壞了會怎樣? → 壞掉的那一路一直讀 120,會被當成「最空曠」,機器人可能往障礙物轉。用範例 1 的常見問題檢查每一路。
範例 5:跟著手走
這個範例會做什麼:機器人跟著你的手走,並且保持 15~25 公分的距離:手在遠一點(25~60 公分)就一邊往前走、一邊轉向手;剛剛好就停;太近(小於 15 公分)就後退;手拿走(超過 60 公分)就停。
要準備什麼:同範例 3。
怎麼接:測距者 8 路插 C 孔、裝在車頭;左輪接 E、右輪接 F。
下載程式
| Pybricks |
|---|
| ex05_follow_hand.py+函式庫 |
Pybricks 程式碼
# 測距者 8 路 範例 5:跟著手走。手在 25~60 公分:一邊往前走一邊轉向手;15~25 公分:停;太近:後退
# 接線:測距者 8 路 → C 埠(裝在車頭);左輪馬達 → E 埠;右輪馬達 → F 埠
from pybricks.parameters import Direction, Port
from pybricks.pupdevices import Motor
from pybricks.robotics import DriveBase
from pybricks.tools import wait
from MBC_laser8_obj_Lib import MBC_LASER8
laser8 = MBC_LASER8(3) # 3 = C 埠
left = Motor(Port.E, Direction.COUNTERCLOCKWISE)
right = Motor(Port.F)
robot = DriveBase(left, right, wheel_diameter=56, axle_track=112)
while True:
dist = laser8.min_distance() # 手(最近的東西)有多遠
direction = laser8.min_direction() # 手在哪個方向:-7 ~ 7
if dist > 60: # 看不到手 → 停
robot.stop()
elif dist < 15: # 太近了 → 每秒 80 mm 往後退
robot.drive(-80, 0)
elif dist > 25: # 有點遠 → 往前走,手偏多少就轉多少
robot.drive(100, direction * 15) # 方向 × 15 = 每秒轉幾度(左負右正)
else: # 15 ~ 25 公分:剛剛好 → 停
robot.stop()
wait(50)一步一步看懂程式
- 讀手(最近的東西)的距離和方向(官方 App 用範例 1 那段積木)。
- 依照距離分 4 種情況,從上往下檢查:
- > 60 公分 → 看不到手 → 停。
- < 15 公分 → 太近 → 後退(MBC 積木網站和 Pybricks:每秒 80 mm)。
- > 25 公分 → 有點遠 → 往前走,並且手偏多少就轉多少:MBC 積木網站和 Pybricks 每秒轉「方向 × 15」度;官方 App 的轉向是「方向 × 10」(方向一樣是第幾路 × 2 - 9)。
- 剩下的(15~25 公分) → 剛剛好 → 停。
跑起來應該看到什麼:手放在機器人前面 40 公分,它會往前走;手往左移,它會邊走邊左轉;手停住,它也在 20 公分左右停下來;手往前推,它會往後退。
常見問題
- 一直前後抖動? → 「剛剛好」的範圍太窄。把 15 改成 12、25 改成 30。
- 轉彎太猛/太慢? → 改「× 15」(官方 App 是「× 10」)那個數字:大一點轉得快、小一點轉得慢。
- 跟著牆走,不跟手? → 旁邊的東西比你的手還近。在空曠的地方玩,手要是最近的東西。
- 官方 App 版不會後退? → 請確認「start moving(開始移動)」積木的方向是「往後」的箭頭。
範例 6(進階):最近的東西有幾毫米
注意
這個範例只有 Pybricks 版。 它用的「毫米距離」放在感應器的模式 6,樂高官方 App 和 MBC 積木網站讀不到(它們只讀公分)。感應器韌體要是 2026-10 以後的版本,舊韌體讀到的會是別的數字。 程式碼就是範例,不需要截圖。
這個範例會做什麼:主機螢幕捲動顯示最近的東西有幾毫米(例如 300),燈號分三段:10 公分以內紅燈、10~30 公分黃燈、更遠綠燈;四周沒東西顯示 ✕。電腦畫面同時印出它在哪個方向、正前方有幾毫米。
要準備什麼:同範例 1(主機+測距者 8 路+一隻手或一本書)。
怎麼接:測距者 8 路插 C 孔。
下載程式
| Pybricks |
|---|
| ex06_nearest_mm.py+函式庫 |
Pybricks 程式碼
# 測距者 8 路 範例 6(進階):最近的東西有幾毫米(螢幕捲動顯示毫米、燈號分三段)
# 接線:測距者 8 路 → C 埠
# 只有 Pybricks 版:毫米距離放在感應器的「模式 6」,官方 App 和積木網站讀不到;感應器韌體要 2026-10 以後
from pybricks.hubs import PrimeHub
from pybricks.parameters import Color, Icon
from pybricks.tools import wait
from MBC_laser8_obj_Lib import MBC_LASER8
hub = PrimeHub()
laser8 = MBC_LASER8(3) # 3 = C 埠
while True:
mm = laser8.nearest_mm() # 最近的東西有幾毫米(0~1200;1200 = 四周沒東西)
direction = laser8.nearest_dir() # 它在哪個方向:-8 ~ 8(0 = 正前方,負 = 左)
front = laser8.front_mm() # 正前方(第 4、5 顆平均)有幾毫米
if mm >= 1200: # 四周沒東西
hub.display.icon(Icon.FALSE)
hub.light.on(Color.GREEN)
else:
hub.display.text(str(mm)) # 螢幕捲動顯示毫米,例如「300」
if mm < 100: # 10 公分以內:紅燈
hub.light.on(Color.RED)
elif mm < 300: # 10~30 公分:黃燈
hub.light.on(Color.YELLOW)
else: # 更遠:綠燈
hub.light.on(Color.GREEN)
print('最近', mm, 'mm 方向', direction, ' 正前方', front, 'mm')
wait(200)一步一步看懂程式
laser8.nearest_mm():最近的東西有幾毫米(0~1200;1200=四周沒東西),比公分細 10 倍。laser8.nearest_dir():它在哪個方向(-8~8,0=正前方,負=左),跟範例 1 的方向一樣。laser8.front_mm():正前方(第 4、5 顆平均)有幾毫米,給「只看前面」的程式用。- 如果 ≥ 1200 → 顯示 ✕、綠燈;否則顯示毫米,再依 100、300 分成紅、黃、綠。
- 這三個數字一起讀只讀一次硬體;函式庫還有
laser8.device_id()、laser8.firmware_version()。
跑起來應該看到什麼:手放在左邊 30 公分:螢幕捲「300」、綠燈,電腦印「方向 -5」;手移到正前方 25 公分:「250」、黃燈、「方向 0」;手貼近到 8 公分:「80」、紅燈。
常見問題
- 毫米值跳來跳去? → 正常,雷射每次量會差 10~20 mm;要穩定就多量幾次取平均。
- 想同時用公分和毫米? → 可以,但不要在同一個迴圈裡混著用:每次切換模式感應器要多花幾十 ms。
- 一直顯示 ✕? → 四周 120 公分內沒東西;或感應器韌體太舊(2026-10 以前)沒有毫米模式,請更新韌體。
其他問題
- 主機認不到感應器? 拔掉重插一次,等 2 秒;換一個孔試試。官方 App 會把它顯示成「顏色感應器」,這是正常的。
- 可以同時用官方 App 和 Pybricks 嗎? 一次只能裝一種韌體:Pybricks 與 MBC 積木網站用 Pybricks 韌體,官方 App 用樂高原廠韌體;隨時可以用 SPIKE App 換回原廠韌體。
還有問題?到 聯絡我們 附上你用的軟體和程式截圖。
下載
- Pybricks 函式庫 MBC_laser8_obj_Lib.py
- 共用函式庫(新專案用,一個檔適用全部 MBC 感應器) MBC_sensors.py
- tof8_pybricks_spike_v4.x.zip
- MBC_TOF8_Pybricks_Lib.zip
- 下載中心(全部產品的函式庫、韌體、型錄)
本頁依據
- 主機與軟體清單:
_build/guides.json - 值與命令:
_build/protocol/tof8.json(單一真相來源) - 安裝與設定:
_build/guides/software/spike-pybricks.zh.md、_build/guides/product/tof8/spike-pybricks.zh.md - 範例:
sensors/tof8/spike-examples.md