IMU Sensor Example Guide
中文 | English
Introduction
This example demonstrates how to use the LSM6DS3TR-C 6-axis IMU sensor on Titan Board Mini to implement inertial measurement functionality. It reads 3-axis accelerometer and 3-axis gyroscope data via the I2C interface, combined with the RT-Thread Sensor Framework for complete sensor data acquisition and processing.
Key features include:
6-axis inertial measurement using LSM6DS3TR-C
Read 3-axis accelerometer data (X/Y/Z)
Read 3-axis gyroscope data (X/Y/Z)
Support for multiple range and sampling rate configurations
Integrated with RT-Thread Sensor Framework
Hardware Overview
1. LSM6DS3TR-C IMU Sensor
Titan Board Mini features the onboard LSM6DS3TR-C high-performance 6-axis IMU sensor:
Parameter |
Description |
|---|---|
Model |
LSM6DS3TR-C |
Manufacturer |
STMicroelectronics |
Type |
6-axis IMU (3-axis accelerometer + 3-axis gyroscope) |
Interface |
I2C / SPI |
Operating Voltage |
1.71V - 3.6V |
Temperature Range |
-40°C ~ +85°C |
Package |
2.5mm x 3mm x 0.83mm LGA-14 |
2. Accelerometer Features
The LSM6DS3TR-C integrates a high-performance 3-axis accelerometer:
Range Selection: ±2g / ±4g / ±8g / ±16g
Resolution: 16-bit ADC
Output Data Rate: 1.6Hz - 6.66kHz
Noise Density: 90μg/√Hz
Zero-g Offset: ±40mg
Bandwidth: Configurable (typically 50Hz - 1.6kHz)
3. Gyroscope Features
The LSM6DS3TR-C integrates a high-precision 3-axis gyroscope:
Range Selection: ±125 / ±250 / ±500 / ±1000 / ±2000 dps
Resolution: 16-bit ADC
Output Data Rate: 1.6Hz - 6.66kHz
Noise Density: 3.8mdps/√Hz
Bias Stability: ±5dps
Bandwidth: Configurable
4. Main Features
Advanced Features
FIFO Buffer: 9KB FIFO with multiple modes
Interrupt Functions: Motion wake-up, free fall, 6D orientation detection
Sensor Fusion: Built-in low-power sensor fusion algorithms
Self-Test: Supports self-test mode
Low Power Mode: Multiple low-power operating modes
Data Processing
Hardware Filtering: Configurable digital filters
Data Fusion: Supports accelerometer + gyroscope data fusion
Time Stamp: Built-in timestamp function
Polling/Interrupt: Supports polling and interrupt data reading
Software Architecture
1. Layered Design
The IMU sensor system uses a layered architecture:
Application Layer (User Code)
↓
RT-Thread Sensor Framework - Sensor Framework
↓
LSM6DS3TR-C Driver - IMU Driver
↓
Sensor HAL - Sensor Hardware Abstraction Layer
↓
I2C/SPI Driver - I2C/SPI Driver
↓
FSP I2C/SPI HAL - Hardware Abstraction Layer
2. Core Components
Porting Layer Interface
Platform-specific interfaces to implement (lsm6ds3tr-c_port.c):
/* I2C read/write interfaces */
int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len);
int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len);
/* Delay interface */
void platform_delay(uint32_t ms);
RT-Thread Sensor Framework
Unified sensor device interface provided by RT-Thread:
/* Find sensor device */
rt_device_t rt_device_find(const char *name);
/* Open sensor device */
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);
/* Read sensor data */
rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
/* Receive sensor data */
rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size));
3. Project Structure
Titan_Mini_peripheral_imu/
├── src/
│ └── hal_entry.c # Main program entry
└── packages/
└── lsm6ds3tr/ # LSM6DS3TR-C driver package
├── lsm6ds3tr-c_reg.h # Register definitions and driver interfaces
├── lsm6ds3tr-c_reg.c # Register-level driver implementation
└── lsm6ds3tr-c_port.c # Platform porting layer
Usage Guide
1. Initialization Flow
The system requires initialization of the I2C interface and IMU sensor during startup:
#include <rtthread.h>
#include "lsm6ds3tr-c_reg.h"
/* I2C configuration */
#define LSM6DS3TR_C_I2C_BUS "i2c2"
#define LSM6DS3TR_C_I2C_ADDR 0x6A /* SA0 pin connected to GND */
void hal_entry(void)
{
stmdev_ctx_t imu_ctx = {0};
/* Initialize I2C interface */
struct rt_i2c_bus_device *i2c_bus = rt_i2c_bus_device_find(LSM6DS3TR_C_I2C_BUS);
if (i2c_bus == RT_NULL)
{
rt_kprintf("I2C bus not found!\n");
return;
}
/* Configure device read/write interfaces */
imu_ctx.handle = i2c_bus;
imu_ctx.write_reg = platform_write;
imu_ctx.read_reg = platform_read;
/* Initialize sensor */
if (lsm6ds3tr_c_init(&imu_ctx) != LSM6DS3TR_C_OK)
{
rt_kprintf("LSM6DS3TR-C initialization failed!\n");
return;
}
/* Configure accelerometer */
lsm6ds3tr_c_xl_full_scale_set(&imu_ctx, LSM6DS3TR_C_2g); /* ±2g */
lsm6ds3tr_c_xl_data_rate_set(&imu_ctx, LSM6DS3TR_C_ODR_104Hz); /* 104Hz */
/* Configure gyroscope */
lsm6ds3tr_c_gy_full_scale_set(&imu_ctx, LSM6DS3TR_C_250dps); /* ±250dps */
lsm6ds3tr_c_gy_data_rate_set(&imu_ctx, LSM6DS3TR_C_ODR_104Hz); /* 104Hz */
rt_kprintf("LSM6DS3TR-C initialized successfully!\n");
/* Main loop - read sensor data */
while (1)
{
/* Read accelerometer data */
lsm6ds3tr_c_axis3bit16_t acc_raw;
lsm6ds3tr_c_acceleration_raw_get(&imu_ctx, &acc_raw);
/* Read gyroscope data */
lsm6ds3tr_c_axis3bit16_t gyro_raw;
lsm6ds3tr_c_angular_rate_raw_get(&imu_ctx, &gyro_raw);
/* Convert data to physical units */
float acc_x = acc_raw.i16bit[0] / 32768.0f * 2.0f; /* 2g range */
float acc_y = acc_raw.i16bit[1] / 32768.0f * 2.0f;
float acc_z = acc_raw.i16bit[2] / 32768.0f * 2.0f;
float gyro_x = gyro_raw.i16bit[0] / 32768.0f * 250.0f; /* 250dps range */
float gyro_y = gyro_raw.i16bit[1] / 32768.0f * 250.0f;
float gyro_z = gyro_raw.i16bit[2] / 32768.0f * 250.0f;
/* Print data */
rt_kprintf("ACC: X=%.3fg Y=%.3fg Z=%.3fg | GYRO: X=%.2fdps Y=%.2fdps Z=%.2fdps\n",
acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z);
rt_thread_mdelay(100); /* 10Hz read rate */
}
}
2. I2C Platform Interface Implementation
The porting layer needs to implement I2C read/write functions:
#include <rtthread.h>
#include <rtdevice.h>
/* I2C write */
int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len)
{
struct rt_i2c_bus_device *i2c_bus = (struct rt_i2c_bus_device *)handle;
struct rt_i2c_msg msgs[2];
/* Write register address */
msgs[0].addr = LSM6DS3TR_C_I2C_ADDR;
msgs[0].flags = RT_I2C_WR;
msgs[0].buf = ®
msgs[0].len = 1;
/* Write data */
msgs[1].addr = LSM6DS3TR_C_I2C_ADDR;
msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
msgs[1].buf = (uint8_t *)bufp;
msgs[1].len = len;
if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2)
{
return -1;
}
return 0;
}
/* I2C read */
int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
struct rt_i2c_bus_device *i2c_bus = (struct rt_i2c_bus_device *)handle;
struct rt_i2c_msg msgs[2];
/* Write register address */
msgs[0].addr = LSM6DS3TR_C_I2C_ADDR;
msgs[0].flags = RT_I2C_WR;
msgs[0].buf = ®
msgs[0].len = 1;
/* Read data */
msgs[1].addr = LSM6DS3TR_C_I2C_ADDR;
msgs[1].flags = RT_I2C_RD;
msgs[1].buf = bufp;
msgs[1].len = len;
if (rt_i2c_transfer(i2c_bus, msgs, 2) != 2)
{
return -1;
}
return 0;
}
/* Delay function */
void platform_delay(uint32_t ms)
{
rt_thread_mdelay(ms);
}
3. Data Format Conversion
Raw sensor data needs to be converted to physical units:
/* Accelerometer data conversion (assuming 2g range) */
int16_t acc_raw_x = 16384; /* Raw ADC value */
float acc_x_g = (float)acc_raw_x / 32768.0f * 2.0f; /* Convert to g (9.8m/s²) */
float acc_x_m_s2 = acc_x_g * 9.80665f; /* Convert to m/s² */
/* Gyroscope data conversion (assuming 250dps range) */
int16_t gyro_raw_x = 1000; /* Raw ADC value */
float gyro_x_dps = (float)gyro_raw_x / 32768.0f * 250.0f; /* Convert to °/s */
float gyro_x_rad_s = gyro_x_dps * 0.017453292519943295f; /* Convert to rad/s */
Configuration Guide
1. Kconfig Configuration
Configure IMU options in libraries/M85_Config/Kconfig:
menuconfig BSP_USING_IMU
bool "Enable IMU (LSM6DS3TR-C)"
select BSP_USING_I2C2
default n
if BSP_USING_IMU
config BSP_IMU_I2C_BUS
string "I2C bus name"
default "i2c2"
config BSP_IMU_ACC_ODR
int "Accelerometer ODR (Hz)"
default 104
config BSP_IMU_GYRO_ODR
int "Gyroscope ODR (Hz)"
default 104
endif
2. RT-Thread Settings
In RT-Thread Studio, the following components need to be enabled:
Device Drivers
Enable I2C device driver
Configure I2C2 interface
Sensors
Enable RT-Thread Sensor Framework
Enable Accel (accelerometer) sensor
Enable Gyro (gyroscope) sensor
Software Packages
Add LSM6DS3TR-C driver package
Running Results
1. Terminal Output
After resetting Titan Board Mini, the terminal will output the following information:
