Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

LEDで遊ぼう

ふう……長い章でしたね。始めたばかりなら、少し圧倒されたかもしれません。ですが、ここでひと休みして、LED マトリクスで遊んでみましょう!

BSP には、シンプルで初心者にも扱いやすい API が用意されています。micro:bit 上の LED マトリクスの実際の配置に合わせた 2 次元配列を定義するだけで使えます。LED を点灯するには 1、消灯するには 0 を使います。残りの処理はすべて BSP が裏側で引き受けてくれます。

これは、ハート形を表示する LED マトリクスの例です。Ferris(カニ)の形も作ってみたのですが、あまりそれらしく見えず、これがカニだと納得してもらう必要がありそうでした。なので、代わりに素直にハート形を表示することにします。

#![allow(unused)]
fn main() {
// ハート形の LED マトリクス
let led_matrix = [
    [0, 1, 0, 1, 0],
    [1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1],
    [0, 1, 1, 1, 0],
    [0, 0, 1, 0, 0],
];
}

Display

BSP は Display 構造体を提供しており、ボードの display_pins を使って初期化できます。いくつか便利な関数が用意されていますが、特に重要なのは showclear です。show 関数は 2 次元配列を受け取り、与えた値に応じて LED を点灯します。内部でどのように動作しているのか気になる場合は、ソースコードをこちらで確認できます。

テンプレートからプロジェクトを作成

これからは、新しいプロジェクトを始めるたびに .cargo/config.tomlmemory.x を作成したり、依存関係を手動で追加したりすることはしません(基本的な依存関係だけであっても)。代わりに、テンプレートベースの方法を使って、プロジェクトのセットアップをずっと簡単にします。

テンプレートを使って新しいプロジェクトを生成するには、次のコマンドを実行します。

cargo generate --git https://github.com/ImplFerris/mb2-template.git --rev 88d339b

プロジェクト名の入力を求められたら、led-matrix のような名前を入力してください。

"BSP" または "HAL" を選択するよう求められたら、"BSP" を選んでください。

プロジェクトが作成されたら、src/main.rs を次のコードで更新します。

完全なコード

#![no_std]
#![no_main]

use embedded_hal::delay::DelayNs;
use microbit::{board::Board, display::blocking::Display, hal::timer::Timer};

use cortex_m_rt::entry;

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

#[entry]
fn main() -> ! {
    let board = Board::take().unwrap();

    let mut timer = Timer::new(board.TIMER0);

    let mut display = Display::new(board.display_pins);
    let led_matrix = [
        [0, 1, 0, 1, 0],
        [1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1],
        [0, 1, 1, 1, 0],
        [0, 0, 1, 0, 0],
    ];
    loop {
        display.show(&mut timer, led_matrix, 1000);
        display.clear();
        timer.delay_ms(1000);
    }
}

このコードの内容はほとんどすべて直感的でシンプルですが、ひとつだけ気になる点があります。show 関数の 3 番目の引数、つまり 1000 を渡しているあれは何でしょうか?

これは duration_ms と呼ばれますが、その duration は何に使われているのでしょうか? いいえ、点滅効果のためではありません。点滅はすでに次のコードで別途処理しています。

#![allow(unused)]
fn main() {
display.clear();
timer.delay_ms(1000);
}

では、duration_ms は実際には何をしているのでしょうか?

前に学んだように、micro:bit の 5x5 LED マトリクスは多重化されています。一度に点灯するのは 1 行だけで、列は画像に応じて設定されます。内部では show 関数が各行を順番に処理し、正しい LED を点灯させ、delay.delay_us(...) で少し待ってから、次の行に移ります。

この走査は非常に高速に行われるため、画像全体が一度に表示されているように見えます。duration_ms の値は、この走査をどれくらいの時間繰り返すかをディスプレイに指示します。

要するに: duration_ms(3 番目の引数)は、画像が画面に表示され続ける時間を制御します。その値を調整して、変化を確認してみてください。

既存のプロジェクトをクローン

私が作成したプロジェクトをクローン(または参照)して、led-matrix フォルダーに移動することもできます。

git clone https://github.com/ImplFerris/microbit-projects
cd microbit-projects/bsp/led-matrix

書き込み

プログラムを micro:bit に書き込むと、点滅するハート形が表示されるはずです

cargo flash