#![deny(unsafe_code)]
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use rtt_target::{rtt_init_print, rprintln};
use panic_rtt_target as _;
#[cfg(feature = "v1")]
use microbit::{
hal::twi,
pac::twi0::frequency::FREQUENCY_A,
};
#[cfg(feature = "v2")]
use microbit::{
hal::twim,
pac::twim0::frequency::FREQUENCY_A,
};
use lsm303agr::{
AccelScale, AccelOutputDataRate, Lsm303agr,
};
use microbit::hal::timer::Timer;
use microbit::hal::prelude::*;
use nb::Error;
#[entry]
fn main() -> ! {
const THRESHOLD: f32 = 0.5;
rtt_init_print!();
let board = microbit::Board::take().unwrap();
#[cfg(feature = "v1")]
let i2c = { twi::Twi::new(board.TWI0, board.i2c.into(), FREQUENCY_A::K100) };
#[cfg(feature = "v2")]
let i2c = { twim::Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::K100) };
let mut countdown = Timer::new(board.TIMER0);
let mut delay = Timer::new(board.TIMER1);
let mut sensor = Lsm303agr::new_with_i2c(i2c);
sensor.init().unwrap();
sensor.set_accel_odr(AccelOutputDataRate::Hz50).unwrap();
// 16Gまで計測できるようにセンサの設定を変更。
// 人のパンチは案外速いものです。
sensor.set_accel_scale(AccelScale::G16).unwrap();
let mut max_g = 0.;
let mut measuring = false;
loop {
while !sensor.accel_status().unwrap().xyz_new_data {}
// X軸の加速度をg単位で取得
let g_x = sensor.accel_data().unwrap().x as f32 / 1000.0;
if measuring {
// contdownタイマのステータスをチェック
match countdown.wait() {
// countdownはまだ終わっていない
Err(Error::WouldBlock) => {
if g_x > max_g {
max_g = g_x;
}
},
// countdown終了
Ok(_) => {
// 最大加速度を報告
rprintln!("Max acceleration: {}g", max_g);
// リセット
max_g = 0.;
measuring = false;
},
// nrf52とnrf51のHALはエラー型としてVoidを返します。
// VoidはEmpty型なので、ここにたどり着くことはありません。
Err(Error::Other(_)) => {
unreachable!()
}
}
} else {
// 加速度がしきい値を超えれば測定を開始
if g_x > THRESHOLD {
rprintln!("START!");
measuring = true;
max_g = g_x;
// ドキュメンテーションによると、タイマは1Mhzで動作します。
// よって、1秒待つためには1_000_000ティック必要です。
countdown.start(1_000_000_u32);
}
}
delay.delay_ms(20_u8);
}
}