My solution
Here's my solution (src/main.rs
). Note that you can get quite high G values by rapping the edge of
your MB2 on a table. Note also that this can break the accelerometer, so probably don't?
#![deny(unsafe_code)]
#![no_main]
#![no_std]
const TICKS_PER_SEC: u32 = 400;
const THRESHOLD: f32 = 1.5;
use cortex_m::asm::nop;
use cortex_m_rt::entry;
use panic_rtt_target as _;
use rtt_target::{rprintln, rtt_init_print};
use microbit::{
hal::{twim, Timer},
pac::twim0::frequency::FREQUENCY_A,
};
use lsm303agr::{AccelMode, AccelOutputDataRate, AccelScale, Lsm303agr};
#[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 delay = Timer::new(board.TIMER0);
let mut sensor = Lsm303agr::new_with_i2c(i2c);
sensor.init().unwrap();
sensor
.set_accel_mode_and_odr(&mut delay, AccelMode::Normal, AccelOutputDataRate::Hz400)
.unwrap();
// Allow the sensor to measure up to 16 G since human punches
// can actually be quite fast
sensor.set_accel_scale(AccelScale::G16).unwrap();
let mut max_g = 0.;
let mut countdown_ticks = None;
loop {
while !sensor.accel_status().unwrap().xyz_new_data() {
nop();
}
// x acceleration in g
let (x, _, _) = sensor.acceleration().unwrap().xyz_mg();
let g_x = x as f32 / 1000.0;
if let Some(ticks) = countdown_ticks {
if ticks > 0 {
// countdown isn't done yet
if g_x > max_g {
max_g = g_x;
}
countdown_ticks = Some(ticks - 1);
} else {
// Countdown is done: report max value
rprintln!("Max acceleration: {}g", max_g);
// Reset
max_g = 0.;
countdown_ticks = None;
}
} else {
// If acceleration goes above a threshold, we start measuring
if g_x > THRESHOLD {
rprintln!("START!");
max_g = g_x;
countdown_ticks = Some(TICKS_PER_SEC);
}
}
}
}