lis2dh12 (0.1.0)
Installation
[registries.forgejo]
index = "sparse+ " # Sparse index
# index = " " # Git
[net]
git-fetch-with-cli = truecargo add lis2dh12@0.1.0 --registry forgejoAbout this package
LIS2DH12 Accelerometer Driver
no_std library for the STMicroelectronics LIS2DH12 3-axis accelerometer sensor, using the I2C interface.
Features
no_stdcompatible for embedded systems- Uses
embedded-haltraits for I2C - Implements standard
AccelerometerandRawAccelerometertraits from theaccelerometercrate - Support for multiple measurement ranges (±2g, ±4g, ±8g, ±16g)
- Support for different power modes (high resolution, normal, low power)
- Configurable data rates (1 Hz to 5.376 kHz)
- Reads acceleration data on all 3 axes (X, Y, Z)
- Interrupt support for threshold detection on INT1 and INT2 pins
- 6D position detection
Usage
Basic Example
use lis2dh12::{Lis2dh12, Range, DataRate, SlaveAddr};
use embedded_hal::i2c::I2c;
use accelerometer::Accelerometer;
// Initialize the driver with SA0 pin LOW (0x18)
let mut accel = Lis2dh12::new(i2c, SlaveAddr::Low)?;
// Configure measurement range (±2g)
accel.set_range(Range::G2)?;
// Configure data rate (100 Hz)
accel.set_data_rate(DataRate::Hz_100)?;
// Read acceleration data using the Accelerometer trait
let accel_data = accel.accel_norm()?;
println!("X: {} g, Y: {} g, Z: {} g", accel_data.x, accel_data.y, accel_data.z);
Advanced Configuration
use lis2dh12::{Lis2dh12, Range, DataRate, PowerMode, SlaveAddr};
use accelerometer::Accelerometer;
let mut accel = Lis2dh12::new(i2c, SlaveAddr::Low)?;
// Configure for high resolution (12-bit)
accel.set_power_mode(PowerMode::HighResolution)?;
// Configure for ±4g
accel.set_range(Range::G4)?;
// Configure for 400 Hz
accel.set_data_rate(DataRate::Hz_400)?;
// Read data using the trait method
let data = accel.accel_norm()?;
// Or read raw values
use accelerometer::RawAccelerometer;
let raw_data = accel.accel_raw()?;
I2C Addresses
The LIS2DH12 supports two I2C addresses depending on the SA0 pin state:
0x18: SA0 = LOW0x19: SA0 = HIGH
Use the SlaveAddr enum to specify the address explicitly:
use lis2dh12::{Lis2dh12, SlaveAddr};
// Address when SA0 pin is LOW (0x18)
let mut accel = Lis2dh12::new(i2c, SlaveAddr::Low)?;
// Address when SA0 pin is HIGH (0x19)
let mut accel = Lis2dh12::new(i2c, SlaveAddr::High)?;
The constants LIS2DH12_I2C_ADDRESS_LOW and LIS2DH12_I2C_ADDRESS_HIGH are also available in the driver module.
Measurement Ranges
Range::G2: ±2g (1 mg/LSB in high resolution mode)Range::G4: ±4g (2 mg/LSB in high resolution mode)Range::G8: ±8g (4 mg/LSB in high resolution mode)Range::G16: ±16g (12 mg/LSB in high resolution mode)
Power Modes
PowerMode::HighResolution: High resolution mode (12-bit)PowerMode::Normal: Normal mode (10-bit)PowerMode::LowPower: Low power mode (8-bit)
Data Rates
DataRate::PowerDown: Power down modeDataRate::Hz_1: 1 HzDataRate::Hz_10: 10 HzDataRate::Hz_25: 25 HzDataRate::Hz_50: 50 HzDataRate::Hz_100: 100 HzDataRate::Hz_200: 200 HzDataRate::Hz_400: 400 HzDataRate::Hz_1600_LP: 1.6 kHz (low power mode only)DataRate::Hz_5376: 5.376 kHz (normal/high resolution) or 1.344 kHz (low power)
Interrupts
The LIS2DH12 supports two interrupt pins (INT1 and INT2) for threshold detection and other events.
Basic Interrupt Configuration
use lis2dh12::{Lis2dh12, InterruptConfig, InterruptMode, InterruptPin, SlaveAddr};
let mut accel = Lis2dh12::new(i2c, SlaveAddr::Low)?;
// Configure INT1 to trigger when X-axis exceeds high threshold
let config = InterruptConfig::new()
.with_x_high(true)
.with_mode(InterruptMode::Or); // OR mode (interrupt if any condition is met)
accel.configure_interrupt(InterruptPin::Int1, config)?;
// Set threshold to 32 (32 * 16 mg = 512 mg in ±2g range)
accel.set_interrupt_threshold(InterruptPin::Int1, 32)?;
// Set minimum duration to 2 samples
accel.set_interrupt_duration(InterruptPin::Int1, 2)?;
// Enable the interrupt pin (active high)
accel.enable_interrupt_pin(InterruptPin::Int1, true, true)?;
Reading Interrupt Source
In your interrupt handler, read the interrupt source to determine what triggered the interrupt:
// In your interrupt handler:
let source = accel.read_interrupt_source(InterruptPin::Int1)?;
if source.active {
if source.x_high {
// X-axis high threshold exceeded
}
if source.y_high {
// Y-axis high threshold exceeded
}
// ... check other axes
}
Important: Reading the interrupt source register clears the interrupt flag. Always read it in your interrupt handler.
Multiple Axes and AND/OR Mode
// Configure interrupt for multiple axes in OR mode
let config = InterruptConfig::new()
.with_x_high(true)
.with_y_high(true)
.with_z_high(true)
.with_mode(InterruptMode::Or); // OR: interrupt if ANY axis exceeds threshold
accel.configure_interrupt(InterruptPin::Int1, config)?;
// OR configure in AND mode
let config = InterruptConfig::new()
.with_x_high(true)
.with_y_high(true)
.with_mode(InterruptMode::And); // AND: interrupt only if ALL enabled axes exceed threshold
accel.configure_interrupt(InterruptPin::Int1, config)?;
6D Position Detection
The LIS2DH12 can detect position changes in 6 directions:
let config = InterruptConfig::new()
.with_six_d(true) // Enable 6D detection
.with_x_high(true)
.with_x_low(true)
.with_y_high(true)
.with_y_low(true)
.with_z_high(true)
.with_z_low(true);
accel.configure_interrupt(InterruptPin::Int1, config)?;
Tests
Tests use embedded-hal-mock to simulate the I2C interface:
cd lis2dh12
cargo test
Documentation
For more information about the LIS2DH12, consult the official datasheet from STMicroelectronics.
Dependencies
| ID | Version |
|---|---|
| accelerometer | ^0.12 |
| cast | ^0.3 |
| embedded-hal | ^1.0.0 |
| embedded-hal-mock | ^0.11.1 |