MicroPython 簡化了 micro:bit 的程式開發,讓音樂和機器人控制變得更易上手。藉由內建的 music 模組,可以輕鬆播放內建或自定義的旋律,並控制播放速度和節奏。同時,speech 模組賦予了 micro:bit 語音合成的能力,可調整語音引數,創造更豐富的聲音效果。文章進一步探討如何結合音樂與語音合成,例如讓 micro:bit 唱歌,並提供實作範例。此外,文章也介紹瞭如何使用 MicroPython 控制機器人,包含伺服馬達控制、距離感測和避障功能的程式碼範例,並以 Trundle Bot 和 BeatBoxing 專案為例,展示如何整合硬體與軟體,實作機器人的基本功能和進階應用。最後,文章也討論了更複雜的機器人控制系統設計,例如 Bit:Bot 的控制邏輯,為讀者提供更廣泛的學習方向。
micro:bit上的音樂功能
micro:bit內建了一個簡單易用的音樂模組,可以用來播放不同的音調和旋律。以下是一個簡單的例子:
import music
from microbit import accelerometer
while True:
music.pitch(accelerometer.get_x(), 20)
內容解密:
- 讀取加速度計:這段程式碼讀取micro:bit上的加速度計X軸值,並根據該值產生對應的音調。
- 播放音調:
music.pitch函式用於播放特定的音調,第一個引數是頻率,第二個引數是播放時間。
量化加速度計讀數
為了使輸出的聲音更像音樂,我們可以對加速度計的讀數進行量化處理。以下是一個範例:
import music
from microbit import accelerometer
buckets = [
262, # C
294, # D
330, # E
392, # G
440 # A
]
while True:
reading = abs(accelerometer.get_x())
bucket = min(4, max(0, reading // 200)) # 量化
music.pitch(buckets[bucket], 20)
內容解密:
- 定義音階:首先,我們定義了一個包含五個音符的列表,代表一個五聲音階。
- 量化讀數:我們將加速度計的絕對值讀數量化到0到4之間的整數,對應於五聲音階中的不同音符。
- 播放量化後的音調:根據量化後的索引,我們從
buckets列表中選擇對應的頻率,並播放相應的音調。
使用 MicroPython 播放音樂與語音
MicroPython 提供了一個簡易的方式來播放音樂和語音。透過內建的 music 模組,可以輕鬆地播放旋律和控制音樂的播放。
播放內建旋律
MicroPython 的 music 模組包含了一系列內建的旋律,可以直接呼叫這些旋律來播放音樂。例如:
import music
music.play(music.NYAN)
這些內建的旋律包括 BADDY、BA_DING、BIRTHDAY、BLUES 等多種不同的音樂。
內容解密:
music.play()函式用於播放指定的旋律。music.NYAN是一個內建的旋律常數,代表特定的音樂旋律。
自定義旋律
除了播放內建旋律外,也可以透過定義自己的旋律來播放。MicroPython 使用一個簡單的音樂 DSL(Domain-Specific Language)來定義旋律。
tune = ["C4:4", "D", "E", "C", "C", "D", "E", "C",
"E", "F", "G:8", "E:4", "F", "G:8",
"G:2", "A", "G", "F", "E:4", "C", "G:2", "A", "G", "F", "E:4", "C",
"C", "G3", "C4:8", "C:4", "G3", "C4:8"]
music.play(tune, wait=False, loop=True)
內容解密:
tune是一個列表,包含了按照特定格式定義的音符。- 每個音符的格式為
NOTE_NAME[octave][:duration],例如"C4:4"表示在第四八度音階的 C 音符,持續 4 個節拍單位。 music.play()函式播放自定義的旋律,可以透過wait=False使播放非同步進行,透過loop=True使旋律迴圈播放。
控制音樂播放
MicroPython 提供了多種方法來控制音樂的播放,包括改變節奏、停止播放等。
music.set_tempo(bpm=180) # 設定節奏為每分鐘 180 拍
music.stop() # 停止音樂播放
內容解密:
music.set_tempo(bpm=180)設定音樂的節奏為每分鐘 180 拍。music.stop()用於停止當前的音樂播放。
語音合成
MicroPython 也提供了語音合成的功能,可以讓裝置發出語音。
import speech
speech.say("Hello, World!", speed=120, pitch=100, throat=100, mouth=200)
內容解密:
speech.say()函式用於讓裝置發出語音。- 可以透過引數調整語音的特性,如速度、音調、喉音和口型等。
語音合成技術與音樂的結合
語音合成技術是一種能夠將文字轉換成聲音的技術,而當這項技術與音樂結合時,便能創造出令人驚豔的效果。在 MicroPython 中,我們可以利用語音合成模組來產生語音,甚至可以讓 micro:bit 唱歌。
語音合成的基礎
在語音合成中,聲音的基本單位是音素(phonemes)。音素可以分為兩大類別:母音和子音。母音又可以進一步分為單純母音和雙母音。子音則分為有聲子音和無聲子音。
有聲子音與無聲子音
有聲子音需要使用聲帶來產生聲音,例如 “L”、“N” 和 “Z”。無聲子音則是透過氣流來產生聲音,例如 “P”、“T” 和 “SH”。
# 有聲子音範例
voiced_consonants = ["R", "D", "L", "G", "W", "J", "M", "N", "B", "V", "DH", "Z", "ZH"]
# 無聲子音範例
unvoiced_consonants = ["S", "SH", "F", "TH", "P", "T", "K", "CH", "H"]
特殊音素
除了基本的有聲和無聲子音外,還有一些特殊的音素,例如表示發音的變化或特殊的發音方式。
# 特殊音素範例
special_phonemes = ["UL", "UM", "UN", "Q"]
使用語音合成模組
在 MicroPython 中,可以使用 speech 模組來進行語音合成。首先,需要將文字轉換成音素,然後才能使用 pronounce 函式來發音。
import speech
# 將文字轉換成音素
phonemes = speech.translate("Hello")
# 發音
speech.pronounce(phonemes)
新增重音
為了使語音聽起來更自然,可以新增重音。重音是透過在母音後面新增數字來實作的,不同的數字代表不同的重音型別。
# 新增重音範例
stress_example = "/HEH3LOW"
speech.pronounce(stress_example)
語音合成與音樂的結合
要讓 micro:bit 唱歌,可以使用 sing 函式,並在音素前新增註解來指定音高。
import speech
# 定義歌曲的音符
solfa = [
"#115DOWWWWWW", # Doh
"#103REYYYYYY", # Re
"#94MIYYYYYY", # Mi
"#88FAOAOAOAOR", # Fa
"#78SOHWWWWW", # Soh
"#70LAOAOAOAOR", # La
"#62TIYYYYYY", # Ti
"#58DOWWWWWW" # Doh
]
# 將音符串接成一首歌
song = ''.join(solfa)
# 唱歌
speech.sing(song, speed=100)
實作範例:讓 micro:bit 唱一首歌
以下是完整的範例程式碼,展示如何讓 micro:bit 唱一首歌。
import speech
# 定義歌曲的每一行
line1 = [
'#26DEYYYYYYYYY',
'#31ZIYIYIYIYIYIYIY',
'#39DEYYYYYYYYY',
'#52ZIYIYIYIYIYIYIY',
'#46GIXV',
'#42MIYIY',
'#39YAOW',
'#46AEAEAEN',
'#39SERER',
'#52DUXUXUXUXUXUXUXUXUXUXUXUX'
]
line2 = [
'#35AYYYYYYMM',
'#26/HAEAEAEAEAEAEF',
'#31KREYYYYYYY',
'#39ZIYIYIYIYIYIYIY',
'#46AXLL',
'#42FAOR',
'#39DHER',
'#35LUHUHUHV',
'#31AXAXV',
'#35YUXUXUXUXUXUXUXUXUXUX'
]
line3 = [
'#31IHT',
'#29WOWNT',
'#31BIY',
'#35ER',
'#26STAYYYYY',
'#31LIHSH',
'#35MAE',
'#39RIXIXIXIXIXIXIXIXIXIXIXIXIXJ',
'#35AYY',
'#31KAEAEAEAENT',
'#39ER',
'#46FAOAOAORD',
'#39ER',
'#46KAA',
'#52RIXIXIXIXIXIXIXIXIXIXIXIXIXJ'
]
line4 = [
'#52BUHT',
'#39YUXUXL',
'#31LUXK',
'#35SWIYIYIYIYT',
'#52ER',
'#39PAAAAAAN',
'#31ER',
'#35SIYIYIYT',
'#31UHV',
'#29ER',
'#26BAY',
'#31SIH',
'#39KUXL',
'#35MEYYYYD',
'#52FER',
'#39TUXUXUXUXUXUXUXUXUXUXUX'
]
# 唱每一行
speech.sing(''.join(line1))
speech.sing(''.join(line2))
speech.sing(''.join(line3))
speech.sing(''.join(line4))
內容解密:
此程式碼展示瞭如何使用 MicroPython 的 speech 模組來讓 micro:bit 唱一首歌。首先定義了歌曲的每一行,每一行都是由多個音符組成,每個音符都指定了音高和發音。然後使用 sing 函式將每一行唱出來。這種技術可以應用於各種創意專案中,例如製作互動式音樂作品或有聲書等。透過調整音符和節奏,可以創造出豐富多樣的音樂效果。
使用 MicroPython 控制機器人
機器人技術因其教育用途而日益普及,許多開發者利用 micro:bit 創造出有趣的機器人專案。本章將探討兩個使用 MicroPython 的機器人專案,展示如何利用 micro:bit 實作簡單的機器人控制。
Trundle Bot 專案
Trundle Bot 是一個簡單的輪式機器人,配備類別比距離感測器,能夠檢測前方障礙物並自動避開。它使用兩個連續旋轉伺服馬達驅動,具有簡單的程式碼和硬體結構。
硬體需求
- micro:bit 主機板
- 2 個 9g 連續旋轉伺服馬達
- Pololu Carrier with Sharp GP2Y0A60SZLF 類別比距離感測器(3V)
- 2 個輪子
- Pololu caster ball
- 可攜式電源(3.3V 至 4.2V)
程式碼解析
from microbit import pin0, pin1, pin2
# 設定伺服馬達控制腳位
left_servo = pin0
right_servo = pin1
# 設定距離感測器腳位
distance_sensor = pin2
def forward():
# 控制伺服馬達向前移動
left_servo.write_analog(180)
right_servo.write_analog(0)
def stop():
# 停止伺服馬達
left_servo.write_analog(90)
right_servo.write_analog(90)
def turn_left():
# 向左轉
left_servo.write_analog(0)
right_servo.write_analog(0)
def turn_right():
# 向右轉
left_servo.write_analog(180)
right_servo.write_analog(180)
while True:
distance = distance_sensor.read_analog()
if distance < 200: # 若偵測到障礙物
stop()
turn_left() # 向左轉
else:
forward() # 向前移動
內容解密:
forward()函式:控制兩個伺服馬達以相反方向旋轉,使機器人向前移動。stop()函式:將伺服馬達的控制訊號設為中間值,使其停止。turn_left()和turn_right()函式:控制伺服馬達以相同方向旋轉,使機器人向左或向右轉。- 距離感測器讀取:透過
distance_sensor.read_analog()讀取距離值,若小於閾值則執行避障動作。
BeatBoxing micro:bit 專案
另一個有趣的專案是使用 micro:bit 製作節奏口技(beatboxing)效果。透過 speech 模組,可以讓 micro:bit 發出類別似口技的聲音,並透過按鈕切換不同的節奏模式。
程式碼範例
import speech
from microbit import sleep, button_a, button_b, display, Image
# 定義口技聲音
bass_drum = "BUH"
snare = "CHIXIX"
roll = "DGDG"
rest = ""
def beat_box(sound):
if sound:
display.show(Image.HEART)
speech.pronounce(sound)
else:
sleep(220)
beats1 = [bass_drum, rest, rest, rest, snare, rest, rest, rest]
beats2 = [bass_drum, snare, snare, snare, bass_drum, snare, roll, roll]
def play(beats):
for beat in beats:
beat_box(beat)
selected = beats1
while True:
if button_a.was_pressed():
selected = beats1
elif button_b.was_pressed():
selected = beats2
play(selected)
內容解密:
beat_box(sound)函式:根據輸入的聲音引數,使用speech.pronounce()發出聲音,若無聲音則暫停一段時間。play(beats)函式:播放指定的節奏序列。- 按鈕控制:透過按鈕 A 和 B 切換不同的節奏模式。
這些範例展示瞭如何利用 MicroPython 控制機器人和創作有趣的音效,為學習者和開發者提供了豐富的創作可能性。
微位元機器人控制系統設計與實作
伺服馬達控制類別實作
微位元機器人的運動控制核心在於伺服馬達的管理,而這部分的功能被封裝在一個名為 Servo 的類別中:
import microbit
class Servo:
def __init__(self, pin, trim=0):
self.pin = pin
self.trim = trim
self.speed = 0
self.pin.set_analog_period(20)
def set_speed(self, speed):
self.pin.write_analog(int(25 + 100 * (90 + speed) / 180 + self.trim))
self.speed = speed
內容解密:
- 初始化引數:建構函式接受兩個引數:
pin(伺服馬達連線的實體針腳)和trim(微調引數,用於補償伺服馬達的效能差異)。 - PWM 設定:透過
set_analog_period(20)設定 PWM 訊號的週期為 20 毫秒,這是伺服馬達控制的標準組態。 - 速度控制:
set_speed方法根據輸入的速度值計算對應的類別比輸出,並寫入指定的針腳,從而控制伺服馬達的轉速。
機器人類設計
機器人的整體控制由 Robot 類別負責整合各個元件:
class Robot:
def __init__(self):
# 記得檢查微調值
self.left_servo = Servo(microbit.pin0, 2)
self.right_servo = Servo(microbit.pin1, 1)
def go(self, distance):
microbit.display.show(microbit.Image.ARROW_S)
self.left_servo.set_speed(-90)
self.right_servo.set_speed(90)
microbit.sleep(int(distance * 2000 / 17))
self.stop()
def turn(self, angle):
if angle > 0:
microbit.display.show(microbit.Image.ARROW_E)
self.left_servo.set_speed(-90)
self.right_servo.set_speed(-90)
microbit.sleep(int(angle * 64 / 9))
else:
microbit.display.show(microbit.Image.ARROW_W)
self.left_servo.set_speed(90)
self.right_servo.set_speed(90)
microbit.sleep(int(-angle * 64 / 9))
self.stop()
def stop(self):
microbit.display.show(microbit.Image.DIAMOND)
self.left_servo.set_speed(0)
self.right_servo.set_speed(0)
def get_distance(self):
return microbit.pin2.read_analog()
內容解密:
- 初始化:建立兩個
Servo例項來控制左右伺服馬達,並可根據需要調整trim值以修正行進方向。 - 運動控制:
go方法控制機器人前進指定距離;turn方法根據給定的角度轉彎;stop方法停止馬達運轉。 - 距離感測:
get_distance方法讀取連線在針腳 2 的距離感測器的類別比值,用於檢測障礙物距離。
簡易自主避障實作
透過簡單的事件迴圈,機器人能夠自主移動並避開障礙物:
robot = Robot()
while True:
robot.go(5)
if robot.get_distance() > 700:
robot.turn(20)
left_distance = robot.get_distance()
robot.turn(-40)
right_distance = robot.get_distance()
robot.turn(20)
if left_distance < right_distance:
robot.turn(60)
else:
robot.turn(-60)
內容解密:
- 基本邏輯:機器人持續前進,當檢測到前方障礙物太近時(距離值大於 700),會暫停並進行左右探測。
- 路徑選擇:比較左右兩側的距離感測值,選擇距離較大的方向進行轉向,以避開障礙物。
Bit:Bot 高階機器人控制
對於像 Bit:Bot 這樣的高階機器人套件,控制邏輯會更加複雜,需要處理更多的感測器輸入和輸出控制,例如 NeoPixels、蜂鳴器和線跟隨感測器等。