MBC 神攝手 × 樂高官方 SPIKE App(Python)

三個步驟用官方 SPIKE App 的 Python 讀神攝手

樂高官方 SPIKE App(教育版)也能寫 Python,不用換韌體。神攝手在 App 裡是一顆顏色感應器,App 不能匯入自己的檔案,所以照這個順序寫:先把讀值小幫手貼在最上面、選好相機模式,再建立物件、幫相機取名字,最後每圈 update() 一次、用名字呼叫功能。左邊一步一步做,右邊的程式會跟著長出來;在模擬的相機畫面裡拖色塊、色紙、積木或線,就能看到程式會印出什麼。

SPIKE 已上機驗證2026-11-01 用出貨版韌體 v1.0-261101 在實機跑過(Pybricks 函式庫與積木、Pybricks 內建積木、官方 App 教育版與家用版、MBC 積木網站)。

1

貼上小幫手、選相機模式

官方 App 的 Python 專案只有一個檔案,不能匯入自己的 .py,所以把「讀值小幫手」整段貼在程式最上面(小幫手開頭也寫了:照抄就好、不用改)。沒有它,後面寫的 UniCamApp 主機看不懂,會出現 NameError。

  1. 打開樂高官方 SPIKE App(教育版,SPIKE Prime 黃色主機),新增專案,選「Python」。
  2. 把右邊標 ① 的程式貼到最上面(小幫手只露第一行,按「顯示小幫手」看全部;「複製程式」一定是完整的)。小幫手也可以單獨下載:MBC_UniCam_App_helper.py(用記事本打開、全選複製)。
  3. 相機插主機 A~F 任一孔,由主機供電;相機要用 SPIKE 版韌體(同一個韌體會自己認出是官方 App 還是 Pybricks)。
  4. 選相機模式:在相機的 MODE 選單選相機模式和子選項,下面點同一個模式編號(模式編號=相機模式 ×10+子選項)。
2

建立物件:幫相機取名字

一台車可能接好幾個感應器,所以要「建立一個物件」:告訴小幫手相機接在哪個孔(port.C 來自 from hub import port)、是哪個模式,並幫它取個名字。之後每次讀值都叫這個名字。

相機接在哪個孔?

第二個數字是第 1 步選的模式編號;相機選單也要切到同一個模式(官方 App 讀不到相機現在是哪個模式,小幫手照你寫的拆,不一樣時數字會亂掉)。

3

每圈 update(),再使用功能

官方 App 的程式放在 async def main(): 裡,最後 runloop.run(main()) 讓它開始跑;等待用 await runloop.sleep_ms(100)(不是 Pybricks 的 wait())。每圈先 cam.update() 讀一次,再用「名字+小數點+功能」。功能依相機模式分組,虛線框的功能是別的模式用的,要換模式才能用(點下去會幫你換)。

模擬相機畫面:拖動畫面裡的東西,看右邊的輸出怎麼變

模擬畫面是示意:數值直接用畫面上的位置換算(X 0~159 左→右、Y 0~119 上→下、面積 %=寬×高÷整個畫面),色相碼是那張色紙/積木本來的顏色(紅 0、黃 40、綠 80、藍 160、紫 200、白桌面 244、黑膠帶 252),不是相機裡面的算法;實際數值會因光線差一些。顏色追蹤假設相機上已經教了 4 色:色 1 紅、色 2 綠、色 3 藍、色 4 黃。物體偵測的形狀是你直接選的(不是相機判斷的),物體 1、2…照面積由大到小排,X、Y 是形狀的質心(白點)、虛線框是外框,角度就是你轉的角度。

每個功能的範例

每個功能都有一段可以直接放進 main() 的範例(名字 cam),右上角標它能用的模式。按「試試看」會切到第 3 步(需要的話也幫你換模式)。

完整範例

按「複製」拿到完整程式(跟 SPIKE 範例頁 的官方 App Python 範例一樣)。小幫手讀不到的值(數量、面積、循線旗標、感應器身分…)用 Pybricks MicroPython 都讀得到(主機要換成 Pybricks 韌體)。

跟著色塊轉(模式 13,左輪 E、右輪 F)

        

!先在相機上教「目標 1」的顏色,相機選單切到模式 13。看不到就原地轉著找,主機燈陣顯示色 1 的 X 格。按「複製」拿到的是完整程式(小幫手已經接好)。

PD 循線+路口停車(模式 41 黑線)

        

!相機斜看前方地面。偏移線在左=負;十字或 T 字路口停車嗶一聲;近處看不到線時往上一次偏的那邊找。

byte 8~15:小幫手讀不到的值

相機每次送 16 byte。官方 App 的 color_sensor.color()、reflection()、rgbi() 只拿到前 8 byte,小幫手用的就是這些。App Python 的 device.data(port.C) 上機實測(2026-11-01)回 8 個值:byte 0、byte 1,之後每 2 byte 一個 int16(原始紅、綠、藍、byte 8~9、10~11、12~13),所以 byte 8~13 讀得到、byte 14~15 讀不到。小幫手沒有用它;要用下表的值,照最下面的寫法自己拆,或改用 Pybricks MicroPython(同一台相機、同一個韌體,主機換 Pybricks 韌體就全部讀得到)。完整排法見 數值對照表。

模式byte 8~15 放的值(小幫手讀不到)
11顏色追蹤 ① 最多色色 8~14 X×10+Y(8×6 格,上=小)
12顏色追蹤 ② 多色色 1~7 數量
13顏色追蹤 ③ 標準色 1~4 數量、色 1~4 面積(佔畫面 %)
14顏色追蹤 ④ 精細色 1~2 數量、色 1~2 面積(佔畫面 %)
21座標取色 ① 色相S7~14 色相
22座標取色 ② 色相+飽和S4~5 色相、S5 飽和度、S6 色相、S6 飽和度、S7 色相、S7 飽和度
23座標取色 ③ 色相+飽和+明度S2~3 明度、S4 色相、S4 飽和度、S4 明度
30照順序給色號左起第 7~13 塊色相
41循線 ① 黑線中段偏移(+100)、有線旗標(近 1+中 2+遠 4)、路口距離 %、穿過的彩色標記線色號、標記線累計條數、遠處線寬 %、近處線左緣(+100)、近處線右緣(+100)
42循線 ② 白線中段偏移(+100)、有線旗標(近 1+中 2+遠 4)、路口距離 %、穿過的彩色標記線色號、標記線累計條數、遠處線寬 %、近處線左緣(+100)、近處線右緣(+100)
43循線 ③ 色線中段偏移(+100)、有線旗標(近 1+中 2+遠 4)、路口距離 %、穿過的彩色標記線色號、標記線累計條數、遠處線寬 %、近處線左緣(+100)、近處線右緣(+100)
51物體偵測 ① 物體清單物體 4 代碼(色號×10+形狀)、物體 4 X×10+Y(8×6 格,上=小)、物體 5 代碼(色號×10+形狀)、物體 5 X×10+Y(8×6 格,上=小)、物體 6 代碼(色號×10+形狀)、物體 6 X×10+Y(8×6 格,上=小)、物體 7 代碼(色號×10+形狀)、物體 7 X×10+Y(8×6 格,上=小)
52物體偵測 ② 物體詳細物體 1 角度、物體 2 X(像素)、物體 2 Y(像素,上=小)、物體 2 寬(像素)、物體 2 高(像素)、物體 2 角度、物體 1 頂點數、物體數

用 device.data() 拆出 byte 8~13(每個 int16 的低位元組=前一個 byte、高位元組=後一個 byte):

import device
from hub import port
import runloop


async def main():
    while True:
        d = device.data(port.C)      # 8 個值:byte 0、byte 1、原始紅、綠、藍、byte 8~9、10~11、12~13
        b8, b9 = d[5] & 255, (d[5] >> 8) & 255
        b10, b11 = d[6] & 255, (d[6] >> 8) & 255
        b12, b13 = d[7] & 255, (d[7] >> 8) & 255
        print(d[0], b8, b9, b10, b11, b12, b13)   # d[0]=「顏色」格的原始值(5 不會變成 6)
        await runloop.sleep_ms(500)

runloop.run(main())

使用注意

  1. 每圈先 update()。小幫手的功能都是拆「最近一次 update() 讀到的 8 byte」;沒 update() 就一直是舊的(一開始全是 0)。
  2. 模式編號一定要跟相機選單一樣。官方 App 讀不到相機現在的模式,小幫手照 UniCamApp(port.C, 模式) 拆;物體功能用錯模式會出現 ValueError,其他功能不會報錯、只是數字沒有意義。
  3. 這是官方 App 3 的寫法,跟 Pybricks 不一樣。孔位是 from hub import port 的 port.C(不是 Port.C)、等待是 await runloop.sleep_ms()(不是 wait()),Pybricks 的程式不能直接貼過來。這頁是教育版的;家用版(Robot Inventor)App 的 Python 寫法不一樣(用 hub.port.C.device.get() 讀 6 個值,排法跟教育版相同),見 SPIKE 讀值教學的家用版段落。
  4. color() 的 5 會變成 6。教育版 App 的 color_sensor.color() 會把相機送的 5 換成 6(樂高的綠色碼),其他數字照原樣,reflection() 不受影響;所以「顏色」那格的 5 和 6 分不出來(例如色 1 的 X 格、找到幾色、路口類型 5 盡頭、物體數、總塊數)。要分清楚,改讀 device.data(port.C)[0](原始值)。
  5. 位置是格子,不是像素。模式 13、14 是 16×12 格(像素 ≈ 格×10−5),模式 11、12 和物體清單 51 是 8×6 格(像素 ≈ 格×20−10);(0, 0)=沒看到。只有模式 52 的物體 1 位置是像素。Y 上=小;循線偏移線在左=負、在右=正(站在車後面往前看)。
  6. 小幫手只讀 byte 0~7。每個模式讀得到哪些,第 1 步選模式時會寫;讀不到的(數量、面積、循線中段偏移、旗標…)見上面「byte 8~15」或改用 Pybricks MicroPython。顏色要在相機上教,程式改不了目標色。