Expand description

This is a platform agnostic Rust driver for the MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC and MMA8653FC tri-axis accelerators using the embedded-hal traits.

This driver allows you to:

The devices

The devices are intelligent, low-power, three-axis, capacitive micromachined accelerometers with 10/12/14 bits of resolution. The accelerometers are packed with embedded functions with flexible user-programmable options, configurable to interrupt pins. Embedded interrupt functions enable overall power savings, by relieving the host processor from continuously polling data. There is access to either low-pass or high-pass filtered data, which minimizes the data analysis required for jolt detection and faster transitions. The device can be configured to generate inertial wake-up interrupt signals from any combination of the configurable embedded functions, enabling the devices to monitor inertial events while remaining in a low-power mode during periods of inactivity.

Feature comparison

FeatureMMA8451MMA8452MMA8453MMA8652MMA8653
Resolution14-bit12-bit10-bit12-bit10-bit
Sensitivity in 2g mode (counts/g)409610242561024256
32-level FIFOYes--Yes-
Low power modeYesYesYesYesYes
Auto-WAKEYesYesYesYesYes
Auto-SLEEPYesYesYesYesYes
High-pass filterYesYesYesYes-
Low-pass filterYesYesYesYesYes
Transient detection with high-pass filterYesYesYesYes-
Fixed orientation detectionYesYesYes-Yes
Programmable orientation detectionYes--Yes-
Data-ready interruptYesYesYesYesYes
Single-tap interruptYesYesYesYes-
Double-tap interruptYesYesYesYes-
Directional-tap interruptYesYesYesYes-
Freefall interruptYesYesYesYesYes
Motion interrupt with directionYesYesYesYes-
Selectable address pinYesYesYes--

(Unavailable features are marked with “-” as this is more easily readable than Yes/No)

Documentation:

Usage examples (see also examples folder)

To use this driver, import this crate and an embedded_hal implementation, then instantiate the appropriate device.

Most of the settings can only be changed while the device is in standby mode. Then the mode can be changed to active and acceleration measurements read.

Please find additional examples using hardware in this repository: driver-examples

Change mode to active and read acceleration

Using an MMA8653

use linux_embedded_hal::I2cdev;
use mma8x5x::Mma8x5x;

let dev = I2cdev::new("/dev/i2c-1").unwrap();
let sensor = Mma8x5x::new_mma8653(dev);
let mut sensor = sensor.into_active().ok().unwrap();
loop {
    let accel = sensor.read().unwrap();
    println!("Acceleration: {:?}", accel);
}

Change mode to active and read raw unscaled acceleration

use mma8x5x::{Mma8x5x, SlaveAddr};

let sensor = Mma8x5x::new_mma8452(dev, SlaveAddr::default());
let mut sensor = sensor.into_active().ok().unwrap();
loop {
    let accel = sensor.read_unscaled().unwrap();
    println!("Raw acceleration: {:?}", accel);
}

Use alternative address

use mma8x5x::{Mma8x5x, SlaveAddr};
let sensor = Mma8x5x::new_mma8451(dev, SlaveAddr::Alternative(true));

Set scale to +/-8g and 200Hz ODR, then read acceleration

use mma8x5x::{Mma8x5x, GScale, OutputDataRate};

let mut sensor = Mma8x5x::new_mma8652(dev);
sensor.set_scale(GScale::G8).unwrap();
sensor.set_data_rate(OutputDataRate::Hz200).unwrap();
let mut sensor = sensor.into_active().ok().unwrap();
loop {
    let accel = sensor.read().unwrap();
    println!("Acceleration: {:?}", accel);
}

Configure auto-sleep/wake mode

use mma8x5x::{Mma8x5x, AutoSleepDataRate, EnabledInterrupts, PowerMode};

let mut sensor = Mma8x5x::new_mma8652(dev);
sensor.set_auto_sleep_data_rate(AutoSleepDataRate::Hz12_5).unwrap();
sensor.set_auto_sleep_count(125).unwrap();
sensor.set_sleep_power_mode(PowerMode::LowPower).unwrap();
sensor.enable_auto_sleep().unwrap();
// ...
let mut sensor = sensor.into_active().ok().unwrap();

Enable portrait/landscape detection and interrupt generation

use mma8x5x::{Mma8x5x, EnabledInterrupts, InterruptPinPolarity};

let mut sensor = Mma8x5x::new_mma8652(dev);
sensor.set_enabled_interrupts(EnabledInterrupts {
    portrait_landscape: true,
    ..EnabledInterrupts::default() // the rest stays disabled
}).unwrap();
sensor.enable_portrait_landscape_detection().unwrap();
sensor.set_interrupt_pin_polarity(InterruptPinPolarity::ActiveHigh).unwrap();
let mut sensor = sensor.into_active().ok().unwrap();
loop {
    let pl_status = sensor.portrait_landscape_status();
    println!("P/L status: {:?}", pl_status);
    let int_status = sensor.interrupt_status();
    println!("Interrupt status: {:?}", int_status);
}

Enable self-test

let mut sensor = Mma8x5x::new_mma8652(dev);
sensor.enable_self_test().unwrap();
let mut sensor = sensor.into_active().ok().unwrap();
loop {
    let accel = sensor.read().unwrap();
    println!("Acceleration: {:?}", accel);
}

Modules

IC markers

Mode markers

Structs

Current data status

Interrupt source enable/disable

Interrupt source pin route

Current interrupt status

Acceleration measurement scaled to configured G range

MMA8x5x device driver

All possible errors in this crate

Current portrait/landscape status

Unscaled acceleration measurement

Interrupts that wake the device from sleep

Enums

Sampling rate used in auto-sleep/wake mode

Portrait/landscape debounce counter mode

All possible errors in this crate

Front/Back orientation

G scale

Physical interrupt pin configuration

Physical interrupt pin polarity

Interrupt source pin route

Output data rate

Portrait/Landscape orientation

Power mode

Read mode

Possible slave addresses

Current system mode