KXCJ9/KXCJB Tri-Axis MEMS Accelerometer Driver in Rust

KXCJ9 can be found inside an E.ZICLEAN CUBE vacuum cleaner (Copyright Sergey Matyukevich)


Not long ago I discovered an interesting project by Sergey Matyukevich to create a custom firmware for a robot vacuum cleaner in Rust.
While I do not own one of these robots, I saw that he would need a driver for the KXCJ9 accelerometer and offered to write it.
The result is what I present you today. A platform-agnostic rust driver for the KXCJ9 and KXCJB accelerometers.
Quiz question: Can you locate the accelerometer in the image above?

The devices

The KXCJ9 is a high-performance, ultra-low-power, tri-axis accelerometer designed for mobile applications. It offers our best power performance along with an embedded wake-up feature, Fast-mode I²C and up to 14-bit resolution. The KXCJ9 sensor offers improved shock, reflow, and temperature performance, and the ASIC has internal voltage regulators that allow operation from 1.8 V to 3.6 V within the specified product performance.

The KXCJB is the thinnest tri-axis accelerometer available on the market today. This ultra-thin 3x3x0.45mm low-power accelerometer is also one of our most full-featured products. The KXCJB offers up to 14-bit resolution for greater precision. User-selectable parameters include ± 2g, 4g or 8g ranges and Output Data Rates (ODR) with programmable low-pass filter. The KXCJB also features the Kionix XAC sense element, our most advanced sense element, for outstanding stability over temperature, shock and post-reflow performance.

The communication is done through an I2C bidirectional bus.

Using the driver

To use the device from Rust, you have to add the kxcj9 crate to your project as well as a concrete implementation of the embedded-hal traits. For example if you are using the Raspberry Pi running Linux (see driver-examples for bare-metal hardware):

# Cargo.toml
kxcj9 = "0.2"
linux-embedded-hal = "0.3"

This is an example program which will measure the acceleration on the axes and print it (in G) (source):

extern crate kxcj9;
extern crate linux_embedded_hal as hal;
use kxcj9::{Kxcj9, SlaveAddr};

fn main() {
let dev = hal::I2cdev::new("/dev/i2c-1").unwrap();
let address = SlaveAddr::default();
let mut sensor = Kxcj9::new_kxcj9_1018(dev, address);
loop {
let acc = sensor.read().unwrap();
println!("X: {:2}, Y: {:2}, Z: {:2}", acc.x, acc.y, acc.z);

I also created an example program that runs on the STM32F3Discovery board which continuously reads the acceleration and transmits the reading per USART. You can find the application source code here.

In the driver-examples repository you can find further examples which you can adapt to do other things with this device.

Where to go from here?

There is much more information and example programs in the crate documentation.
Please give this driver a try and report any issues you may encounter in the issue tracker.
Feedback, suggestions and improvements are gladly welcome.


Thanks to Kionix engineers for precisely answering my questions and also Sergey Matyukevich for providing the title image.

What’s next?

I have been writing many other platform-agnostic Rust drivers although I am slow to announce them here. If you want to know what I am currently working on you can follow me on github.

Thanks for reading and stay tuned!

Links: Source code - Crate - Documentation

Quiz solution: The accelerometer is the small square chip located down-right from the main MCU (the big chip).