My Solution
Here's my solution (in src/main.rs
):
#![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::{twim, Timer}, 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 { while !sensor.mag_status().unwrap().xyz_new_data() { timer0.delay_ms(1u32); } let (x, y, _) = sensor.magnetic_field().unwrap().xyz_nt(); // Get an angle between -180° and 180° from the x axis. let theta = atan2f(y as f32, x as f32); // Cut the unit circle into thirty-two segments, // with pairs of adjacent segments corresponding to // each compass direction. let seg = floorf(16.0 * theta / PI) as i8; // Figure out what LED index to blink. let index = if seg >= 15 || seg <= -15 { 8 } else if seg >= 0 { (seg / 2) as usize } else { ((31 + seg) / 2) as usize }; // 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); } }