lis2dh12 (0.1.0)

Published 2026-03-08 13:40:56 +00:00 by faicel

Installation

[registries.forgejo]
index = "sparse+" # Sparse index
# index = "" # Git

[net]
git-fetch-with-cli = true
cargo add lis2dh12@0.1.0 --registry forgejo

About this package

LIS2DH12 Accelerometer Driver

no_std library for the STMicroelectronics LIS2DH12 3-axis accelerometer sensor, using the I2C interface.

Features

  • no_std compatible for embedded systems
  • Uses embedded-hal traits for I2C
  • Implements standard Accelerometer and RawAccelerometer traits from the accelerometer crate
  • 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 = LOW
  • 0x19 : 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 mode
  • DataRate::Hz_1 : 1 Hz
  • DataRate::Hz_10 : 10 Hz
  • DataRate::Hz_25 : 25 Hz
  • DataRate::Hz_50 : 50 Hz
  • DataRate::Hz_100 : 100 Hz
  • DataRate::Hz_200 : 200 Hz
  • DataRate::Hz_400 : 400 Hz
  • DataRate::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
Details
Cargo
2026-03-08 13:40:56 +00:00
2
625 KiB
Assets (1)
Versions (1) View all
0.1.0 2026-03-08