微控制器應用中,人機互動與環境感測至關重要。本文涵蓋按鈕、電容式觸控、加速度計、針、麥克風、光線和溫度感測器等常見互動輸入和感測技術,並以 micro:bit、Circuit Playground Express 和 PyBoard 為例,展示如何在 MicroPython 中運用這些技術。文章從按鈕的底層原理出發,逐步探討不同開發板的按鈕使用方法、中斷處理機制以及電容式觸控的應用。接著,文章講解加速度計、磁力計和手勢識別的原理和程式設計方法,並以程式碼範例說明如何結合這些感測器實作更豐富的互動功能。最後,文章介紹麥克風、光感測器和溫度感測器的工作原理,並提供 MicroPython 程式碼範例,展示如何使用這些感測器取得環境資訊,例如錄製音訊、檢測光線強度和溫度變化等。
按鈕與電容式觸控技術的深度解析
在微控制器開發板中,按鈕(Button)是最常見的人機互動元件之一。無論是micro:bit、Circuit Playground Express還是PyBoard,按鈕都扮演著至關重要的角色。本文將探討不同開發板上的按鈕使用方法及其底層原理,並結合具體程式碼範例進行詳細分析。
按鈕的基本原理
按鈕本質上是一種數位輸入裝置,只有兩種狀態:按下(Pressed)或釋放(Released)。這種狀態變化透過連線按鈕的引腳傳遞給微控制器。微控制器透過檢測引腳的電壓變化來判斷按鈕的狀態。
引腳的三種狀態
- 高電平(High):當引腳檢測到特定的電壓(如3.3伏特),則認為是高電平。
- 低電平(Low):當引腳無法檢測到電壓(0伏特),則認為是低電平。
- 浮空(Floating):如果引腳未被明確設定為高或低電平,則可能出現浮空狀態,此時微控制器可能無法準確判斷輸入狀態。
為了避免浮空狀態,需要將引腳設定為上拉(Pull-up)或下拉(Pull-down)。上拉模式下,引腳預設為高電平;下拉模式下,引腳預設為低電平。
micro:bit上的按鈕使用
在micro:bit上,按鈕的使用非常簡單。提供了is_pressed()、was_pressed()和get_presses()三個方法,分別用於檢測按鈕當前狀態、檢查按鈕是否曾經被按下以及取得按鈕的累計點選次數。
Circuit Playground Express上的按鈕處理
在Circuit Playground Express上,按鈕的使用需要更底層的操作。以下是一個範例程式碼,展示如何使用digitalio模組來控制NeoPixels的閃爍方向:
import neopixel
import time
import digitalio
from board import NEOPIXEL, BUTTON_A, BUTTON_B
np = neopixel.NeoPixel(NEOPIXEL, 10, auto_write=False)
button_a = digitalio.DigitalInOut(BUTTON_A)
button_a.pull = digitalio.Pull.DOWN
button_b = digitalio.DigitalInOut(BUTTON_B)
button_b.pull = digitalio.Pull.DOWN
clockwise = True
while True:
time.sleep(0.05)
if button_a.value:
clockwise = True
elif button_b.value:
clockwise = False
for i in range(10):
if clockwise:
i = 9 - i
for j in range(10):
np[j] = tuple((max(0, val - 64) for val in np[j]))
np[i] = (0, 0, 254)
np.write()
內容解密:
- 初始化NeoPixels和按鈕物件:使用
neopixel和digitalio模組初始化NeoPixels燈條和兩個按鈕物件,並將按鈕的提取模式設定為下拉。 - 主迴圈邏輯:在主迴圈中,程式會檢查兩個按鈕的狀態。如果按鈕A被按下,則設定
clockwise為True;如果按鈕B被按下,則設定為False。 - 控制NeoPixels閃爍:根據
clockwise的值,程式會以不同的方向點亮NeoPixels,並逐漸降低其他燈光的亮度,形成閃爍效果。
PyBoard上的按鈕與回呼函式
PyBoard提供了另一種與按鈕互動的方式,即使用回呼函式(Callback)。以下是一個簡單的範例:
import pyb
led = pyb.LED(1)
sw = pyb.Switch()
def toggle_led():
led.toggle()
sw.callback(toggle_led)
while True:
pyb.delay(100)
內容解密:
- 初始化LED和開關物件:使用
pyb模組初始化LED和開關物件。 - 定義回呼函式:定義一個名為
toggle_led的函式,用於切換LED的狀態。 - 註冊回呼函式:將
toggle_led函式註冊到開關物件的回呼事件中,當開關被按下時,自動呼叫該函式。
互動輸入與感測技術
在微控制器開發中,互動輸入與感測技術是至關重要的環節。這些技術使裝置能夠對使用者的輸入做出反應,從而實作各種應用功能。本章節將探討按鈕輸入、中斷處理以及電容式觸控等技術,並透過具體範例展示如何在不同的硬體平台上實作這些功能。
按鈕輸入與中斷處理
在微控制器開發中,按鈕是一種常見的輸入裝置。當按鈕被按下時,會觸發相應的事件,從而執行特定的程式碼。為了有效處理按鈕輸入,通常會使用中斷機制。
中斷機制的工作原理
當按鈕被按下時,相關的引腳狀態會從低電平變為高電平,觸發微控制器的中斷。此時,微控制器會暫停當前任務,儲存其狀態,並呼叫與按鈕相關聯的中斷處理函式。中斷處理函式執行完畢後,微控制器會還原之前儲存的狀態,繼續執行被中斷的任務。
import pyb
# 初始化按鈕物件
sw = pyb.Switch()
# 定義回呼函式
def my_callback():
pyb.LED(1).toggle()
# 設定按鈕回呼函式
sw.callback(my_callback)
程式碼解析:
- 匯入
pyb模組,該模組提供 PyBoard 的硬體控制介面。 - 初始化一個
Switch物件sw,代表板上的按鈕。 - 定義一個名為
my_callback的函式,當按鈕被按下時,該函式會被呼叫,切換 LED 的狀態。 - 使用
sw.callback(my_callback)設定按鈕的回呼函式。
電容式觸控技術
電容式觸控技術利用人體的電容特性來檢測觸控事件。當人體接觸到特定的引腳時,會改變該引腳的電容值,從而觸發相應的事件。
micro:bit 平台上的電容式觸控
在 micro:bit 平台上,電容式觸控可以透過特定的引腳(標記為 0、1 和 2)來實作。
from microbit import display, Image, pin0
while True:
display.show(Image.ASLEEP)
if pin0.is_touched():
display.show(Image.HAPPY)
程式碼解析:
- 匯入必要的模組,包括
display、Image和pin0。 - 在無限迴圈中,顯示
ASLEEP影像。 - 當
pin0被觸控時,is_touched()方法傳回True,顯示HAPPY影像。
Circuit Playground Express 平台上的電容式觸控
在 Circuit Playground Express 平台上,多個引腳都支援電容式觸控。
import neopixel
import touchio
import digitalio
from board import *
# 停用喇叭以避免雜訊
spkr = digitalio.DigitalInOut(SPEAKER_ENABLE)
spkr.switch_to_output()
spkr.value = False
# 初始化 NeoPixel
np = neopixel.NeoPixel(NEOPIXEL, 10, auto_write=False)
# 初始化觸控輸入物件
touch_a1 = touchio.TouchIn(A1)
touch_a3 = touchio.TouchIn(A3)
touch_a4 = touchio.TouchIn(A4)
touch_a6 = touchio.TouchIn(A6)
while True:
if touch_a4.value:
np[0] = (255, 0, 0)
np[1] = (255, 0, 0)
if touch_a6.value:
np[3] = (0, 255, 0)
np[4] = (0, 255, 0)
if touch_a1.value:
np[5] = (255, 255, 0)
np[6] = (255, 255, 0)
if touch_a3.value:
np[8] = (0, 0, 255)
np[9] = (0, 0, 255)
# 使 NeoPixel 漸漸變暗
for j in range(10):
np[j] = tuple((max(0, val - 32) for val in np[j]))
np.write()
程式碼解析:
- 初始化 NeoPixel 和多個觸控輸入物件。
- 在無限迴圈中,檢查各個觸控輸入物件的狀態,若被觸控,則點亮對應的 NeoPixel。
- 使用迴圈使 NeoPixel 的亮度漸漸降低,實作漸暗效果。
PyBoard 的 LCD 螢幕觸控功能
若 PyBoard 連線了 LCD 螢幕,則可以使用螢幕的觸控功能來實作互動輸入。
import lcd160cr
# 初始化 LCD 物件
lcd = lcd160cr.LCD160CR('X')
lcd.erase()
while True:
a, x, y = lcd.get_touch()
if a:
lcd.set_pixel(x, y, lcd.rgb(255, 255, 255))
程式碼解析:
- 初始化 LCD 物件並清除螢幕。
- 在無限迴圈中,使用
get_touch()方法取得螢幕的觸控狀態和座標。 - 若螢幕被觸控,則在對應的座標上繪製白色畫素點。
加速度計、手勢與針:微型裝置中的互動技術
在現代的微型計算裝置中,如micro:bit、PyBoard和Circuit Playground Express等,內建了多種感測器,使得裝置能夠感知其方向、運動狀態,甚至識別特定的手勢。這些功能大大豐富了人機互動的方式,使得裝置更加智慧化和易於使用。
加速度計的工作原理
加速度計是一種機電裝置,透過測量因重力或加速度引起的品質移動所導致的電容變化,將機械運動轉化為電訊號。這種技術與觸控式螢幕的工作原理類別似,都是根據電容變化的測量。加速度計通常包含三個獨立的感測器,分別測量X、Y和Z三個垂直軸上的重力或加速度。
針與磁力計
磁力計則是用於測量磁場的裝置。在micro:bit中,磁力計採用了微型的霍爾效應感測器,可以測量地球磁場在X、Y和Z三個軸上的分量。透過校準和對這些測量值的分析,可以確定裝置的方位,使其能夠作為針使用。
程式設計介面
這些裝置的加速度計和磁力計的程式設計介面非常相似,通常傳回X、Y和Z三個軸上的測量值。例如,在micro:bit上,可以使用以下程式碼來控制螢幕上畫素的移動:
from microbit import *
x = 2
y = 2
sensitivity = 50
pause = 90
fade = 2
while True:
roll = accelerometer.get_x()
yaw = accelerometer.get_y()
if roll < -sensitivity:
x = max(0, x - 1)
elif roll > sensitivity:
x = min(4, x + 1)
if yaw < -sensitivity:
y = max(0, y - 1)
elif yaw > sensitivity:
y = min(4, y + 1)
for i in range(5):
for j in range(5):
brightness = max(0, display.get_pixel(i, j) - fade)
display.set_pixel(i, j, brightness)
display.set_pixel(x, y, 9)
sleep(pause)
內容解密:
accelerometer.get_x()和accelerometer.get_y()用於讀取加速度計在X和Y軸上的測量值,反映裝置的傾斜狀態。sensitivity變數用於設定靈敏度閾值,避免過於敏感導致誤動作。- 程式碼透過改變畫素的位置來實作裝置傾斜控制螢幕上影像的效果。
display.set_pixel和display.get_pixel用於控制和讀取螢幕上畫素的亮度。
手勢識別
加速度計還可用於識別特定的手勢,如搖晃、自由落體或正面朝上。目前,micro:bit對手勢識別有內建支援。以下是一個簡單的例子:
from microbit import *
while True:
if accelerometer.was_gesture('shake'):
display.show(Image.ANGRY)
elif accelerometer.was_gesture('face up'):
display.show(Image.ASLEEP)
elif accelerometer.was_gesture('up'):
display.show(Image.HAPPY)
sleep(100)
內容解密:
accelerometer.was_gesture方法用於檢測特定的手勢,如搖晃(‘shake’)、正面朝上(‘face up’)或直立(‘up’)。- 根據檢測到的手勢,裝置會在螢幕上顯示不同的影像,如憤怒、睡著或快樂的表情。
- 這種互動方式極大地增強了裝置與使用者之間的互動體驗。
結合針功能
micro:bit內建的磁力計可以用作針,但需要先進行校準。以下是一個簡單的針範例:
from microbit import *
compass.calibrate()
while True:
sleep(100)
needle = ((15 - compass.heading()) // 30) % 12
display.show(Image.ALL_CLOCKS[needle])
內容解密:
compass.calibrate()方法用於校準針,需要使用者透過旋轉裝置來完成校準過程。compass.heading()傳回裝置相對於磁北的方位角。- 程式碼將方位角轉換為時鐘指標的位置,並顯示在螢幕上,以模擬針的效果。
麥克風、光線與溫度感測的原理與應用
在微控制器和開發板上,感測器扮演著至關重要的角色,讓裝置能夠感知周圍環境的變化。Circuit Playground Express 和 micro:bit 等開發板搭載了多種感測器,包括麥克風、光感測器和溫度感測器。本文將探討這些感測器的工作原理及其在 MicroPython 中的應用。
麥克風的工作原理
麥克風是一種將聲波轉換為電訊號的裝置。在 Circuit Playground Express 上,麥克風的工作原理類別似於加速計:當聲波引起空氣壓力變化時,裝置中的薄膜會振動,進而改變薄膜與固定板之間的電容。這個變化被轉換為電流,最終成為數位訊號。
光感測器的工作原理
光感測器的工作原理與 LED 相反。當 LED 發光時,是因為電流透過它。然而,如果光線照射到 LED 上,它會產生反向電流。micro:bit 利用這個特性來檢測光線。Circuit Playground Express 則使用光電晶體來檢測光線,光電晶體是一種專門用於檢測光線的元件,將光能轉換為電流。
溫度感測器的工作原理
溫度感測器使用熱敏電阻,其電阻值會隨著溫度變化而改變。Circuit Playground Express 的溫度感測器就是根據這種原理。此外,許多晶片,包括執行 MicroPython 的微控制器,都具有內建的熱二極體,用於監控晶片的溫度。熱二極體的電壓會隨著溫度變化,從而實作溫度測量。
使用麥克風錄音
以下範例展示瞭如何使用 Circuit Playground Express 上的麥克風錄製短片段音訊:
import neopixel
import audiobusio
import digitalio
import audioio
import time
from board import *
def countdown(np):
""" 使用 NeoPixels 顯示倒數計時 """
np.fill((0, 0, 0))
np.write()
for i in range(10):
np[i] = (0, 20, 0)
np.write()
time.sleep(0.5)
np.fill((0, 128, 0))
np.write()
def record():
""" 傳回錄製的音訊緩衝區 """
buf = bytearray(8000)
with audiobusio.PDMIn(MICROPHONE_CLOCK, MICROPHONE_DATA) as mic:
mic.record(buf, len(buf))
return buf
def play(buf, freq):
"""
以指定頻率播放音訊緩衝區
"""
speaker_enable = digitalio.DigitalInOut(SPEAKER_ENABLE)
speaker_enable.switch_to_output(value=True)
with audioio.AudioOut(SPEAKER, buf) as speaker:
speaker.frequency = freq
speaker.play()
while speaker.playing:
pass
neopixels = neopixel.NeoPixel(NEOPIXEL, 10, auto_write=False)
button_a = digitalio.DigitalInOut(BUTTON_A)
button_a.pull = digitalio.Pull.DOWN
button_b = digitalio.DigitalInOut(BUTTON_B)
button_b.pull = digitalio.Pull.DOWN
countdown(neopixels)
audio_buffer = record()
neopixels.fill((0, 0, 0))
neopixels.write()
freq = 8000 # 預設頻率
if button_a.value:
freq = 12000 # 按下按鈕 A 時的頻率
elif button_b.value:
freq = 6000 # 按下按鈕 B 時的頻率
play(audio_buffer, freq)
程式碼解析:
countdown函式:使用 NeoPixels 顯示倒數計時,準備開始錄音。record函式:建立一個bytearray緩衝區,使用PDMIn類別從麥克風錄製音訊資料。PDMIn類別:使用脈衝密度調變(PDM)將類別比訊號表示為二進位資料。record方法:將錄製的音訊資料填入緩衝區。
play函式:以指定的頻率播放錄製的音訊。- 設定喇叭輸出,並使用
AudioOut類別播放音訊緩衝區。 speaker.frequency屬性:控制播放頻率,從而改變音調。
- 設定喇叭輸出,並使用
光感測器和溫度感測器的使用
光感測器和溫度感測器都是類別比輸入裝置,其讀取值反映了檢測到的光強度和溫度變化。以下是在 REPL 中使用光感測器的範例:
>>> import analogio
>>> from board import *
>>> light = analogio.AnalogIn(LIGHT)
>>> light.value # 在黑暗環境中的讀取值
程式碼解析:
analogio.AnalogIn:初始化一個類別比輸入物件,用於讀取光感測器的值。light.value:取得當前光感測器的讀取值,該值與檢測到的光強度成正比。