スマイリーボタン
この章では、micro:bit の 2 つのオンボードボタンの使い方を見ていきます。Smiley Buttons プロジェクトは、インタラクティブな入力を導入する、初心者にやさしい優れた演習です。内蔵ボタン A と B を押すことで、micro:bit の LED 画面に異なる表情を表示します。
-
ボタン A を押すと、うれしい顔 😊 を表示します
-
ボタン B を押すと、悲しい顔 🙁 を表示します
ボタンを理解する
🪝 micro:bit のドキュメントより:
ボタンは一般的な反転電気モードで動作し、プルアップ抵抗によってボタンが離されているときは論理値 ‘1’ が保証され、ボタンが押されているときは論理値 ‘0’ になります
最初は少し技術的に聞こえるかもしれませんので、もう少しわかりやすく説明します。
ボタンが押されていないとき、micro:bit は入力を論理 HIGH(つまり 1)として読み取ります。これは、入力ピンの電圧レベルを高く保つプルアップ抵抗があるためです。
ボタンが押されると、回路はグラウンドに接続され、micro:bit は論理 LOW(つまり 0)を読み取ります。
ボタンを押すことは直感的には何かを有効にすることのように思えるかもしれませんが、ハードウェアは反転した方式で動作します。コードでは、ボタンが押されたことを検出するために LOW 信号を確認します。そのため、ボタン入力に対して is_low() メソッドを使い、押されているかどうかを確認します。
テンプレートからプロジェクトを作成する
テンプレートを使って新しいプロジェクトを生成するには、次のコマンドを実行します。
cargo generate --git https://github.com/ImplFerris/mb2-template.git --rev 88d339b
プロジェクト名を求められたら、smiley-buttons のような名前を入力します
"BSP" または "HAL" を選択するよう求められたら、"BSP" を選択します。
絵文字用のマトリクス
以下は、うれしい顔と悲しい顔を表す 2 次元配列です。
#![allow(unused)] fn main() { let happy_face = [ [0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0], ]; let sad_face = [ [0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [1, 0, 0, 0, 1], ]; }
初期化
いつものように、まずボードを初期化し、その後でディスプレイとタイマーを初期化します。また、扱いやすいように、ボードから button_a と button_b を取得して変数に保存します。
#![allow(unused)] fn main() { let board = Board::take().unwrap(); let mut display = Display::new(board.display_pins); let mut timer = Timer::new(board.TIMER0); let mut button_a = board.buttons.button_a; let mut button_b = board.buttons.button_b; }
ボタン入力とスマイリーの表示
ボタンとディスプレイの初期化が完了したので、ボタン入力に反応し、LED 画面に適切な表情を表示するループを書けます。
#![allow(unused)] fn main() { loop { let a_pressed = button_a.is_low().unwrap_or(false); let b_pressed = button_b.is_low().unwrap_or(false); if a_pressed { display.show(&mut timer, happy_face, 1000); timer.delay_ms(100); } else if b_pressed { display.show(&mut timer, sad_face, 1000); timer.delay_ms(100); } } }
このループでは、.is_low() メソッドを使って各ボタンの状態を確認します。micro:bit のボタンはアクティブローなので、このメソッドはボタンが押されているときに true を返します。潜在的なエラーに対処するために .unwrap_or(false) を使っています。何らかの理由で結果を読み取れない場合は、単に false を返し、ボタンは押されていないものとして扱われます。
ボタン A が押されると、うれしい顔のパターンが 1 秒間 LED ディスプレイに表示されます。同様に、ボタン B が押されると、悲しい顔が表示されます。
各表示の後には 100 ミリ秒の短い遅延が入り、視覚的にわかりやすい効果を与えるとともに、ボタンを押し続けていることによる繰り返し更新を防ぎます。
完全なコード
この演習には、前回にはなかった新しい import が含まれています: embedded_hal::digital::InputPin。この trait は Embedded HAL の一部であり、入力ピンの状態を読み取るための is_low() や is_high() のようなメソッドを提供します。
#![no_std] #![no_main] use cortex_m_rt::entry; use embedded_hal::{delay::DelayNs, digital::InputPin}; use microbit::{display::blocking::Display, hal::Timer, Board}; #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } #[entry] fn main() -> ! { let board = Board::take().unwrap(); let mut display = Display::new(board.display_pins); let mut timer = Timer::new(board.TIMER0); let mut button_a = board.buttons.button_a; let mut button_b = board.buttons.button_b; let happy_face = [ [0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0], ]; let sad_face = [ [0, 0, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [1, 0, 0, 0, 1], ]; loop { let a_pressed = button_a.is_low().unwrap_or(false); let b_pressed = button_b.is_low().unwrap_or(false); if a_pressed { display.show(&mut timer, happy_face, 1000); timer.delay_ms(100); } else if b_pressed { display.show(&mut timer, sad_face, 1000); timer.delay_ms(100); } } }
既存のプロジェクトをクローンする
私が作成したプロジェクトをクローン(または参照)して、bsp/smiley-buttons フォルダーに移動することもできます。
git clone https://github.com/ImplFerris/microbit-projects
cd microbit-projects/bsp/smiley-buttons
書き込み
コードが完成したら、次のコマンドを使ってプログラムを micro:bit に書き込めます。
cargo flash
プログラムがデバイス上で動作すると、button A を押すとうれしい顔が表示され、button B を押すと LED ディスプレイに悲しい顔が表示されます。
