第一弾
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::*, switch_hal::OutputSwitch, Direction, I16x3}; #[entry] fn main() -> ! { let (leds, mut lsm303dlhc, mut delay, _itm) = aux15::init(); let mut leds = leds.into_array(); 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().unwrap()); leds[dir as usize].on().unwrap(); delay.delay_ms(1_000_u16); } }
led
モジュールには、Direction
列挙体があります。
この列挙体は、North
、East
、Southwest
のように、方位に基づいて名付けられた8個のヴァリアントがあります。
各ヴァリアントは、円形に並んだ8個のLEDを表しています。
Leds
の値は、Direction
enum
を使ってインデックスアクセスできます。
インデックスアクセスの結果は、Direction
を向いたLEDです。