Learning Objectives
- 說出 micro:bit 板上有哪些內建的輸入與輸出
- 用 display 顯示圖案、文字,並控制單一顆 LED 的亮度
- 分辨 is_pressed 與 was_pressed,用按鈕做出互動
- 讀加速度計判斷傾斜方向,做出會回應動作的作品
一塊板子就能做互動作品
前面幾課的開發板,要接麵包板、LED、按鈕才看得到效果。micro:bit 把常用的輸入輸出直接做在板子上, 接上 USB 線、寫幾行程式,就能做出會顯示、會回應按鈕與動作的作品,所以很常出現在入門課與工作坊。
micro:bit 是英國 BBC 主導、多個合作夥伴一起開發的教育用開發板:2015 年 3 月發表,2016 年開始發給英國的 Year 7 學生(11~12 歲)。 2020 年推出 V2,換了更快的處理器,加上麥克風與喇叭。
| V1 | V2 | |
|---|---|---|
| 微控制器 | Nordic nRF51822(ARM Cortex-M0,16 MHz) | Nordic nRF52833(ARM Cortex-M4,64 MHz) |
| 記憶體 | 256 KB Flash、16 KB RAM | 512 KB Flash、128 KB RAM |
| 兩版都有 | 5×5 LED 點陣、按鈕 A 與 B、加速度計、磁力計(電子羅盤)、藍牙低功耗無線電、邊緣接腳 | |
| V2 新增 | 麥克風、喇叭、觸控按鈕 |
板子下緣是一排邊緣接腳,其中五個大圓孔是 0、1、2、3V、GND,可以用鱷魚夾接上外部零件;0、1、2 也能讀類比值與做 PWM。
怎麼寫 MicroPython
micro:bit 支援 MicroPython。常見的做法是用官方的線上 Python 編輯器(python.microbit.org)寫程式, 把板子接上電腦就能直接燒錄;也可以用 Thonny 等編輯器。程式開頭一律是:
from microbit import *
這一行把 display、Image、button_a、button_b、accelerometer、sleep、pin0 等全部匯入。
注意 micro:bit 的 sleep() 單位是毫秒(ESP32 的 time.sleep() 是秒)。
5×5 LED 點陣
25 顆 LED 排成 5 列 5 行,座標從左上角 (0, 0) 開始,x 往右、y 往下。每顆 LED 的亮度是 0~9(0 熄滅、9 最亮)。
| 函式 | 做什麼 |
|---|---|
display.show(Image.HEART) |
顯示一個圖案 |
display.show(5)、display.show("A") |
顯示數字或字元;字串會一個字一個字顯示 |
display.scroll("Hello") |
捲動一段文字,捲完才往下執行 |
display.set_pixel(x, y, 亮度) |
設定一顆 LED |
display.get_pixel(x, y) |
讀一顆 LED 目前的亮度 |
display.clear() |
全部熄滅 |
Image 有很多內建圖案:HEART、HAPPY、SAD、YES、NO、ARROW_N(北,朝上)、ARROW_E(東,朝右)等,
也可以自己畫:Image("09090:99999:99999:09990:00900"),每 5 個數字是一列,用冒號分開。
逐步看:圖案、捲動文字與單顆 LED
上方的 micro:bit 畫面會跟著每一步更新。注意 scroll 這一行讓時間前進最多:文字捲完,程式才往下執行。
按鈕 A 與 B
button_a、button_b 各有三種讀法:
| 方法 | 回傳 | 適合 |
|---|---|---|
is_pressed() |
現在是不是正按著 | 按住才有作用,例如按住加速 |
was_pressed() |
上次問過之後有沒有按過;問完就清掉紀錄 | 「按一下做一件事」,不會因為迴圈跑得慢而漏掉 |
get_presses() |
上次問過之後按了幾次;問完歸零 | 計數 |
用 is_pressed() 做「按一下」,如果迴圈剛好在 sleep 時按下又放開,就會漏掉;
was_pressed() 由系統在背景記下按過的事,就不會漏。
逐步看:按 A 加分、按 B 歸零
模擬時,A 在 0.3、1.1、2.5 秒各按一次,B 在 1.9 秒按住 0.2 秒。看分數怎麼變,以及 B 按下時分數歸零。
加速度計:知道自己怎麼被拿著
加速度計量三個方向的加速度,單位是 milli-g(千分之一個重力加速度)。 板子靜止時量到的主要是地球重力,所以可以知道板子怎麼傾斜:
accelerometer.get_x():左右傾斜。往右傾是正數、往左傾是負數,水平時接近 0accelerometer.get_y():前後傾斜accelerometer.get_z():上下,平放時大約是 ±1000(一個 g)
另外還有手勢:accelerometer.current_gesture() 回傳 "up"、"face up"、"shake" 等名稱,
accelerometer.was_gesture("shake") 判斷剛剛有沒有被搖過。手勢要在迴圈裡一直呼叫加速度計的函式才會被偵測到。
逐步看:傾斜就顯示箭頭
模擬時,板子先往左傾,再回到水平,最後往右傾。看 x 的數值與顯示的箭頭。 (模擬器的讀值單位和 micro:bit 一樣是 milli-g,1000 代表 1 g。)
還能做什麼
- 聲音:
import music,music.play(music.BA_DING)播內建的旋律;V2 預設從板上的喇叭與 0 號接腳發聲(V1 要在 0 號接腳和 GND 接耳機或喇叭)。 - 接腳:
pin0.read_analog()讀類比值(0~1023)、pin1.write_digital(1)輸出高電位、pin0.is_touched()觸控。 - 溫度:
temperature()讀處理器附近的溫度(會受到板子本身發熱影響)。 - 光線:
display.read_light_level()用 LED 點陣反過來感測光線,回傳 0~255。 - 無線電:
import radio讓兩塊 micro:bit 互傳訊息,適合課堂上的分組活動(模擬器目前沒有模擬)。
小測驗:硬體與顯示
display.set_pixel(4, 0, 9) 會點亮哪一顆 LED?
micro:bit V2 比 V1 多了哪些內建的硬體?
accelerometer.get_x() 回傳 −600,代表板子大概是什麼狀態?
小測驗:按鈕的讀法
下面的程式模擬 was_pressed():每 500 毫秒檢查一次,期間按過就加一分(不管按了幾次)。會印出什麼?
presses = [300, 400, 1100] # 按下 A 的時間(毫秒)
seen = 0
score = 0
for now in range(0, 2000, 500):
n = len([t for t in presses if t <= now])
if n > seen:
score += 1
seen = n
print(score)
想做「按住 B 時角色一直往右移,放開就停」,應該用哪一個?
重點整理
- micro:bit 內建 5×5 LED 點陣、按鈕 A 與 B、加速度計、磁力計與無線電;V2 加上麥克風、喇叭與觸控按鈕。
- 程式開頭
from microbit import *;sleep()的單位是毫秒。 display.show()顯示圖案、數字或字元,scroll()捲動文字,set_pixel(x, y, 0~9)控制單顆 LED。is_pressed()看現在、was_pressed()看上次之後有沒有按過、get_presses()算次數。- 加速度計的單位是 milli-g,x 往右傾為正;也可以用手勢判斷搖晃、翻面。
下一課介紹另一塊常見的入門板:Raspberry Pi Pico 與它的 RP2040 微控制器。