這頁內容已整合到新的說明頁:循行者 16 路

循行者 16 路 指令參考

回到循行者 16 路產品頁

這一頁列出循行者 16 路送給每個上位機的每一個值、每一個命令:它是什麼意思、範圍多少、在 SPIKE/EV3/Arduino I2C/mBlock/MATRIX/micro:bit 各要怎麼讀。網址加 ?host=spike(或 ev3、arduino、mblock、matrix、microbit)會直接展開那個平台。

SPIKEEV3Arduino I2CmBlockMATRIXmicro:bit

項目 內容
I2C 出廠位址 0x16
hw[0] 16(F0 高 byte、SPIKE 模式 8/EV3 模式 5 ID 高 byte)
型號 LINE16
協議版本 2
支援平台 SPIKE、EV3、Arduino I2C、mBlock、MATRIX、micro:bit

值一覽

編號 值 範圍 SPIKE EV3 Arduino I2C mBlock MATRIX micro:bit
01 線位置 -16~+16 ✓ ✓ ✓ ✓ ✓ ✓
02 細位置 -100~+100 ✓ ✓ ✓ ✓ ✓ ✓
03 線寬 0~16 路 ✓ ✓ ✓ ✓ ✓ ✓
04 線段數 0~8 ✓ — ✓ ✓ — ✓
05 壓線位元圖 0~65535 bit ✓ ✓ ✓ ✓ — ✓
06 最後離線方向 -16~+16 — — ✓ ✓ — ✓
07 二值化門檻 1~99 — — ✓ ✓ — ✓
08 校準完成次數 0~255 次 — — ✓ ✓ — ✓
10~1F 第 1~16 路光值 0~100 ✓ ✓ ✓ ✓ ✓ ✓

✓ = 這個平台有這個值;— = 沒有(表格裡的平台欄位只列產品支援的平台)。

每個值怎麼讀

01 線位置 linePos

線位置
項目 內容
用途 線在哪一路:−16(最左)~+16(最右),0 = 正中間;站在車後往前看,負 = 線在左(平常 ±15,±16 只在最外側掉線後 200 ms 內)
範圍 -16~+16
I2C/mBlock 編號 01
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 0 (edu) byte 1 −16 🔒;模式 0 (toy) byte 0 −16 🔒;模式 1 byte 0 −16;模式 5 v[0] 🔒;模式 9 v[4] lo −16 🔒。備註:Pybricks reflection() 編碼:X = (線位置+16)×100 + 線寬,共用核心 mbcReflFill8 送出:2026-11-01 以後的韌體 reflection() 剛好是整數(3.x、4.x 都是);舊韌體(R=G=B=a×256+b)在 4.x 帶小數,先 int();X ≥ 3200 時讀到負數 X−6399(F16:905)

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

w = dev.read(9)[4]
linePos = (w & 0xFF) - 16   # 線位置(低 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_line16_obj_Lib import MBC_LINE16

line = MBC_LINE16(Port.A)
linePos = line.pos16()
EV3

模式 0 · int8 · IR-PROX(F16:739-741)(已鎖住的模式,韌體與主機端都不再改)

from pybricks.iodevices import LUMPDevice
from pybricks.parameters import Port

sensor = LUMPDevice(Port.S1)   # 感應器插 1 號孔

linePos = sensor.read(0)[0]   # 線位置:-16~+16
' clev3r (BASIC)
Sensor.SetMode(1, 0)
linePos = Sensor.ReadRawValue(1, 0)
Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t linePos = mbcRead(0x16, 0x01);   // 線位置:-16~+16
mBlock

積木傳回 線位置(-16~+16)。主機送 [01] → 回 [值低][值高][01 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 線的位置 :: sensing)
MATRIX

0x22 R (+16)。

// A. 原廠 0x22 積木:R = 線位置 + 16
int linePos = MiniR4.I2C1.MXColor.getColor(R) - 16;
micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 線位置 :: #00A4E4)
let linePos = mbc.linePosition()   // 線位置:-16~+16

02 細位置 linePosFine

細位置
項目 內容
用途 線位置的細分:−100 ~ +100,0 = 正中間,負 = 線在左(與線位置同號)
範圍 -100~+100
I2C/mBlock 編號 02
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 0 (edu) byte 2 −100 🔒;模式 0 (toy) byte 2 −100 🔒;模式 3 byte 0 −100;模式 4 v[0] −100;模式 7 v[0] 🔒;模式 9 v[5] lo −100 🔒。備註:byte2 = 細位置+100(0200)、byte3 = 0;App 原始紅讀成 int16; 細位置+100 經玩具版查表編碼成 byte23; 4 個 int16:第 1、2、4 格 = (細位置+100)×100 + 線寬(0~20016;Pybricks hsv(surface=False).h 讀第 1 格,原封不動);第 3 格 = (細位置+100)×100 + min(線寬,9)×10(Pybricks ambient() 讀這格:4.1.2 先 ÷10 去尾再 ÷10、3.6.1/4.0.0 ÷100,都得到 細位置+100 . 線寬,線寬最多顯示 9)。2026-10-30 起第 3 格改這個編碼

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

w = dev.read(9)[5]
linePosFine = (w & 0xFF) - 100   # 細位置(低 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_line16_obj_Lib import MBC_LINE16

line = MBC_LINE16(Port.A)
linePosFine = line.pos100()
EV3

模式 2 · int8 · IR-REMOTE byte0 = highRes−100 存成 int8(F16:745-751);模式 4 · int8 · #67 新:IR-S-ALT 內容同模式 2(原本不送)(已鎖住的模式,韌體與主機端都不再改)

from pybricks.iodevices import LUMPDevice
from pybricks.parameters import Port

sensor = LUMPDevice(Port.S1)   # 感應器插 1 號孔

linePosFine = sensor.read(2)[0]   # 細位置:-100~+100
linePosFine = sensor.read(4)[0]   # 細位置:-100~+100
' clev3r (BASIC)
Sensor.SetMode(1, 2)
linePosFine = Sensor.ReadRawValue(1, 0)
Sensor.SetMode(1, 4)
linePosFine = Sensor.ReadRawValue(1, 0)
Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t linePosFine = mbcRead(0x16, 0x02);   // 細位置:-100~+100
mBlock

積木傳回 細位置(-100~+100)。主機送 [02] → 回 [值低][值高][02 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 線的細位置 :: sensing)
MATRIX

0x22 B (+100)。

// A. 原廠 0x22 積木:B = 細位置 + 100
int linePosFine = MiniR4.I2C1.MXColor.getColor(B) - 100;
micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 細位置 :: #00A4E4)
let linePosFine = mbc.linePositionFine()   // 細位置:-100~+100

03 線寬 lineWidth

線寬
項目 內容
用途 壓到線的路數 0~16,0 = 找不到線
範圍 0~16 路
I2C/mBlock 編號 03
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 0 (edu) byte 0 🔒;模式 0 (toy) byte 1 🔒;模式 2 byte 0;模式 3 byte 1;模式 9 v[4] hi 🔒。備註:min(線寬, 10)

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

w = dev.read(9)[4]
lineWidth = ((w >> 8) & 0xFF)   # 線寬(高 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_line16_obj_Lib import MBC_LINE16

line = MBC_LINE16(Port.A)
lineWidth = line.width()
EV3

模式 2 · int8;模式 4 · int8 · #67 新:同模式 2(已鎖住的模式,韌體與主機端都不再改)

from pybricks.iodevices import LUMPDevice
from pybricks.parameters import Port

sensor = LUMPDevice(Port.S1)   # 感應器插 1 號孔

lineWidth = sensor.read(2)[1]   # 線寬:0~16 路
lineWidth = sensor.read(4)[1]   # 線寬:0~16 路
' clev3r (BASIC)
Sensor.SetMode(1, 2)
lineWidth = Sensor.ReadRawValue(1, 1)
Sensor.SetMode(1, 4)
lineWidth = Sensor.ReadRawValue(1, 1)
Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t lineWidth = mbcRead(0x16, 0x03);   // 線寬:0~16 路
mBlock

積木傳回 線寬(0~16 路)。主機送 [03] → 回 [值低][值高][03 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 線寬 :: sensing)
MATRIX

0x22 G。

// A. 原廠 0x22 積木:G = 線寬
int lineWidth = MiniR4.I2C1.MXColor.getColor(G);
micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 線寬 :: #00A4E4)
let lineWidth = mbc.lineWidth()   // 線寬:0~16 路

04 線段數 groupCount

線段數
項目 內容
用途 看到幾段線:0 丟線、1 一條線、2 以上 = 分岔/十字
範圍 0~8
I2C/mBlock 編號 04

怎麼讀

SPIKE

模式 9 v[5] hi 🔒

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

w = dev.read(9)[5]
groupCount = ((w >> 8) & 0xFF)   # 線段數(高 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_line16_obj_Lib import MBC_LINE16

line = MBC_LINE16(Port.A)
groupCount = line.junction()
EV3

EV3 模式沒有送這個值(EV3 封包以已鎖住的模式為準)。需要時改用 Arduino I2C/mBlock。

Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t groupCount = mbcRead(0x16, 0x04);   // 線段數:0~8
mBlock

積木傳回 線段數(0~8)。主機送 [04] → 回 [值低][值高][04 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 線段數 :: sensing)
MATRIX

MATRIX 原廠 0x22 積木沒有這個值。

micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 線段數 :: #00A4E4)
let groupCount = mbc.lineSegments()   // 線段數:0~8

相關積木「循行者 看到線?」

let lineSeen = mbc.lineSeen()

相關積木「當循行者 [丟線]」

mbc.onLineEvent(MbcLineEvent.Lost, function () {
})

05 壓線位元圖 bitmap

壓線位元圖
項目 內容
用途 bit0 = 第 1 路(最左)… bit15 = 第 16 路,1 = 那一路在線上
範圍 0~65535 bit
I2C/mBlock 編號 05

怎麼讀

SPIKE

模式 4 v[1];模式 9 v[6] 🔒。備註:binRaw 16 bit(byte2 低、byte3 高); byte12 低、byte13 高

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

bitmap = dev.read(9)[6]   # 壓線位元圖

MBC 函式庫

from pybricks.parameters import Port
from MBC_line16_obj_Lib import MBC_LINE16

line = MBC_LINE16(Port.A)
bitmap = line.bin_raw()
EV3

模式 3 · int16 · #67 新:IR-REM-A 1×int16 = 16 bit 位元圖(原本不送)

from pybricks.iodevices import LUMPDevice
from pybricks.parameters import Port

sensor = LUMPDevice(Port.S1)   # 感應器插 1 號孔

bitmap = sensor.read(3)[0]   # 壓線位元圖:0~65535 bit
' clev3r (BASIC)
Sensor.SetMode(1, 3)
bitmap = Sensor.ReadRawValue(1, 0)
Arduino I2C

這個值本身就可能是 −32768(最高位元 = 1,例如 0x8000),跟讀不到時回的 MBC_NONE 一樣,不要拿 −32768 判斷有沒有讀到:要分辨就改用 mbcReadMany(0x16, 0x05, 1, &bitmap),回傳 false 才是讀不到。

int16_t bitmap = mbcRead(0x16, 0x05);   // 壓線位元圖:0~65535 bit
mBlock

積木傳回 壓線位元圖(0~65535 bit)。主機送 [05] → 回 [值低][值高][05 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 壓線位元圖 :: sensing)
MATRIX

MATRIX 原廠 0x22 積木沒有這個值。

micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 壓線位元圖 :: #00A4E4)
let bitmap = mbc.lineBitmap()   // 壓線位元圖:0~65535 bit

相關積木「循行者 第 1 路在線上?」

let lineChannelOnLine = mbc.lineChannelOnLine(1)

06 最後離線方向 lastDir

項目 內容
用途 丟線前線最後在哪一側:−16 ~ +16(負 = 左),找回線後維持最後一次
範圍 -16~+16
I2C/mBlock 編號 06

怎麼讀

SPIKE

SPIKE 模式沒有送這個值(已鎖住的模式不再改)。需要時改用 Arduino I2C/mBlock。

EV3

EV3 模式沒有送這個值(EV3 封包以已鎖住的模式為準)。需要時改用 Arduino I2C/mBlock。

Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t lastDir = mbcRead(0x16, 0x06);   // 最後離線方向:-16~+16
mBlock

積木傳回 最後離線方向(-16~+16)。主機送 [06] → 回 [值低][值高][06 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 最後離線方向 :: sensing)
MATRIX

MATRIX 原廠 0x22 積木沒有這個值。

micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 最後離線方向 :: #00A4E4)
let lastDir = mbc.lineLastDirection()   // 最後離線方向:-16~+16

07 二值化門檻 threshold

項目 內容
用途 判斷「在線上」的光值門檻 1~99,預設 40(2026-11-03 以前出貨的韌體是 50);用 E4 改
範圍 1~99
I2C/mBlock 編號 07

怎麼讀

SPIKE

SPIKE 模式沒有送這個值(已鎖住的模式不再改)。需要時改用 Arduino I2C/mBlock。

EV3

EV3 模式沒有送這個值(EV3 封包以已鎖住的模式為準)。需要時改用 Arduino I2C/mBlock。

Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t threshold = mbcRead(0x16, 0x07);   // 二值化門檻:1~99
mBlock

積木傳回 二值化門檻(1~99)。主機送 [07] → 回 [值低][值高][07 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 門檻 :: sensing)
MATRIX

MATRIX 原廠 0x22 積木沒有這個值。

micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 門檻 :: #00A4E4)
let threshold = mbc.lineThreshold()   // 二值化門檻:1~99

08 校準完成次數 calibCount

項目 內容
用途 開機後完成校準的次數(按鈕校準也算)
範圍 0~255 次
I2C/mBlock 編號 08

怎麼讀

SPIKE

SPIKE 模式沒有送這個值(已鎖住的模式不再改)。需要時改用 Arduino I2C/mBlock。

EV3

EV3 模式沒有送這個值(EV3 封包以已鎖住的模式為準)。需要時改用 Arduino I2C/mBlock。

Arduino I2C

讀不到(沒接、位址錯)時回 MBC_NONE(−32768)。

int16_t calibCount = mbcRead(0x16, 0x08);   // 校準完成次數:0~255 次
mBlock

積木傳回 校準完成次數(0~255 次)。主機送 [08] → 回 [值低][值高][08 ^ 值低 ^ 值高],值 = int16 小端。

(循行者 連接埠 [1 v] 校準次數 :: sensing)
MATRIX

MATRIX 原廠 0x22 積木沒有這個值。

micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 校準次數 :: #00A4E4)
let calibCount = mbc.lineCalibrationCount()   // 校準完成次數:0~255 次

相關積木「循行者 校準中?」

let lineCalibrating = mbc.lineCalibrating()

10~1F 第 1~16 路光值 light

第 1~16 路光值
項目 內容
用途 第 116 路校準後光值 0100(第 1 路最左);編號 10~1F
範圍 0~100
I2C/mBlock 編號 10~1F
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 0 (edu) byte 4 🔒;模式 0 (toy) byte 4 🔒;模式 3 byte 2;模式 6 v[0];模式 8 v[0];模式 9 v[0] 🔒。備註:每路 2 bit((v×10)>>8:025→0、2651→1、5276→2、77100→3);byte4 = 第 58 路(第 5 路在 bit7-6)、byte5 = 第 14 路、byte6 = 第 1316 路、byte7 = 第 912 路 → App 原始綠 = 第 18 路(bit15-14 = 第 1 路)、原始藍 = 第 916 路;byte 815 = 0; 每路 1 bit(光值 ≥ 門檻(值 07,預設 40)= 1 亮,跟二值化判白同一個判斷;2026-11-03 以前的韌體是光值 > 50):第 18 路合成 1 byte(第 1 路在 bit7)經玩具版查表編碼成 byte45;第 916 路 → byte67; byte2 = 第 1 路、byte3 = 第 16 路(描述表只宣告 3×int8,第 4 byte 主機可能砍掉); byte05 = 第 611 路光值 → 3×int16,每個 lo = 前一路、hi = 後一路; byte03 = 第 710 路(只送 4 B); 每 int16 四路 4-bit((v×5)>>5,015):bit0-3 = 第 1 路、bit4-7 = 第 2 路、bit8-11 = 第 3 路、bit12-15 = 第 4 路;v0v3 = 第 116 路

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

words = dev.read(9)[0:4]
light = []
for w in words:
    for k in range(4):
        light.append((w >> (4 * k)) & 0x0F)   # 低位元在前

MBC 函式庫

from pybricks.parameters import Port
from MBC_line16_obj_Lib import MBC_LINE16

line = MBC_LINE16(Port.A)
light = line.ir_calibration()   # list,第 1 路 = [0]
EV3

模式 1 · int8 · IR-SEEK 8×int8 兩路壓一 byte:byte i = convert9(第 2i+1 路)×10 + convert9(第 2i+2 路)(1199;convert9:011→1、1222→2 … 89100→9,F16:716-723);模式 2 · int8 · index 2 = 第 1 路、index 3 = 第 16 路(0~100);模式 4 · int8 · #67 新:同模式 2(已鎖住的模式,韌體與主機端都不再改)

from pybricks.iodevices import LUMPDevice
from pybricks.parameters import Port

sensor = LUMPDevice(Port.S1)   # 感應器插 1 號孔

light = sensor.read(1)[0:8]   # 第 1~16 路光值
light = sensor.read(2)[2:4]   # 第 1~16 路光值
light = sensor.read(4)[2:4]   # 第 1~16 路光值
' clev3r (BASIC)
Sensor.SetMode(1, 1)
light1 = Sensor.ReadRawValue(1, 0)   ' 第 1 筆;第 N 筆改成 0 + N - 1
Sensor.SetMode(1, 2)
light1 = Sensor.ReadRawValue(1, 2)   ' 第 1 筆;第 N 筆改成 2 + N - 1
Sensor.SetMode(1, 4)
light1 = Sensor.ReadRawValue(1, 2)   ' 第 1 筆;第 N 筆改成 2 + N - 1
Arduino I2C

編號 0x10~0x1F 連號,一次 mbcReadMany 讀完保證同一瞬間。

int16_t light[16];
mbcReadMany(0x16, 0x10, 16, light);   // 第 1~16 路光值:0~100
for (uint8_t i = 0; i < 16; i++) { Serial.print(light[i]); Serial.print(' '); }
Serial.println();
mBlock

積木傳回 第 116 路光值(0100)。主機送 [10] → 回 [值低][值高][10 ^ 值低 ^ 值高],值 = int16 小端;第 N 路的編號 = 0x10 + (N − 1)。

(循行者 連接埠 [1 v] 第 [1 v] 路光值 :: sensing)
MATRIX

0x22 C~K。

// A. 原廠 0x22 積木:C~K = 第 1~16 路光值(C~K 四路一組,每路 2 bit(convert3:0~24→0、25~49→1、50~74→2、75~100→3):第 1 路在 bit7-6 … 第 4 路在 bit1-0;C = 第 1~4 路、M = 5~8、Y = 9~12、K = 13~16)
int raw = MiniR4.I2C1.MXColor.getColor(C);   // 第 1 組
micro:bit

感應器沒接好(讀不到)時回 0,先用「位址 … 的裝置就緒?」確認接線。

(循行者 第 (1) 路光值 :: #00A4E4)
let light = mbc.lineChannel(1)   // 第 1~16 路光值:0~100(N = 1~16)

寫入命令

只有 Arduino I2C、mBlock、micro:bit 能送命令;SPIKE/EV3 接頭是唯讀的。

E0 切黑線 blackLine

項目 內容
作用 追黑線(預設);存 RAM,重開機回預設
參數 無
忙碌旗標 無(立即生效)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE0)   # 切黑線
ok = line.wait_done()   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE0);   // 切黑線
mBlock

主機送 [E0] → 感應器回 [00][00][E0](收到了)再執行。

循行者 連接埠 [1 v] 切黑線 :: sensing
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit
循行者 循 [黑 v] 線 :: #00A4E4
mbc.lineSetColor(MbcLineColor.Black)   // 切黑線

E1 切白線 whiteLine

項目 內容
作用 追白線(F3 b1 = 1);存 RAM,重開機回預設
參數 無
忙碌旗標 無(立即生效)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE1)   # 切白線
ok = line.wait_done()   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE1);   // 切白線
mBlock

主機送 [E1] → 感應器回 [00][00][E1](收到了)再執行。

循行者 連接埠 [1 v] 切白線 :: sensing
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit
循行者 循 [白 v] 線 :: #00A4E4
mbc.lineSetColor(MbcLineColor.White)   // 切白線

E2 黑色校準 calibBlack

項目 內容
作用 把目前讀值記為黑(感應器壓在黑線上),約 50 ms;寫入 EEPROM
參數 無
忙碌旗標 F3 bit2(執行中 = 1)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE2)   # 黑色校準
ok = line.wait_done()   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE2);   // 黑色校準
while (mbcRead(0x16, 0xF3) & (1 << 2)) delay(10);   // 等 F3 bit2 歸零 = 做完
mBlock

主機送 [E2] → 感應器回 [00][00][E2](收到了)再執行;執行期間 F3 bit2 = 1。

循行者 連接埠 [1 v] 黑色校準 :: sensing
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit
循行者 校準 [目前讀值記為黑 v] :: #00A4E4
mbc.lineCalibrate(MbcLineCalib.Black)   // 黑色校準

E3 白色校準 calibWhite

項目 內容
作用 把目前讀值記為白(感應器壓在白底上),約 50 ms;寫入 EEPROM
參數 無
忙碌旗標 F3 bit2(執行中 = 1)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE3)   # 白色校準
ok = line.wait_done()   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE3);   // 白色校準
while (mbcRead(0x16, 0xF3) & (1 << 2)) delay(10);   // 等 F3 bit2 歸零 = 做完
mBlock

主機送 [E3] → 感應器回 [00][00][E3](收到了)再執行;執行期間 F3 bit2 = 1。

循行者 連接埠 [1 v] 白色校準 :: sensing
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit
循行者 校準 [目前讀值記為白 v] :: #00A4E4
mbc.lineCalibrate(MbcLineCalib.White)   // 白色校準

E4 設定門檻 setThreshold

項目 內容
作用 二值化門檻 1~99(RAM,重開機回預設 40);SPIKE 參數超出範圍回失敗(狀態 2)
參數 門檻 1~99(1 byte)
忙碌旗標 無(立即生效)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE4, 50)   # 設定門檻(門檻 1~99)
ok = line.wait_done()   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE4, 50);   // 設定門檻(門檻 1~99)
mBlock

主機送 [E4][參數…] → 感應器回 [00][00][E4](收到了)再執行。

循行者 連接埠 [1 v] 設定門檻 (50) :: sensing
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit
循行者 門檻設為 (50) :: #00A4E4
mbc.lineSetThreshold(50)   // 設定門檻

E7 5 秒動態校準 calibAuto

項目 內容
作用 5 秒內把感應器在黑線與白底上來回掃,取極值當黑白參考(共識 B-12,= v1 的 0x20=0x01);期間 F3 b2 = 1
參數 無
忙碌旗標 F3 bit2(執行中 = 1)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE7)   # 5 秒動態校準
ok = line.wait_done(8000)   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE7);   // 5 秒動態校準
while (mbcRead(0x16, 0xF3) & (1 << 2)) delay(10);   // 等 F3 bit2 歸零 = 做完
mBlock

主機送 [E7] → 感應器回 [00][00][E7](收到了)再執行;執行期間 F3 bit2 = 1。

循行者 連接埠 [1 v] 5 秒動態校準 :: sensing
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit
循行者 校準 [自動(來回掃 5 秒) v] :: #00A4E4
mbc.lineCalibrate(MbcLineCalib.Auto)   // 5 秒動態校準

E9 左右反向 reverse

項目 內容
作用 [0 正常/1 左右反向]:感應器反裝時用,通道順序與線位置左右對調;校準值照實體通道存,切換不用重校;存 RAM,重開機回 0(舊 mBlock 沒有);SPIKE 參數超出範圍回失敗(狀態 2)
參數 反向 0~1(1 byte)
忙碌旗標 無(立即生效)

怎麼送

SPIKE

Pybricks+MBC 函式庫才送得了(官方 App、內建 ColorSensor 積木不行);要 2026-10 以後的感應器韌體。

from pybricks.parameters import Port
from MBC_sensors import MBC_LINE16

line = MBC_LINE16(Port.A)
line.cmd(0xE9, 1)   # 左右反向(反向 0~1)
ok = line.wait_done()   # True=做完;False=失敗/拒絕/逾時
EV3

EV3 接頭沒有寫入命令;校準用感應器上的按鈕,設定用 Arduino I2C/mBlock。

Arduino I2C
mbcWrite(0x16, 0xE9, 1);   // 左右反向(反向 0~1)
MATRIX

MATRIX 原廠 0x22 積木沒有這個命令。

micro:bit

擴充沒有這顆積木;在 JavaScript 用 mbc.writeCmd(0x16, 0xE9, [參數])。

狀態旗標 F3

F3 每個 bit 一個狀態;I2C、mBlock、micro:bit 直接讀。

bit 名稱 說明
b0 就緒 (ready) 恆 1
b1 白線模式 (whiteMode) 1 = 正在追白線
b2 校準中 (calibrating) E2/E3/E7 執行中;此時拒收新的校準命令
b3 丟線 (lost) 線段數 = 0
b4 分岔 (fork) 線段數 ≥ 2
b5 左右反向 (reversed) E9 = 1(感應器反裝,左右對調)
SPIKE

SPIKE 沒有 F3 旗標;模式 8 回裝置 ID/版本。官方 App 讀不到模式 8。

from pybricks.iodevices import PUPDevice
from pybricks.parameters import Port

dev = PUPDevice(Port.A)   # 感應器插 A 孔

id_word, proto, fw, seq = dev.read(8)   # 模式 8:[ID | hw0<<8, 協議版 2, 主版×100+次版, 更新序號]
addr = id_word & 0xFF   # 0x16
hw0 = id_word >> 8      # 16
EV3

EV3 沒有 F3 旗標;模式 5 回裝置 ID 與韌體版本(ID 格式 B)。

from pybricks.iodevices import LUMPDevice
from pybricks.parameters import Port

sensor = LUMPDevice(Port.S1)   # 感應器插 1 號孔

id_word, fw = sensor.read(5)   # 模式 5:[ID | hw0<<8, 主版×100+次版]
addr = id_word & 0xFF             # 0x16
hw0 = id_word >> 8                # 16
Arduino I2C
int16_t st = mbcRead(0x16, 0xF3);
bool ready = st & (1 << 0);   // 就緒
bool whiteMode = st & (1 << 1);   // 白線模式
bool calibrating = st & (1 << 2);   // 校準中
bool lost = st & (1 << 3);   // 丟線
bool fork = st & (1 << 4);   // 分岔
bool reversed = st & (1 << 5);   // 左右反向
mBlock

狀態旗標 F3 的各 bit 由擴展拆成布林積木(就緒、校準中…)。

<循行者 連接埠 [1 v] 連線正常? :: sensing>
MATRIX

MATRIX 原廠 0x22 積木讀不到狀態旗標。

micro:bit
<位址 (0x16 v) 的裝置就緒? :: #00A4E4>
let ready = mbc.deviceReady(0x16)   // F3 bit0;沒接 = false
let st = mbc.status(0x16)   // F3

共用暫存器與命令

所有產品相同,只在 通用 I2C 協議 寫一次:

編號 名稱 說明
F0 裝置 ID 低 byte = 出廠 I2C 位址(換位址後不變),高 byte = hw[0](通道數/顆數/類別)
F1 協議版本 本版 = 2(SPIKE 模式 8 v[1]、EV3 ID 封包同一個數字)
F2 韌體版本 主版×100 + 次版(例 102 = 1.2)
F3 狀態旗標 b0 就緒,其餘各產品定義(見各產品 flags)
F4 更新序號 每 10 ms 快照 +1,0~255 循環(2.56 秒一圈,不能拿來偵測重開機;不動 = 模組忙)
F5 開機秒數 開機後秒數,到 32767 停住(約 9 小時);數字變小 = 重開機過
F8 換 I2C 位址 [F8][新位址 0x08~0x77][新位址取反],存 EEPROM,重開機後生效;[F8][0x00][0xFF] = 回出廠位址(共識 B-5)
EF 重新開機 [EF][0xA5];mBlock 先回 ACK 再重開

本頁依據與假設

本頁由 _build/gen-reference.mjs 從 _build/protocol/line16.json(單一真相來源,轉錄自 2026-10-21 協定定案)產生。

  • B-11:細位置 02 與線位置 01 同號(負 = 左);韌體 F16:1290 註解寫反,程式碼同號(IR:11 為準)。
  • B-12:E7 五秒動態校準補回(v1 的 0x20=0x01),定案表沒列。
  • EV3:模式 0~2 鎖住;模式 3 原本不送 → 16 bit 位元圖;模式 4 原本不送 → 同模式 2;模式 5 ID 格式 B(共用函式)。
  • SPIKE:0/5/7/9 鎖住,14、6 維持不動;教育版模式 0 的 16 路光值是 2-bit(玩具版 1-bit),跟 8 路的 4-bit 不同;byte 815 補 0(#65 已改,使用者保留);模式 9 排法照盤點(四路 4-bit 一個 int16,v6 = 位元圖);模式 8 v[0] 改 ID|hw[0]<<8。
  • 線段數 04 範圍:定案沒寫,16 路最多 8 段(交錯壓線),採 0~8。
  • mBlock 舊版:MBC_MBLOCK_LEGACY=1 時逐 byte 同 2026-10-21 統一後韌體(0x01 位置、0x02 線寬、n<<4|03 反向兩路壓一 byte、0x07 細位置 0~200),0x0B 回 1(B-1)。
  • Flash:C031 硬體鎖 28 KB,I2C 版餘 848 B;不夠時照 B-17 順序瘦身,JSON 不受影響。
LINE 詢價選購指南