1 unstable release
0.1.0 | Mar 17, 2020 |
---|
#1627 in Embedded development
58KB
1K
SLoC
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
- SPI communication with Accelerometer/Gyroscope
- SPI communication with Magnetometer
- SPI communication with Temperature Sensor
- I2C communication with Accelerometer/Gyroscope
- I2C communication with Magnetometer
- I2C communication with Temperature Sensor
- Custom sensor settings
- Sensor reading (Accel, Gyro, Mag, Temperature)
- Raw Sensor reading (Accel, Gyro, Mag) See
read_sensor_raw()
. - Calibration
- Interrupt
- FIFO Mode
Usage
Overview
- Configure sensor settings with
LSM9DS1Init
. - Initialize a communication interface: either
SpiInterface
orI2cInterface
. - 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, // custom setting
..Default::default() // the rest of the fields are the default values.
},
..Default::default() // gyro and mag use the default settings.
}
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.
// Create SPI interface
let spi_interface = SpiInterface::init(spi, ag_cs, m_cs);
// Init LSM9DS1 driver with settings and SPI interface
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(); // temperature reading in celsius
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.)
//! Target board: STM32F3DISCOVERY
#![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();
// Accelerometer/Gyroscope Chip Select
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();
// Magnetometer Chip Select
let mut m_cs = gpiob
.pb4
.into_push_pull_output(&mut gpiob.moder, &mut gpiob.otyper);
m_cs.set_high().unwrap();
// SPI
let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);
let clocks = rcc.cfgr.freeze(&mut flash.acr);
// Configure pins for SPI
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,
);
// Create SPI interface
let spi_interface = SpiInterface::init(spi, ag_cs, m_cs);
// Init LSM9DS1 with default settings and attach SPI interface
let mut lsm9ds1 = LSM9DS1Init {
..Default::default()
}
.with_interface(spi_interface);
// start sensors
lsm9ds1.begin_accel().unwrap();
lsm9ds1.begin_gyro().unwrap();
lsm9ds1.begin_mag().unwrap();
loop {
// read sensors
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);
}
}
Dependencies
~71KB