這頁內容已整合到新的說明頁:測距者 2 路

測距者 2 路 指令參考

回到測距者 2 路產品頁

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

SPIKEEV3Arduino I2CmBlockMATRIXmicro:bit

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

值一覽

編號 值 範圍 SPIKE EV3 Arduino I2C mBlock MATRIX micro:bit
01 左距離 cm 0~120 cm ✓ ✓ ✓ ✓ ✓ ✓
02 右距離 cm 0~120 cm ✓ ✓ ✓ ✓ ✓ ✓
03 較近距離 cm 0~120 cm — — ✓ ✓ ✓ ✓
04 左距離 mm 0~1200 mm ✓ ✓ ✓ ✓ — ✓
05 右距離 mm 0~1200 mm ✓ ✓ ✓ ✓ — ✓
06 初始化位元圖 0~3 bit ✓ — ✓ ✓ — ✓
07 故障位元圖 0~3 bit ✓ — ✓ ✓ — ✓
08 左右平均 mm 0~1200 mm ✓ ✓ ✓ ✓ — ✓

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

每個值怎麼讀

01 左距離 cm leftCm

左距離 cm
項目 內容
用途 左邊那顆的距離 0~120 cm(站在車後往前看,左 = 第 0 顆),120 = 前面沒東西/那顆失效
範圍 0~120 cm
I2C/mBlock 編號 01
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 0 (edu) byte 0 🔒;模式 0 (toy) byte 0 🔒;模式 1 byte 0;模式 2 byte 0;模式 3 byte 0 🔒;模式 4 v[0] lo;模式 5 v[0] 🔒;模式 8 v[0] lo;模式 9 v[0] lo 🔒。備註:16 B = [左, 右, 0, 左, 0, 右, 0, 平均, 0×8]:App 顏色 = 左、原始紅 = 256×左; 8 B 原樣(不壓縮); 韌體註解寫「最近」,實際送左(INO:261-263); 網站 read(3) 在用:[左, 右, 0]; Pybricks reflection() 編碼:L = 左 cm,a = L/25、b = 10×(L mod 25)+9,3 個 int16 = a×256+b → reflection() = L; 只送 4 B,v0 = 左 + 256×右

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

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

w = dev.read(9)[0]
leftCm = (w & 0xFF)   # 左距離 cm(低 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
leftCm = laser.left()
EV3

模式 1 · int8 · #67 新:IR-SEEK 8×int8 = [左, 右, 左, 右, 左, 右, 左, 右](index 0/2/4/6 = 左;原本 index 2~7 = 0);模式 2 · int8 · IR-REMOTE [左, 右, 0, 0](INO:137-139);模式 4 · int8 · IR-S-ALT 同模式 2(已鎖住的模式,韌體與主機端都不再改)

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

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

leftCm = sensor.read(1)[0]   # 左距離 cm:cm×100/120(0~100)
leftCm = sensor.read(2)[0]   # 左距離 cm:cm×100/120(0~100)
leftCm = sensor.read(4)[0]   # 左距離 cm:cm×100/120(0~100)
' clev3r (BASIC)
Sensor.SetMode(1, 1)
leftCm = Sensor.ReadRawValue(1, 0)
Sensor.SetMode(1, 2)
leftCm = Sensor.ReadRawValue(1, 0)
Sensor.SetMode(1, 4)
leftCm = Sensor.ReadRawValue(1, 0)
Arduino I2C

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

int16_t leftCm = mbcRead(0x29, 0x01);   // 左距離 cm:0~120 cm
mBlock

積木傳回 左距離 cm(0~120 cm)。主機送 [01] → 回 [值低][值高][01 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 左距離 cm :: sensing)
MATRIX

0x22 R。

// A. 原廠 0x22 積木:R = 左距離 cm
int leftCm = MiniR4.I2C1.MXColor.getColor(R);
micro:bit

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

(測距者 2 路 [左 v] 距離([公分 v]) :: #00A4E4)
let leftCm = mbc.tof2Distance(MbcTofSide.Left, MbcDistUnit.Cm)   // 左距離 cm:0~120 cm

02 右距離 cm rightCm

右距離 cm
項目 內容
用途 右邊那顆的距離 0~120 cm(右 = 第 1 顆),120 = 前面沒東西/那顆失效
範圍 0~120 cm
I2C/mBlock 編號 02
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 0 (edu) byte 1 🔒;模式 0 (toy) byte 1 🔒;模式 3 byte 1 🔒;模式 4 v[0] hi;模式 7 v[2] 🔒;模式 8 v[0] hi;模式 9 v[0] hi 🔒。備註:App 反射光 = 右、原始綠 = 256×右; 網站 read(3) 在用; Pybricks ambient() = int16[2]/100 = 右 cm(INO:300-312)

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

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

w = dev.read(9)[0]
rightCm = ((w >> 8) & 0xFF)   # 右距離 cm(高 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
rightCm = laser.right()
EV3

模式 1 · int8 · #67 新:index 1/3/5/7 = 右;模式 2 · int8;模式 4 · int8(已鎖住的模式,韌體與主機端都不再改)

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

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

rightCm = sensor.read(1)[1]   # 右距離 cm:cm×100/120(0~100)
rightCm = sensor.read(2)[1]   # 右距離 cm:cm×100/120(0~100)
rightCm = sensor.read(4)[1]   # 右距離 cm:cm×100/120(0~100)
' clev3r (BASIC)
Sensor.SetMode(1, 1)
rightCm = Sensor.ReadRawValue(1, 1)
Sensor.SetMode(1, 2)
rightCm = Sensor.ReadRawValue(1, 1)
Sensor.SetMode(1, 4)
rightCm = Sensor.ReadRawValue(1, 1)
Arduino I2C

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

int16_t rightCm = mbcRead(0x29, 0x02);   // 右距離 cm:0~120 cm
mBlock

積木傳回 右距離 cm(0~120 cm)。主機送 [02] → 回 [值低][值高][02 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 右距離 cm :: sensing)
MATRIX

0x22 G。

// A. 原廠 0x22 積木:G = 右距離 cm
int rightCm = MiniR4.I2C1.MXColor.getColor(G);
micro:bit

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

(測距者 2 路 [右 v] 距離([公分 v]) :: #00A4E4)
let rightCm = mbc.tof2Distance(MbcTofSide.Right, MbcDistUnit.Cm)   // 右距離 cm:0~120 cm

03 較近距離 cm nearCm

較近距離 cm
項目 內容
用途 左右兩顆取較近的 0~120 cm
範圍 0~120 cm
I2C/mBlock 編號 03
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

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

EV3

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

Arduino I2C

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

int16_t nearCm = mbcRead(0x29, 0x03);   // 較近距離 cm:0~120 cm
mBlock

積木傳回 較近距離 cm(0~120 cm)。主機送 [03] → 回 [值低][值高][03 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 較近距離 cm :: sensing)
MATRIX

0x22 B。

// A. 原廠 0x22 積木:B = 較近距離 cm(B(命令 12 也回較近,schema 不收 12))
int nearCm = MiniR4.I2C1.MXColor.getColor(B);
micro:bit

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

(測距者 2 路 較近距離(公分) :: #00A4E4)
let nearCm = mbc.tof2NearestCm()   // 較近距離 cm:0~120 cm

相關積木「當測距者 2 路 距離小於 10 公分」

mbc.onTof2Near(10, function () {
})

04 左距離 mm leftMm

左距離 mm
項目 內容
用途 左邊那顆的距離 0~1200 mm,1200 = 前面沒東西/那顆失效
範圍 0~1200 mm
I2C/mBlock 編號 04

怎麼讀

SPIKE

模式 6 v[0]。備註:#67 新:HSV 3×int16 = [左 mm, 右 mm, 平均 mm](原本是基底緩衝合併值)

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

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

leftMm = dev.read(6)[0]   # 左距離 mm

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
leftMm = laser.left_mm()
EV3

模式 5 · int16 · #67 新:IR-CAL 2×int16 = [左 mm, 右 mm](原本 word0 = 左'+256×右')

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

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

leftMm = sensor.read(5)[0]   # 左距離 mm:0~1200 mm
' clev3r (BASIC)
Sensor.SetMode(1, 5)
leftMm = Sensor.ReadRawValue(1, 0)
Arduino I2C

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

int16_t leftMm = mbcRead(0x29, 0x04);   // 左距離 mm:0~1200 mm
mBlock

積木傳回 左距離 mm(0~1200 mm)。主機送 [04] → 回 [值低][值高][04 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 左距離 mm :: sensing)
MATRIX

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

micro:bit

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

(測距者 2 路 [左 v] 距離([公釐 v]) :: #00A4E4)
let leftMm = mbc.tof2Distance(MbcTofSide.Left, MbcDistUnit.Mm)   // 左距離 mm:0~1200 mm

05 右距離 mm rightMm

右距離 mm
項目 內容
用途 右邊那顆的距離 0~1200 mm,1200 = 前面沒東西/那顆失效
範圍 0~1200 mm
I2C/mBlock 編號 05

怎麼讀

SPIKE

模式 6 v[1]。備註:#67 新

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

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

rightMm = dev.read(6)[1]   # 右距離 mm

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
rightMm = laser.right_mm()
EV3

模式 5 · int16 · #67 新

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

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

rightMm = sensor.read(5)[1]   # 右距離 mm:0~1200 mm
' clev3r (BASIC)
Sensor.SetMode(1, 5)
rightMm = Sensor.ReadRawValue(1, 1)
Arduino I2C

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

int16_t rightMm = mbcRead(0x29, 0x05);   // 右距離 mm:0~1200 mm
mBlock

積木傳回 右距離 mm(0~1200 mm)。主機送 [05] → 回 [值低][值高][05 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 右距離 mm :: sensing)
MATRIX

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

micro:bit

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

(測距者 2 路 [右 v] 距離([公釐 v]) :: #00A4E4)
let rightMm = mbc.tof2Distance(MbcTofSide.Right, MbcDistUnit.Mm)   // 右距離 mm:0~1200 mm

06 初始化位元圖 initOk

初始化位元圖
項目 內容
用途 bit0 = 左、bit1 = 右,1 = 那顆開機初始化成功(失敗不重試);3 = 兩顆都好
範圍 0~3 bit
I2C/mBlock 編號 06
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 9 v[1] lo 🔒

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

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

w = dev.read(9)[1]
initOk = (w & 0xFF)   # 初始化位元圖(低 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
initOk = laser.is_ok(1)
EV3

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

Arduino I2C

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

int16_t initOk = mbcRead(0x29, 0x06);   // 初始化位元圖:0~3 bit
mBlock

積木傳回 初始化位元圖(0~3 bit)。主機送 [06] → 回 [值低][值高][06 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 初始化位元圖 :: sensing)
MATRIX

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

micro:bit

擴充沒有這顆積木;在 JavaScript 用 mbc.readValue(位址, 編號) 讀(讀不到 = −32768)。相關積木:「測距者 2 路 [左] 感應器正常?」。

let initOk = mbc.readValue(0x29, 0x06)   // 初始化位元圖:0~3 bit

07 故障位元圖 fault

故障位元圖
項目 內容
用途 bit0 = 左、bit1 = 右,1 = 那顆目前失效(I2C 讀失敗或 200 ms 沒更新);失效那顆距離回 120/1200
範圍 0~3 bit
I2C/mBlock 編號 07
鎖住 🔒 已鎖住的樂高模式排法不再改

怎麼讀

SPIKE

模式 9 v[1] hi 🔒

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

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

w = dev.read(9)[1]
fault = ((w >> 8) & 0xFF)   # 故障位元圖(高 byte)

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
fault = laser.is_ok(1)
EV3

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

Arduino I2C

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

int16_t fault = mbcRead(0x29, 0x07);   // 故障位元圖:0~3 bit
mBlock

積木傳回 故障位元圖(0~3 bit)。主機送 [07] → 回 [值低][值高][07 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 故障位元圖 :: sensing)
MATRIX

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

micro:bit

擴充沒有這顆積木;在 JavaScript 用 mbc.readValue(位址, 編號) 讀(讀不到 = −32768)。相關積木:「測距者 2 路 [左] 感應器正常?」。

let fault = mbc.readValue(0x29, 0x07)   // 故障位元圖:0~3 bit

08 左右平均 mm avgMm

左右平均 mm
項目 內容
用途 (左 mm + 右 mm) / 2,0~1200;跟 EV3 模式 3、SPIKE 模式 6 第 3 個值一致(共識 #8 補上)
範圍 0~1200 mm
I2C/mBlock 編號 08

怎麼讀

SPIKE

模式 0 (edu) byte 7 🔒;模式 6 v[2]。備註:byte7 = (左 cm + 右 cm)>>1;App 原始藍 = 256×平均; #67 新:平均 mm

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

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

avgMm = dev.read(0)[7]   # 左右平均 mm

MBC 函式庫

from pybricks.parameters import Port
from MBC_laser2_obj_Lib import MBC_LASER2

laser = MBC_LASER2(Port.A)
avgMm = laser.average_mm()
EV3

模式 0 · int8 · IR-PROX = (左'+右')>>1,cm 縮放後平均(鎖住,INO:131-133);模式 3 · int16 · #67 新:IR-REM-A 1×int16 = 左右平均 mm(原本 = 左 0~100)(已鎖住的模式,韌體與主機端都不再改)

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

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

avgMm = sensor.read(0)[0]   # 左右平均 mm:cm 平均 ×100/120(0~100)
avgMm = sensor.read(3)[0]   # 左右平均 mm:0~1200 mm
' clev3r (BASIC)
Sensor.SetMode(1, 0)
avgMm = Sensor.ReadRawValue(1, 0)
Sensor.SetMode(1, 3)
avgMm = Sensor.ReadRawValue(1, 0)
Arduino I2C

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

int16_t avgMm = mbcRead(0x29, 0x08);   // 左右平均 mm:0~1200 mm
mBlock

積木傳回 左右平均 mm(0~1200 mm)。主機送 [08] → 回 [值低][值高][08 ^ 值低 ^ 值高],值 = int16 小端。

(測距者 2 路 連接埠 [1 v] 左右平均 mm :: sensing)
MATRIX

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

micro:bit

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

(測距者 2 路 平均距離(公釐) :: #00A4E4)
let avgMm = mbc.tof2AverageMm()   // 左右平均 mm:0~1200 mm

狀態旗標 F3

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

bit 名稱 說明
b0 就緒 (ready) 2 顆都初始化完、快照開始更新後恆 1
b1 任一顆失效 (fault) 初始化失敗、I2C 讀失敗或 200 ms 沒更新,任一顆就是 1(= 07 ≠ 0 或 06 ≠ 3)
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   # 0x29
hw0 = id_word >> 8      # 2
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             # 0x29
hw0 = id_word >> 8                # 2
Arduino I2C
int16_t st = mbcRead(0x29, 0xF3);
bool ready = st & (1 << 0);   // 就緒
bool fault = st & (1 << 1);   // 任一顆失效
mBlock

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

<測距者 2 路 連接埠 [1 v] 連線正常? :: sensing>
MATRIX

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

micro:bit
<位址 (0x29 v) 的裝置就緒? :: #00A4E4>
let ready = mbc.deviceReady(0x29)   // F3 bit0;沒接 = false
let st = mbc.status(0x29)   // 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/tof2.json(單一真相來源,轉錄自 2026-10-21 協定定案)產生。

  • 共識 #8:08 左右平均 mm 補進 I2C/mBlock 值表(定案 §5 已列)。
  • 0x22 命令 412 不動(4 左、5 右、6 最近、711 = 0、12 = 最近);schema 不收 11/12,所以 12 只寫在 03 的 note。
  • EV3:模式 0、2、4 鎖住(照盤點);模式 1 改 [左,右]×4(index 0/1 各代表左右)、模式 3 改平均 mm、模式 5 改 [左 mm, 右 mm];模式 1 描述表宣告 int8 −100~100,cm×100/120 在範圍內。
  • SPIKE:0/5/7/9 鎖住,另加模式 3 鎖住(網站 sensors/tof2/index.md read(3) = 左/右 cm,共識 #11);模式 6 改 [左 mm, 右 mm, 平均 mm];模式 1、2、4、8 維持不動;模式 8 v[0] 改 ID|hw[0]<<8(統一後共用函式)。
  • 「左」= 站在車後往前看的左(第 0 顆,XSHUT PA6);韌體只有 L/R 巨集名,盤點檔標為推測。
  • 沒有寫入命令;F8 換位址/EF 重開機用共用的。
LINE 詢價選購指南