循行者 8 路 (Line8) × micro:bit × MakeCode

互動教學micro:bit

第一次用?先跟著互動教學在網頁上做一遍,再照下面的步驟接主機。

這一頁只講 MakeCode(積木/JavaScript):在 BBC micro:bit V1/V2 上用它讀循行者 8 路 (Line8)的安裝步驟、每個值怎麼讀、能用的命令與範例。要換產品、主機或軟體,用上方的切換列。

要買哪個版本、怎麼接

買 通用 I2C 版,接 micro:bit 擴充板的 I2C 孔(SDA = P20、SCL = P19),出廠位址 0x16。這款耗電小,VCC 可以先接 micro:bit 的 3V 腳(V1 約 90 mA、V2 約 190 mA);用電池供電時電壓可能掉到 3 V 以下,不穩就改外接 5 V(GND 要和 micro:bit 共地)。

循行者 8 路 (Line8) × BBC micro:bit V1/V2

安裝與設定

你需要

  • 感應器:循行者 8 路 (Line8)(通用 I2C 版)。SPIKE 版、EV3 版韌體不同,接 micro:bit 讀不到。
  • 主板:BBC micro:bit V1 或 V2,加上能接到 P19/P20 的擴充板或鱷魚夾轉接板。
  • 軟體:MakeCode 網頁版(makecode.microbit.org,積木/JavaScript);離線版(Windows/Mac App)也可以,第一次加擴充要連網。
  • 擴充:pxt-mbc-sensors v2(MIT,免下載,貼網址就能加)。

重要

上機待測:擴充 v2.0.5 已在 MakeCode 編譯通過(V1+V2),還沒有接實機逐顆積木核對數值。積木名稱以 GitHub 發布版 為準。

安裝軟體

  1. 打開 makecode.microbit.org → 新專案。
  2. 編輯器語言切到 繁體中文(右上齒輪 → Language),積木就會顯示中文。

讓軟體認得感應器

  1. 點積木區下方的 進階 → 擴充(齒輪選單裡也有「擴充」)。
  2. 在搜尋框貼上 https://github.com/contactmbcrobot/pxt-mbc-sensors,按 Enter。
  3. 點出現的 mbc-sensors 卡片,積木區會多出「MBC 感應器」分類(循行者、測距者、掌控者、陀螺儀、神攝手、裝置六組)。
  4. 用範例:右上切到 JavaScript → 貼上範例 → 下載 .hex 拖進 MICROBIT 磁碟。

提示

不需要送審、不需要下載檔案:老師把網址給學生貼就能用。要固定版本可貼 https://github.com/contactmbcrobot/pxt-mbc-sensors#v2.0.5。

接線

micro:bit 的 I2C 腳位是固定的:P19 = SCL、P20 = SDA(金手指邊緣接頭,要用擴充板或鱷魚夾轉接板才接得到)。MBC 4P 感應器線的 TX 接 SCL、RX 接 SDA,跟接 Arduino 是同一條線。

感應器 micro:bit 說明
SCL(TX) P19 I2C 時脈
SDA(RX) P20 I2C 資料
VCC 3V 或外部 5 V 耗電大的產品不能吃 micro:bit 的 3V
GND GND 外部供電時 GND 要和 micro:bit 共地
  • 3V 腳電流:V1 約 90 mA、V2 約 190 mA;用電池時電壓可能掉到 2 V 多。測距者 8 路、掌控者 PS4/PS5、神攝手 一定要外部 5 V;其他產品可先試 3V,電池供電時建議外部 5 V。
  • 電壓準位:MBC 產品的 I2C 線是 3.3 V 準位,跟 micro:bit 相容,不需要準位轉換。
  • 這個產品的出廠位址是 0x16;位址不同的產品可以串在同一組 P19/P20 上。

先校準(只要做一次)

循行者要先「認識」你場地上的黑色和白色,數值才會準。校準完會記在感應器裡,重新開機也還在(除非換場地)。

  1. 感應器插好、主機開機(感應器的燈亮起來)。
  2. 按住感應器上的校準按鈕約 0.5 秒再放開(不要一直按著,按著不放會一直重新校準)。
  3. 綠色校準指示燈(靠近校準按鈕)亮起後,5 秒內把感應器在黑線和白色地面之間來回掃幾次,8 個感應點都要掃過最黑的黑線和最白的白色區域。
  4. 掃的時候感應器離地 3~12 mm,太高會讀不準。
  5. 綠燈熄滅=校準完成,數值自動存進感應器。

怎麼知道校準好了? 放在白色地面時「線寬」是 0,壓在一般黑線上是 2~3。

提示

也可以用積木校準:「循行者 校準 …」選「記為黑」(E2)、「記為白」(E3)或「5 秒動態掃描」(E7),結果存進感應器。

第一次測試

  1. 先用「裝置 → 等位址 0x16 的裝置就緒」或「位址 0x16 的裝置就緒?」積木確認接線。
  2. 下載本頁範例 1 的 .hex 到 micro:bit。
  3. LED 顯示的數字跟著感應器前方的東西變化,就是接好了。

常見問題

  • 讀值一直是 0? 裝置沒接時讀值積木回 0(內部的 −32768 已過濾)、是/否積木一律回「否」,不會報錯。依序檢查:接線(SDA=P20、SCL=P19)→ 外接電源有沒有開 →「位址 … 的裝置就緒?」是不是 true。
  • V1 的指南針、加速度計也壞了? V1 的 I2C 線和板上加速度計共用,感應器卡住 SDA 會連帶讓它們失效;V2 把外部 I2C 分開了。
  • 時好時壞? STM32 產品(循行者、測距者、PS2、陀螺儀)會時脈延展,micro:bit V2 的 nRF52 對此有已知問題(errata 219),V1/V2 都要實測;ESP32 產品(PS4、神攝手)不延展,擴充已內建「寫完編號等 2 ms 再讀」。
  • 兩個同類產品一起接? 同類產品位址相同,先用「裝置 → 把位址 … 的裝置改成位址 …」把其中一個改掉(重開機生效),再用該產品的「改用位址」積木告訴擴充新位址。

讀值

MakeCode 加入 pxt-mbc-sensors 擴充後,在「MBC 感應器」分類找積木;JavaScript 寫法一併列出,位址 0x16。

線位置 linePos

線位置
範圍 意思
-8~+8 線在哪一路:−8(最左)~+8(最右),0 = 正中間;站在車後往前看,負 = 線在左
(循行者 線位置 :: #00A4E4)
let linePos = mbc.linePosition()   // 線位置:-8~+8

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

細位置 linePosFine

細位置
範圍 意思
-100~+100 線位置的細分:−100 ~ +100,0 = 正中間,負 = 線在左(與線位置同號)
(循行者 細位置 :: #00A4E4)
let linePosFine = mbc.linePositionFine()   // 細位置:-100~+100

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

線寬 lineWidth

線寬
範圍 意思
0~8 路 壓到線的路數 0~8,0 = 找不到線
(循行者 線寬 :: #00A4E4)
let lineWidth = mbc.lineWidth()   // 線寬:0~8 路

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

線段數 groupCount

線段數
範圍 意思
0~4 看到幾段線:0 丟線、1 一條線、2 以上 = 分岔/十字
(循行者 線段數 :: #00A4E4)
let groupCount = mbc.lineSegments()   // 線段數:0~4

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

let lineSeen = mbc.lineSeen()

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

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

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

壓線位元圖 bitmap

壓線位元圖
範圍 意思
0~255 bit bit0 = 第 1 路(最左)… bit7 = 第 8 路,1 = 那一路在線上
(循行者 壓線位元圖 :: #00A4E4)
let bitmap = mbc.lineBitmap()   // 壓線位元圖:0~255 bit

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

let lineChannelOnLine = mbc.lineChannelOnLine(1)

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

最後離線方向 lastDir

範圍 意思
-8~+8 丟線前線最後在哪一側:−8 ~ +8(負 = 左),找回線後維持最後一次
(循行者 最後離線方向 :: #00A4E4)
let lastDir = mbc.lineLastDirection()   // 最後離線方向:-8~+8

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

二值化門檻 threshold

範圍 意思
1~99 判斷「在線上」的光值門檻 1~99,預設 50;用 E4 改
(循行者 門檻 :: #00A4E4)
let threshold = mbc.lineThreshold()   // 二值化門檻:1~99

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

校準完成次數 calibCount

範圍 意思
0~255 次 開機後完成校準的次數(按鈕校準也算)
(循行者 校準次數 :: #00A4E4)
let calibCount = mbc.lineCalibrationCount()   // 校準完成次數:0~255 次

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

let lineCalibrating = mbc.lineCalibrating()

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

第 1~8 路光值 light

第 1~8 路光值
範圍 意思
0~100 第 18 路校準後光值 0100(第 1 路最左);編號 10~17
(循行者 第 (1) 路光值 :: #00A4E4)
let light = mbc.lineChannel(1)   // 第 1~8 路光值:0~100(N = 1~8)

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

命令

切黑線 blackLine

追黑線(預設);存 RAM,重開機回預設

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

切白線 whiteLine

追白線(F3 b1 = 1);存 RAM,重開機回預設

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

黑色校準 calibBlack

把目前讀值記為黑(感應器壓在黑線上),約 50 ms;寫入 EEPROM

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

白色校準 calibWhite

把目前讀值記為白(感應器壓在白底上),約 50 ms;寫入 EEPROM

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

設定門檻 setThreshold

二值化門檻 1~99(RAM,重開機回預設 50);SPIKE 參數超出範圍回失敗(狀態 2)

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

5 秒動態校準 calibAuto

5 秒內把感應器在黑線與白底上來回掃,取極值當黑白參考(共識 B-12,= v1 的 0x20=0x01);期間 F3 b2 = 1

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

左右反向 reverse

[0 正常/1 左右反向]:感應器反裝時用,通道順序與線位置左右對調;校準值照實體通道存,切換不用重校;存 RAM,重開機回 0(舊 mBlock 沒有);SPIKE 參數超出範圍回失敗(狀態 2)

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

範例

這一頁是寫給完全沒寫過程式的人。5 個範例從「LED 顯示讀值」開始,一步一步做到「開車」。全部用 MakeCode 網頁版+MBC 擴充 pxt-mbc-sensors v2 寫:切到 JavaScript 把範例貼上就能用,也可以切回積木模式看它變成哪些積木。

重要

  • 擴充 pxt-mbc-sensors v2 還沒上機驗證。本頁的範例都在電腦上用 MakeCode CLI 編譯通過(V1+V2 各一次),數值方向、就緒時間、供電等實機結果見下方「硬體關卡」的「上機待測」。
  • 請用 通用 I2C 版的產品。SPIKE 版、EV3 版韌體不同,接 micro:bit 讀不到。

軟體對照表

寫法 micro:bit V1 micro:bit V2 怎麼用
MakeCode 網頁版(makecode.microbit.org,積木/JavaScript) ✔(記憶體較小,本頁範例都編得過) ✔ 新專案 → 齒輪 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 右上切到 JavaScript → 貼上範例 → 下載 .hex 拖進 MICROBIT 磁碟
MakeCode 離線版(Windows/Mac App) ✔ ✔ 同上;第一次加擴充要連網
Python Editor(MicroPython) — — 還沒有 MBC 模組
  • 聲音:V2 有內建喇叭;V1 要在 P0 接蜂鳴器或耳機才有聲音。
  • 伺服/馬達:範例用 pins.servoWritePin,一顆 9g 伺服(SG90)接 P1;開車用兩顆連續旋轉伺服(FS90R 之類),左輪 P1、右輪 P2。伺服電源一律外接 4.8~6 V 電池盒,電池負極要和 micro:bit GND 接在一起(共地);不要從 micro:bit 3V 腳推伺服。
  • 積木文字:MakeCode 語言切成繁體中文,擴充的積木就是中文(例如「循行者 線位置」);本頁表格同時列出中文積木和 JavaScript 寫法。

開始之前:硬體關卡(上機待測)

micro:bit 是 3.3 V 的板子,接 MBC 產品前每一關都要過;打「上機待測」的是擴充 v2 還沒在實機確認的項目。

關卡 這款產品 狀態
電壓 MBC 產品的 I2C 都是 3.3 V 準位,直接接 P19/P20,不用準位轉換 ✔
供電 約 30 mA,可以先試 micro:bit 的 3V 腳(V1 約 90 mA、V2 約 190 mA 上限);用電池盒供電時電壓可能掉到 3 V 以下,不穩就外接 5 V 上機待測
I2C 上拉 micro:bit 板上已有 4.7 kΩ;產品板若也有上拉,並聯後要確認低電位 ≤ 0.3×VDD 上機待測
時脈延展 STM32 從機預設會時脈延展,V2(nRF52833)對延展有已知問題,要 V1、V2 各測一次 上機待測
位址衝突 出廠位址 0x16;接兩個循行者要先用「裝置」分類的「改成位址」積木換掉一個 —
就緒時間 開機後馬上就緒(F3 b0 恆 1) 上機待測

讀不到值時先看:接線(SDA=P20、SCL=P19)→ 外接電源有沒有開 → 擴充「裝置」分類的「位址 … 的裝置就緒?」積木是不是 true。

接線(所有範例共用)

循行者 8 路 × micro:bit
感應器 micro:bit
SDA P20
SCL P19
VCC 3V(或外接 5 V)
GND GND(伺服電池負極也接這裡)

這頁會用到的數值

「左、右」一律是感應器裝在車上、你站在車子後面往前看:線在左 = 負數,第 1 路在最左。

積木(繁中) JavaScript 範圍 意思 用在
循行者 線位置 mbc.linePosition() −8~+8 線在哪一路,0 = 正中間,負 = 線在左 1, 3, 4
循行者 細位置 mbc.linePositionFine() −100~+100 線位置的細分,跟線位置同號 5
循行者 看到線? mbc.lineSeen() true / false 至少有一路壓到線 1, 3, 4, 5
循行者 線寬 mbc.lineWidth() 0~8 壓到線的路數,0 = 沒線 1
循行者 最後離線方向 mbc.lineLastDirection() −8~+8 丟線前線在哪一側,負 = 左 5
當循行者 丟線/找回線/分岔 mbc.onLineEvent(...) 事件 線段數變成 0/變回 >0/變成 ≥2 時各觸發一次 2, 5
循行者 校準 自動(來回掃 5 秒) mbc.lineCalibrate(MbcLineCalib.Auto) 命令 E7 5 秒內在黑線和白底上來回掃,存進感應器 2
循行者 校準中?/校準次數 mbc.lineCalibrating() / mbc.lineCalibrationCount() true / false、0~255 校準旗標(F3 b2)與開機後完成次數 2
循行者 循 黑/白 線 mbc.lineSetColor(MbcLineColor.Black) 命令 E0/E1 白底黑線(預設)或黑底白線 2
等位址 … 的裝置就緒 mbc.waitReady(mbc.ADDR_LINE, 3000) true / false 最多等 3 秒,感應器有回應就 true(進階 → 裝置) 1

範例 1:線在哪一路

這個範例會做什麼:LED 上的一根光柱跟著線跑:線在左邊光柱就在左邊,線在正中間光柱在中間。按 A 顯示線位置的數字、按 B 顯示線寬。可以用來確認接線正確、方向沒弄反。

要準備什麼

  • micro:bit V1 或 V2+USB 線
  • 循行者 8 路(通用 I2C 版)+4P 線
  • 一張白紙+一條黑色電工膠帶(約 2 cm 寬)

怎麼接:照上面的接線表:SDA → P20、SCL → P19、VCC → 3V、GND → GND。

下載程式:ex01_show_position.ts(右鍵另存)→ MakeCode 新專案 → 齒輪 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 右上切到 JavaScript → 全選刪掉原本的內容、把檔案內容貼上 → 下載,把 .hex 拖進 MICROBIT 磁碟。

程式

// 循行者 8 路 × micro:bit 範例 1:線在哪一路(LED 光柱跟著線跑)
// 做什麼:把感應器在黑線上左右移動,LED 上的一根光柱會跟著線跑;按 A 顯示線位置的數字、按 B 顯示線寬。
// 接線:感應器 SDA → P20、SCL → P19、VCC → 3V(或外接 5 V)、GND → GND。
// 準備:MakeCode 新專案 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 切到 JavaScript 把本檔全部貼上 → 下載到 micro:bit。
// 看到什麼:開機先打勾(找到感應器);線在左 → 光柱在左邊;線在正中間 → 光柱在中間;沒線 → 畫一個 X。

const CH = 8                                              // 路數:8 路版 8、16 路版 16
let busy = false                                          // 按鈕顯示數字時,暫停畫光柱

if (mbc.waitReady(mbc.ADDR_LINE, 3000)) {                 // 最多等 3 秒,看感應器有沒有接好
    basic.showIcon(IconNames.Yes)
} else {
    basic.showIcon(IconNames.No)                          // 沒回應:檢查 P19/P20 和電源
}

basic.forever(function () {
    if (busy) {
        basic.pause(100)
        return
    }
    if (mbc.lineSeen()) {
        let pos = mbc.linePosition()                      // −CH(最左)~ +CH(最右),0 = 正中間
        let x = Math.round(Math.map(pos, -CH, CH, 0, 4))  // 換算成 LED 的第 0~4 行
        basic.clearScreen()
        for (let y = 0; y < 5; y++) {
            led.plot(x, y)                                // 畫一整根光柱
        }
    } else {
        basic.showIcon(IconNames.No, 0)                   // 沒看到線
    }
    basic.pause(50)
})

input.onButtonPressed(Button.A, function () {
    busy = true
    basic.showNumber(mbc.linePosition())                  // 線位置:負 = 線在左(站在車後往前看)
    busy = false
})
input.onButtonPressed(Button.B, function () {
    busy = true
    basic.showNumber(mbc.lineWidth())                     // 線寬:壓到線的路數,0 = 沒線
    busy = false
})

一步一步看懂程式

  1. const CH = 8:路數。16 路版把 8 改成 16,其他不用動。
  2. mbc.waitReady(mbc.ADDR_LINE, 3000):最多等 3 秒看感應器有沒有回應,有就打勾、沒有就 X。
  3. basic.forever:一直重複。先問 mbc.lineSeen()「有看到線嗎」,沒有就畫 X。
  4. 有線:mbc.linePosition() 讀線位置(−8~+8),用 Math.map 換算成 LED 的第 0~4 行,再用迴圈 led.plot 把那一行 5 顆燈全部點亮。
  5. 按 A/B:basic.showNumber 把數字捲過螢幕;busy 這個變數讓光柱在捲數字時先暫停,兩邊才不會搶螢幕。

跑起來應該看到什麼

  • 開機:打勾(找到感應器)。
  • 感應器放在白紙上、黑線在感應器正中間:光柱在中間那一行;按 A 顯示 0。
  • 把感應器往右移(線跑到感應器左邊):光柱往左跑;按 A 顯示負數。
  • 拿離紙面:X。

常見問題

  • 光柱方向跟線相反? → 感應器裝反了(第 1 路要在車子左邊)。把感應器轉 180°,不要改程式。
  • 光柱一直在中間不動? → 還沒校準:先跑範例 2 按 A 做自動校準,或讀值全 0(看範例 1 的 X 有沒有出現)。
  • 開機就是 X(找不到感應器)? → 看接線 SDA=P20、SCL=P19 有沒有接反;外接電源有沒有開;用鱷魚夾接的話夾子有沒有碰到旁邊的腳。
  • 模擬器裡數字都是 0? → 正常。MakeCode 模擬器沒有真的 I2C,讀到的都是 0;要看真的數值一定要下載到 micro:bit。
  • V1 沒有聲音? → V1 沒有喇叭,在 P0 和 GND 之間接蜂鳴器或耳機。

範例 2:丟線警報+一鍵校準

這個範例會做什麼:看到線 → 笑臉;線不見 → 哭臉並嗶一聲。按 A 做 5 秒自動校準(LED 倒數 5 4 3 2 1),按 B 切換黑線/白線模式。這是用「事件」積木寫的:線丟掉的那一瞬間才觸發,不是一直問。

要準備什麼

  • 範例 1 的東西
  • V1 另外要蜂鳴器或耳機接 P0

怎麼接:同範例 1。

下載程式:ex02_line_alarm.ts(右鍵另存)→ MakeCode 新專案 → 齒輪 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 右上切到 JavaScript → 全選刪掉原本的內容、把檔案內容貼上 → 下載,把 .hex 拖進 MICROBIT 磁碟。

程式

// 循行者 8 路 × micro:bit 範例 2:丟線警報+一鍵校準
// 做什麼:看到線 → 笑臉;丟線 → 哭臉並嗶一聲。按 A 做 5 秒自動校準(LED 倒數),按 B 切換黑線/白線。
// 接線:感應器 SDA → P20、SCL → P19、VCC → 3V(或外接 5 V)、GND → GND。V1 要在 P0 接蜂鳴器或耳機才有聲音(V2 有內建喇叭)。
// 準備:一張白紙+黑色電工膠帶貼一條線。擴充與貼程式的方法同範例 1。
// 看到什麼:感應器在線上 → 笑臉;拿開 → 哭臉+嗶;按 A → 5 4 3 2 1 倒數、顯示校準次數、打勾。

let white = false                                         // 目前是不是白線模式

mbc.lineSetColor(MbcLineColor.Black)                      // 開機先設成追黑線(預設)
basic.showIcon(IconNames.Happy)

mbc.onLineEvent(MbcLineEvent.Lost, function () {          // 線段數從 >0 變 0 時觸發一次
    basic.showIcon(IconNames.Sad, 0)
    music.playTone(Note.C, music.beat(BeatFraction.Half)) // 低音 Do 響半拍
})
mbc.onLineEvent(MbcLineEvent.Found, function () {         // 重新看到線
    basic.showIcon(IconNames.Happy, 0)
})

input.onButtonPressed(Button.A, function () {
    mbc.lineCalibrate(MbcLineCalib.Auto)                  // 5 秒內把感應器在黑線和白底上來回掃
    for (let i = 5; i > 0; i--) {
        basic.showNumber(i)                               // 倒數
        basic.pause(1000)
    }
    while (mbc.lineCalibrating()) {                       // 等感應器的「校準中」旗標歸零
        basic.pause(100)
    }
    basic.showNumber(mbc.lineCalibrationCount())          // 開機後完成校準的次數
    basic.showIcon(IconNames.Yes)
})

input.onButtonPressed(Button.B, function () {
    white = !white
    mbc.lineSetColor(white ? MbcLineColor.White : MbcLineColor.Black)   // 白底黑線 ↔ 黑底白線
    basic.showString(white ? "W" : "B")
})

一步一步看懂程式

  1. mbc.lineSetColor(MbcLineColor.Black):先設成追黑線(命令 E0)。
  2. mbc.onLineEvent(MbcLineEvent.Lost, ...):線段數從 >0 變 0 時執行一次 → 哭臉+music.playTone 嗶半拍。Found 那個是重新看到線 → 笑臉。
  3. 按 A:mbc.lineCalibrate(MbcLineCalib.Auto) 送出命令 E7,感應器開始 5 秒校準;程式同時用 for 迴圈倒數。
  4. while (mbc.lineCalibrating()):校準旗標(F3 b2)還是 1 就再等 0.1 秒,歸零才往下。
  5. mbc.lineCalibrationCount():顯示開機後完成的校準次數,確認真的做完了。
  6. 按 B:變數 white 翻轉,lineSetColor 在黑線(E0)和白線(E1)之間切換,螢幕顯示 B 或 W。

跑起來應該看到什麼

  • 感應器在線上:笑臉。拿開:哭臉+嗶一聲(只嗶一次,不會一直響)。
  • 按 A,在 5 秒內把感應器在黑線和白紙上來回掃幾次 → 顯示次數(第一次是 1)→ 打勾。之後線位置會更準。
  • 按 B 顯示 W:黑紙白線才會被當成線。

常見問題

  • 按 A 之後一直沒顯示次數? → 校準旗標沒歸零,通常是感應器沒接好(讀值全 0 時 lineCalibrating() 是 false,會馬上跳過)。先跑範例 1 看有沒有打勾。
  • 丟線時沒聲音? → V1 要接蜂鳴器;V2 確認沒有在 MakeCode 裡把喇叭關掉。

範例 3:方向盤伺服跟著線轉

這個範例會做什麼:一顆 9g 伺服當方向盤:線在左伺服就往左轉,線越偏轉越多(最外側 80°);丟線回正中。這是第一次讓感應器「動」東西。按 A 顯示目前角度。

要準備什麼

  • 範例 1 的東西,先做過一次範例 2 的校準
  • 9g 伺服(SG90)×1
  • 4.8~6 V 電池盒(4 顆 AA)+杜邦線

怎麼接:感應器同範例 1。伺服 橘(訊號)→ P1、紅 → 外接 4.8~6 V 電池正極、棕 → 電池負極,電池負極再接一條到 micro:bit GND(共地)。

下載程式:ex03_steer_servo.ts(右鍵另存)→ MakeCode 新專案 → 齒輪 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 右上切到 JavaScript → 全選刪掉原本的內容、把檔案內容貼上 → 下載,把 .hex 拖進 MICROBIT 磁碟。

程式

// 循行者 8 路 × micro:bit 範例 3:方向盤伺服跟著線轉
// 做什麼:一顆 9g 伺服(SG90)當方向盤:線在左 → 伺服往左轉,線越偏轉越多;丟線 → 回正中。按 A 顯示目前角度。
// 接線:感應器 SDA → P20、SCL → P19、VCC → 3V、GND → GND。伺服 橘(訊號)→ P1、紅 → 外接 4.8~6 V 電池正極、棕 → 電池負極並接 micro:bit GND(共地)。
// 準備:範例 2 的黑線紙+先做過一次校準。
// 看到什麼:感應器往線的左邊移 → 伺服擺臂往一邊轉;移到右邊 → 往另一邊;拿開 → 回到 90°。

const CH = 8                                              // 路數:8 路版 8、16 路版 16
const GAIN = Math.idiv(80, CH)                            // 每偏一路轉幾度:最外側剛好 ±80°
let angle = 90

basic.forever(function () {
    if (mbc.lineSeen()) {
        angle = 90 + mbc.linePosition() * GAIN            // 線在左(負)→ 角度小於 90
    } else {
        angle = 90                                        // 沒線:回正
    }
    angle = Math.constrain(angle, 0, 180)
    pins.servoWritePin(AnalogPin.P1, angle)               // 0~180°
    basic.pause(30)
})

input.onButtonPressed(Button.A, function () {
    basic.showNumber(angle)
})

一步一步看懂程式

  1. GAIN = Math.idiv(80, CH):每偏一路轉幾度。8 路是 10°,16 路是 5°,最外側都剛好 80°。
  2. 有線時 angle = 90 + 線位置 × GAIN:線在左(負)角度小於 90,線在右大於 90。
  3. 沒線時 angle = 90 回正。
  4. Math.constrain(angle, 0, 180):伺服只能 0~180°,超過就夾住。
  5. pins.servoWritePin(AnalogPin.P1, angle):把角度送到 P1 的伺服。每 30 ms 更新一次。

跑起來應該看到什麼

  • 線在正中間:伺服在 90°。
  • 感應器往右移(線跑到左邊):擺臂往一邊轉;越偏轉越多。
  • 拿開:回 90°。按 A 顯示 90。

常見問題

  • 伺服一直抖、或 micro:bit 一直重開? → 伺服不能用 micro:bit 的 3V 腳供電,一定要外接電池盒,而且電池負極要接 micro:bit GND。
  • 轉的方向跟你想的相反? → 把 90 + ... 改成 90 - ... 就好,看伺服裝的方向。

範例 4:循線小車(三段式)

這個範例會做什麼:按 A 開車:線在左 → 左轉、線在右 → 右轉、正中間 → 直走;丟線 → 停。按 B 停車。只有三種動作,最容易看懂的循線。

要準備什麼

  • 兩輪小車:兩顆連續旋轉伺服(FS90R 之類)當輪子+一顆萬向輪
  • 循行者裝在車頭、離地 0.5~1 cm
  • 4.8~6 V 電池盒
  • 黑線跑道(白紙+黑膠帶,轉彎不要太急)

怎麼接:感應器同範例 1,裝在車頭離地 0.5~1 cm。左輪連續旋轉伺服訊號 → P1、右輪 → P2,兩顆伺服的紅線接 4.8~6 V 電池盒正極、棕線接電池負極,電池負極再接 micro:bit GND。

下載程式:ex04_simple_follow.ts(右鍵另存)→ MakeCode 新專案 → 齒輪 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 右上切到 JavaScript → 全選刪掉原本的內容、把檔案內容貼上 → 下載,把 .hex 拖進 MICROBIT 磁碟。

程式

// 循行者 8 路 × micro:bit 範例 4:循線小車(三段式)
// 做什麼:按 A 開車:線在左 → 左轉、線在右 → 右轉、正中間 → 直走;丟線 → 停。按 B 停車。
// 接線:感應器 SDA → P20、SCL → P19、VCC → 3V、GND → GND。左輪連續旋轉伺服訊號 → P1、右輪 → P2;兩顆伺服的電源接 4.8~6 V 電池盒,電池負極接 micro:bit GND。
// 準備:兩輪小車(兩顆連續旋轉伺服當輪子)、感應器裝在車頭離地 0.5~1 cm、黑線跑道。
// 看到什麼:按 A 後箭頭朝上、車子沿線走;轉彎時箭頭指向轉彎方向;拿開線 → 哭臉、停車。

let running = false

// 左輪伺服 P1、右輪伺服 P2(連續旋轉伺服);left/right = −100~100,正 = 前進
function drive(left: number, right: number): void {
    left = Math.constrain(left, -100, 100)
    right = Math.constrain(right, -100, 100)
    pins.servoWritePin(AnalogPin.P1, Math.round(90 + left * 0.9))    // 90 = 停、180 = 全速前進、0 = 全速後退
    pins.servoWritePin(AnalogPin.P2, Math.round(90 - right * 0.9))   // 右輪裝的方向相反,所以用減的
}

input.onButtonPressed(Button.A, function () {
    running = true
    basic.showArrow(ArrowNames.North, 0)
})
input.onButtonPressed(Button.B, function () {
    running = false
    drive(0, 0)
    basic.showIcon(IconNames.No, 0)
})

basic.forever(function () {
    if (!running) {
        basic.pause(100)
        return
    }
    if (!mbc.lineSeen()) {
        drive(0, 0)                                       // 丟線就停,才不會跑出跑道
        basic.showIcon(IconNames.Sad, 0)
    } else {
        let pos = mbc.linePosition()                      // 負 = 線在左
        if (pos < 0) {
            drive(20, 60)                                 // 左輪慢、右輪快 = 左轉
            basic.showArrow(ArrowNames.West, 0)
        } else if (pos > 0) {
            drive(60, 20)                                 // 右轉
            basic.showArrow(ArrowNames.East, 0)
        } else {
            drive(50, 50)                                 // 直走
            basic.showArrow(ArrowNames.North, 0)
        }
    }
    basic.pause(20)
})

一步一步看懂程式

  1. function drive(left, right):這一頁所有開車範例都用它。數字 −100~100,正 = 前進。左輪 90 + left × 0.9(90 停、180 全速前);右輪裝的方向相反,所以 90 − right × 0.9。
  2. 按 A:running = true;按 B:running = false 並 drive(0, 0) 停車。
  3. basic.forever:沒在跑就什麼都不做(return)。
  4. !mbc.lineSeen():丟線 → 停車、哭臉,車子才不會衝出跑道。
  5. pos < 0(線在左)→ drive(20, 60):左輪慢、右輪快 = 左轉。pos > 0 相反。pos == 0 → 兩輪一樣快直走。

跑起來應該看到什麼

  • 按 A:箭頭朝上、車子沿線走;彎道時箭頭指向轉彎方向。
  • 把車抬起來:哭臉、兩輪停。
  • 按 B:X、停車。

常見問題

  • 按 A 車子倒退? → 兩顆伺服都裝反了:把 drive 裡的 + left 改 - left、- right 改 + right。只有一輪反 → 只改那一行。
  • 車子在線上左右甩? → 把 60/20 改成 50/30(轉彎溫和一點),或進階用範例 5 的比例控制。
  • 停不下來、放開還慢慢轉? → 連續旋轉伺服的「停」不一定剛好是 90,用小螺絲起子調伺服背面的微調孔,或把 90 改成 88~92 試。

範例 5:平滑循線+數路口停車(綜合)

這個範例會做什麼:用「細位置」做比例控制:線偏多少就修正多少,走起來不會左右甩;遇到十字路口(分岔事件)就計數,第 3 個路口停車;丟線時用「最後離線方向」原地轉回去找線。把前面學的讀值、事件、開車全部放在一起。

要準備什麼

  • 範例 4 的小車
  • 畫了 3 個十字路口的黑線跑道

怎麼接:同範例 4。

下載程式:ex05_smooth_follow_stop.ts(右鍵另存)→ MakeCode 新專案 → 齒輪 → 擴充 → 貼 https://github.com/contactmbcrobot/pxt-mbc-sensors → 右上切到 JavaScript → 全選刪掉原本的內容、把檔案內容貼上 → 下載,把 .hex 拖進 MICROBIT 磁碟。

程式

// 循行者 8 路 × micro:bit 範例 5:平滑循線+數路口停車(綜合)
// 做什麼:用「細位置」做比例控制,線越偏修正越多,走起來不抖;遇到十字路口就計數,第 3 個路口停車;丟線時用「最後離線方向」原地轉回去找線。A 開始、B 停。
// 接線:同範例 4(感應器 P19/P20、左輪 P1、右輪 P2、伺服外接電池、共地)。
// 準備:畫了 3 個十字路口的黑線跑道。
// 看到什麼:按 A 車子平順沿線走,每過一個路口 LED 顯示 1、2、3,到 3 停車打勾;把線拿開,車子會往線消失的那一邊轉,找到線再繼續。

const SPEED = 50
const KP = 0.5                                            // 細位置 ±100 → 修正 ±50
let running = false
let crossings = 0

// 左輪伺服 P1、右輪伺服 P2(連續旋轉伺服);left/right = −100~100,正 = 前進
function drive(left: number, right: number): void {
    left = Math.constrain(left, -100, 100)
    right = Math.constrain(right, -100, 100)
    pins.servoWritePin(AnalogPin.P1, Math.round(90 + left * 0.9))    // 90 = 停、180 = 全速前進、0 = 全速後退
    pins.servoWritePin(AnalogPin.P2, Math.round(90 - right * 0.9))   // 右輪裝的方向相反,所以用減的
}

mbc.onLineEvent(MbcLineEvent.Fork, function () {          // 線段數 ≥ 2:十字或分岔
    if (!running) {
        return
    }
    crossings += 1
    basic.showNumber(crossings)
    if (crossings >= 3) {
        running = false
        drive(0, 0)
        basic.showIcon(IconNames.Yes)
    }
})
mbc.onLineEvent(MbcLineEvent.Lost, function () {
    if (!running) {
        return
    }
    if (mbc.lineLastDirection() < 0) {                    // 線從左邊跑掉 → 原地左轉找線
        drive(-30, 30)
    } else {
        drive(30, -30)
    }
    basic.showIcon(IconNames.Confused, 0)
})

input.onButtonPressed(Button.A, function () {
    crossings = 0
    running = true
    basic.showArrow(ArrowNames.North, 0)
})
input.onButtonPressed(Button.B, function () {
    running = false
    drive(0, 0)
    basic.showIcon(IconNames.No, 0)
})

basic.forever(function () {
    if (running && mbc.lineSeen()) {
        let err = mbc.linePositionFine()                  // −100~+100,負 = 線在左
        let turn = err * KP                               // 線在左 → turn 是負的 → 左輪減速 = 左轉
        drive(SPEED + turn, SPEED - turn)
    }
    basic.pause(20)
})

一步一步看懂程式

  1. KP = 0.5:細位置 −100~+100 乘 0.5 = 修正 −50~+50。這個數字越大轉得越兇。
  2. basic.forever:在跑而且看得到線時,err = 細位置,turn = err × KP,drive(SPEED + turn, SPEED − turn)。線在左(負)→ 左輪減速、右輪加速 = 平滑左轉。
  3. onLineEvent(Fork):線段數 ≥ 2(十字)時 crossings + 1 顯示在 LED;到 3 就 running = false 停車打勾。
  4. onLineEvent(Lost):mbc.lineLastDirection() < 0 表示線從左邊跑掉 → drive(−30, 30) 原地左轉;否則右轉。forever 迴圈在看不到線時不會動馬達,所以會一直轉到找回線為止。
  5. A:次數歸零、開始;B:停。

跑起來應該看到什麼

  • 按 A:車子平順沿線走,比範例 4 穩。
  • 每過一個十字:LED 顯示 1、2、3;到 3 停車打勾。
  • 把跑道從車底抽走:問號臉、車子往線消失的那一側原地轉;放回去就繼續走。

常見問題

  • 一個路口算了兩次? → 車速太慢、經過路口時線段數跳了兩次。加快 SPEED,或在 Fork 事件裡加 basic.pause(500) 讓同一個路口不重複計。
  • 車子還是會左右抖? → KP 從 0.5 降到 0.3;還抖就把 basic.pause(20) 改 10(更新快一點)。
  • 找線時一直原地轉? → 線拿太遠了。它只會轉,不會前進;要往前找線可以在 Lost 事件改成 drive(10, 40) 這種弧線。

下一步

其他問題

還有問題?到 聯絡我們 附上你用的軟體和程式截圖。

下載

本頁依據

  • 主機與軟體清單:_build/guides.json
  • 值與命令:_build/protocol/line8.json(單一真相來源)
  • 安裝與設定:_build/guides/software/microbit-makecode.zh.md、_build/guides/product/line8/microbit-makecode.zh.md
  • 範例:sensors/line8/microbit-examples.md
LINE 詢價選購指南