Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Модуль вектора

Насколько сильно магнитное поле Земли? Согласно документации к методу magnetic_field(), значения x, y, z, которые мы получаем, выражены в нанотеслах. Значит, чтобы получить величину магнитного поля в нанотеслах, нужно вычислить только модуль трёхмерного вектора, который описывают наши значения x, y, z. Как вы, возможно, помните из школы, он равен:

#![allow(unused)]
fn main() {
use libm::sqrtf;
let magnitude = sqrtf(x * x + y * y + z * z);
}

В core у Rust нет математических функций для чисел с плавающей точкой, таких как sqrtf(), поэтому наша программа no_std должна взять их реализацию откуда-то. Для этого мы используем крейт libm.

Соберём всё это в программу (examples/magnitude.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::{rprintln, rtt_init_print};

use libm::sqrtf;

use microbit::{
    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 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();

    loop {
        while !sensor.mag_status().unwrap().xyz_new_data() {
            timer0.delay_ms(1u32);
        }
        let (x, y, z) = sensor.magnetic_field().unwrap().xyz_nt();
        let (x, y, z) = (x as f32, y as f32, z as f32);
        let magnitude = sqrtf(x * x + y * y + z * z);
        rprintln!("{} mG", magnitude / 100.0);
    }
}

Запустите её командой cargo run --example magnitude.

Программа выводит величину (силу) магнитного поля в нанотеслах (nT) и миллигауссах (mG, где 1 mG = 100 nT). Величина магнитного поля Земли лежит в диапазоне от 250 mG до 650 mG (она зависит от географического положения), так что в идеале вы должны увидеть значение примерно в этом диапазоне. Ваше значение, скорее всего, будет заметно отличаться, потому что датчик не откалиброван: о калибровке см. приложение 3. После калибровки у меня получается величина около 340 mG.

Несколько вопросов:

  • Какое значение вы видите, не двигая плату? Всегда ли оно одинаковое?

  • Меняется ли величина, если поворачивать плату? Должна ли она меняться?