第一弾

LEDをコンパスを実装する最も単純な方法はどのようなものでしょうか?例えそれが完璧でなかったとしても。

初心者のために、磁場のXとYの要素だけを取り扱います。なぜならコンパスを見る時、常にコンパスを水平に保ちます。 従って、コンパスはXY平面にあると考えます。

例えば、次の場合に、どのLEDを点灯するでしょうか。EMFは地球磁場を意味しており、緑の矢印はEMFの方向です(北を向いています)。

南東のLEDで良いでしょうか?

この場合、磁場のXとY要素の符号は何になっているでしょうか?両方ともに正数です。

XとY要素の符号だけを見る場合、磁場が4象限のどこに属しているか、を決定できます。

前の例では、磁場は第一象限に属していました(xとyは正)。そして、南東のLEDを点灯することがわかりました。 同様に、磁場が別の象限に属している場合に、別のLEDを点灯します。

このロジックを試してみましょう。スターターコードは、次の通りです。

#![deny(unsafe_code)]
#![no_main]
#![no_std]

#[allow(unused_imports)]
use aux15::{entry, iprint, iprintln, prelude::*, Direction, I16x3};

#[entry]
fn main() -> ! {
    let (mut leds, mut lsm303dlhc, mut delay, _itm) = aux15::init();

    loop {
        let I16x3 { x, y, .. } = lsm303dlhc.mag().unwrap();

        // 磁場がどの象限に属するか決めるため、XとY要素の符号を見ます。
        let dir = match (x > 0, y > 0) {
            // 第???象限
            (true, true) => Direction::Southeast,
            // 第???象限
            (false, true) => panic!("TODO"),
            // 第???象限
            (false, false) => panic!("TODO"),
            // 第???象限
            (true, false) => panic!("TODO"),
        };

        leds.iter_mut().for_each(|led| led.off());
        leds[dir].on();

        delay.delay_ms(1_000_u16);
    }
}

ledモジュールには、Direction列挙体があります。 この列挙体は、NorthEastSouthwestのように、方位に基づいて名付けられた8個のヴァリアントがあります。 各ヴァリアントは、円形に並んだ8個のLEDを表しています。 Ledsの値は、Direction enumを使ってインデックスアクセスできます。 インデックスアクセスの結果は、Directionを向いたLEDです。