課題
磁場が磁力計の X 軸および Y 軸となす正確な角度を求めるために、少し高度な数学を使います。これにより、どの LED が北を向いているかを特定できます。
atan2 関数を使います。この関数は、-PI から PI の範囲の角度を返します。下の図は、この角度がどのように測定されるかを示しています。
明示的には示されていませんが、この図では X 軸は右向き、Y 軸は上向きです。私たちの座標系はこれから 180° 回転していることに注意してください。
以下がスターターコードです(templates/compass.rs 内)。ラジアン単位の theta は、すでに計算されています。theta の値に基づいて、どの LED を点灯させるかを選ぶ必要があります。
#![deny(unsafe_code)]
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use embedded_hal::delay::DelayNs;
use panic_rtt_target as _;
use rtt_target::rtt_init_print;
// You'll find these useful ;-).
use core::f32::consts::PI;
use libm::{atan2f, floorf};
use microbit::{
display::blocking::Display,
hal::{Timer, twim},
pac::twim0::frequency::FREQUENCY_A,
};
use lsm303agr::{Lsm303agr, MagMode, MagOutputDataRate};
#[entry]
fn main() -> ! {
rtt_init_print!();
let board = microbit::Board::take().unwrap();
let i2c = { twim::Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100) };
let mut timer0 = Timer::new(board.TIMER0);
let mut display = Display::new(board.display_pins);
let mut sensor = Lsm303agr::new_with_i2c(i2c);
sensor.init().unwrap();
sensor.set_mag_mode_and_odr(
&mut timer0,
MagMode::HighResolution,
MagOutputDataRate::Hz10,
).unwrap();
let mut sensor = sensor.into_mag_continuous().ok().unwrap();
let mut leds = [[0u8; 5]; 5];
// Indexes of the 16 LEDs to be used in the display, and their
// compass directions.
#[rustfmt::skip]
let indices = [
(2, 0) /* W */, (3, 0) /* W-SW */, (3, 1) /* SW */, (4, 1) /* S-SW */,
(4, 2) /* S */, (4, 3) /* S-SE */, (3, 3) /* SE */, (3, 4) /* E-SE */,
(2, 4) /* E */, (1, 4) /* E-NE */, (1, 3) /* NE */, (0, 3) /* N-NE */,
(0, 2) /* N */, (0, 1) /* N-NW */, (1, 1) /* NW */, (1, 0) /* W-NW */,
];
loop {
// Measure the magnetic field.
let (x, y) = todo!();
// Get an angle between -180° and 180° from the x axis.
let theta = atan2f(y as f32, x as f32);
// Figure out what LED index to blink.
let index = todo!();
// Blink the given LED.
let (r, c) = indices[index];
leds[r][c] = 255u8;
display.show(&mut timer0, leds, 50);
leds[r][c] = 0u8;
display.show(&mut timer0, leds, 50);
}
}
提案/ヒント:
- 円を 1 周回転すると 360 度です。
PIラジアンは 180 度に相当します。thetaが 0 なら、どの方向を指していますか?- では、
thetaが 0 に非常に近い場合は、どの方向を指していますか? thetaが増え続けるとしたら、どの値で方向を変えるべきでしょうか