スピーカー
micro:bit v2 には組み込みスピーカーが搭載されているため、追加のハードウェアを接続しなくても、音やトーン、さらにはシンプルなメロディまで再生できます。スピーカーは内部で GPIO ピンの 1 つに接続されており、ソフトウェアから適切な信号を送ることで、さまざまな音高を出せます。
microbit-bsp API を使う
microbit-bsp crate を使うと、スピーカーを簡単に利用できます。低レベルな詳細をすべて処理してくれる高水準 API が提供されています。内部では、PWM(パルス幅変調)と呼ばれるものを使ってトーンを生成しています。PWM が何かはまだ気にしなくて大丈夫です。これについては後の章で扱います。ここでは API を使うだけにしましょう。
コード例
この例は、microbit-bsp crate の公式 GitHub リポジトリ から取られています。組み込みスピーカーを使ってシンプルなメロディを再生します。この crate は NamedPitch のような補助 enum を提供しており、各バリアントが音符を表します。そのため、なじみのある音名を使って独自の曲を簡単に定義できます。
#![no_std] #![no_main] use embassy_executor::Spawner; use embassy_time::Timer; use microbit_bsp::{ embassy_nrf::pwm::SimplePwm, speaker::{NamedPitch, Note, PwmSpeaker}, Microbit, }; use {defmt_rtt as _, panic_probe as _}; const TUNE: [(NamedPitch, u32); 18] = { #[allow(clippy::enum_glob_use)] use NamedPitch::*; [ (D4, 1), (DS4, 1), (E4, 1), (C5, 2), (E4, 1), (C5, 2), (E4, 1), (C5, 3), (C4, 1), (D4, 1), (DS4, 1), (E4, 1), (C4, 1), (D4, 1), (E4, 2), (B4, 1), (D5, 2), (C4, 4), ] }; #[embassy_executor::main] async fn main(_s: Spawner) { let board = Microbit::default(); defmt::info!("Application started!"); let mut speaker = PwmSpeaker::new(SimplePwm::new_1ch(board.pwm0, board.speaker)); loop { defmt::info!("Playing tune!"); for (pitch, ticks) in TUNE { speaker.play(&Note(pitch.into(), 200 * ticks)).await; } Timer::after_secs(5).await; } }
ここでは、TUNE 配列で定義された各音高を順に処理し、指定された tick 数だけ再生します。長さは単純に ticks * 200 ミリ秒です。したがって、ある音符の ticks = 2 であれば、400 ms 再生されます。