lsm9ds1

A platform agnostic driver to interface with LSM9DS1 3D accelerometer, 3D gyroscope, 3D magnetometer sensor module.
This library is work in progress. Not all features are implemented yet. Contributions are welcome.
Features
Usage
Overview
- Configure sensor settings with
LSM9DS1Init.
- Initialize a communication interface: either
SpiInterface or I2cInterface.
- Initialize
LSM9DS1 driver with the interface of your choice.
- Start the sensors.
- Get the sensors' readings.
Sensor Settings
This driver uses LSM9DS1Init struct to set sensor configuration.
pub struct LSM9DS1Init {
pub accel: AccelSettings,
pub gyro: GyroSettings,
pub mag: MagSettings,
}
You can find each sensor's default settings in accel.rs, gyro.rs and mag.rs.
Accelerometer default settings
impl Default for AccelSettings {
fn default() -> Self {
AccelSettings {
enable_x: true,
enable_y: true,
enable_z: true,
sample_rate: ODR::_119Hz,
scale: Scale::_2G,
bandwidth_selection: BandwidthSelection::ByODR,
bandwidth: Bandwidth::_408Hz,
high_res_bandwidth: HighRes::Disabled,
}
}
}
Gyroscope default settings
impl Default for GyroSettings {
fn default() -> Self {
GyroSettings {
enable_x: true,
enable_y: true,
enable_z: true,
flip_x: false,
flip_y: false,
flip_z: false,
scale: Scale::_245DPS,
sample_rate: ODR::_952Hz,
bandwidth: Bandwidth::LPF_0,
int_selection: GyroIntSelection::SEL_0,
out_selection: GyroOutSelection::SEL_0,
low_power_mode: LowPowerMode::Disabled,
hpf_mode: HpFilter::Disabled,
hpf_cutoff: HpFilterCutoff::HPCF_1,
latch_interrupt: LatchInterrupt::Disabled,
}
}
}
Magnetometer default settings
impl Default for MagSettings {
fn default() -> Self {
MagSettings {
temp_compensation: TempComp::Disabled,
x_y_performance: OpModeXY::Low,
sample_rate: ODR::_10Hz,
scale: Scale::_4G,
i2c_mode: I2cMode::Enabled,
system_op: SysOpMode::Continuous,
low_power: LowPowerMode::Disabled,
spi_mode: SpiMode::RW,
z_performance: OpModeZ::Low,
}
}
}
How to configure settings
If you want to use the default settings, initialize LSM9DS1Init this way.
LSM9DS1Init {
..Default::default()
}
If you want a custom configuration, modify the fields that are different from the default values.
LSM9DS1Init {
accel: accel::AccelSettings {
scale: accel::Scale::_16G, ..Default::default() },
..Default::default() }
Communication Interface
LSM9DS1 supports SPI and I2C communication. Create an instance of SpiInterface or I2cInterface and pass it to LSM9DS1Init's with_interface() method to create an instance of LSM9DS1 driver.
let spi_interface = SpiInterface::init(spi, ag_cs, m_cs);
let mut lsm9ds1 = LSM9DS1Init {
..Default::default()
}
.with_interface(spi_interface);
Reading Sensors
Turn on sensors.
lsm9ds1.begin_accel().unwrap();
lsm9ds1.begin_gyro().unwrap();
lsm9ds1.begin_mag().unwrap();
Get readings
let temp = lsm9ds1.read_temp().unwrap(); let (x, y, z) = lsm9ds1.read_accel().unwrap();
let (x, y, z) = lsm9ds1.read_gyro().unwrap();
let (x, y, z) = lsm9ds1.read_mag().unwrap();
Example
This code shows how to read sensor values with SPI interface. (Error handling is omitted for brevity.)
#![no_std]
#![no_main]
extern crate panic_semihosting;
pub use cortex_m::{asm::bkpt, iprint, iprintln, peripheral::ITM};
use cortex_m_rt::entry;
use embedded_hal::spi::MODE_0;
use stm32f3xx_hal as hal;
use hal::prelude::*;
use hal::spi::Spi;
use hal::stm32;
use lsm9ds1::interface::SpiInterface;
use lsm9ds1::{accel, gyro, mag, LSM9DS1Init};
#[entry]
fn main() -> ! {
let cp = cortex_m::Peripherals::take().unwrap();
let mut itm = cp.ITM;
let dp = stm32::Peripherals::take().unwrap();
let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
let mut gpiob = dp.GPIOB.split(&mut rcc.ahb);
let mut ag_cs = gpiob
.pb5
.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
ag_cs.set_high().unwrap();
let mut m_cs = gpiob
.pb4
.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
m_cs.set_high().unwrap();
let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);
let clocks = rcc.cfgr.freeze(&mut flash.acr);
let sck = gpioa.pa5.into_af5(&mut gpioa.moder, &mut gpioa.afrl);
let miso = gpioa.pa6.into_af5(&mut gpioa.moder, &mut gpioa.afrl);
let mosi = gpioa.pa7.into_af5(&mut gpioa.moder, &mut gpioa.afrl);
let spi = Spi::spi1(
dp.SPI1,
(sck, miso, mosi),
MODE_0,
1.mhz(),
clocks,
&mut rcc.apb2,
);
let spi_interface = SpiInterface::init(spi, ag_cs, m_cs);
let mut lsm9ds1 = LSM9DS1Init {
..Default::default()
}
.with_interface(spi_interface);
lsm9ds1.begin_accel().unwrap();
lsm9ds1.begin_gyro().unwrap();
lsm9ds1.begin_mag().unwrap();
loop {
let temp = lsm9ds1.read_temp().unwrap();
iprintln!(&mut itm.stim[0], "temp: {}", temp);
let (x, y, z) = lsm9ds1.read_accel().unwrap();
iprintln!(&mut itm.stim[0], "xl: {}, {}, {}", x, y, z);
let (x, y, z) = lsm9ds1.read_gyro().unwrap();
iprintln!(&mut itm.stim[0], "gy: {}, {}, {}", x, y, z);
let (x, y, z) = lsm9ds1.read_mag().unwrap();
iprintln!(&mut itm.stim[0], "mg: {}, {}, {}", x, y, z);
cortex_m::asm::delay(8_000_000);
}
}