Skip to content

第 5 章:QMI8658 IMU(I2C 读取)

📂 示例代码05_imu_i2c

5.1 知识要点

  • ESP-IDF I2C Master 新 API(v5.x)的总线与设备配置
  • QMI8658 寄存器映射与初始化序列
  • 加速度计(±4g)和陀螺仪(±1024 dps)的量程与灵敏度
  • 5 样本硬件平均、静止检测与陀螺仪偏置校准
  • 原始数据到物理量的换算公式

5.2 课程内容

QMI8658 是一款六轴惯性测量单元(IMU),集成三轴加速度计和三轴陀螺仪,通过 I2C 接口与 ESP32-S3 通信。OSRCORE 将其配置为 1000 Hz 输出速率,为姿态解算提供高频传感器数据。

5.3 基础学习

I2C Master 新 API 架构

ESP-IDF v5.x 引入了新的 I2C Master API,采用总线-设备两级结构:

  • i2c_new_master_bus():创建总线句柄,配置 SDA/SCL 引脚和时钟
  • i2c_master_bus_add_device():在总线上添加设备,配置地址和速率
  • i2c_master_transmit() / i2c_master_transmit_receive():执行传输

QMI8658 关键寄存器

寄存器地址说明
WHO_AM_I0x00芯片 ID(应为 0x05)
CTRL10x02SPI/I2C 配置
CTRL20x03加速度计量程/ODR(0x13 = ±4g,1000 Hz)
CTRL30x04陀螺仪量程/ODR(0x63 = ±1024 dps,1000 Hz)
CTRL70x08使能加速度计+陀螺仪
AX_L0x35加速度 X 低字节(共 12 字节)

数据换算

加速度(g)= raw_int16 / 8192.0   (±4g 量程,ACCEL_SCALE = 32768/4 = 8192 LSB/g)
角速度(dps)= raw_int16 / 32.0   (±1024 dps 量程,GYRO_SCALE = 32768/1024 = 32 LSB/dps)
温度(°C)= raw_int16 / 256.0 + 25.0

5 样本平均与偏置校准

驱动内部对每 5 次原始读取做算术平均后才输出一次 qmi8658_data_t,有效降低高频噪声。

陀螺仪偏置分两阶段校准:

  1. 启动校准:上电后采集 100 个静止样本,计算均值作为初始偏置。
  2. 在线批量校准:运行中持续检测静止状态(加速度 Z 轴方差 + 陀螺仪 Z 轴均值),静止超过阈值后累积 1000 个样本更新偏置,防止温漂。

水平偏移(level offset)通过 qmi8658_set_level_offset(ox, oy, oz) 设置,从加速度计输出中减去安装误差。

5.4 程序学习

I2C 总线与设备初始化:

c
i2c_master_bus_config_t bus_cfg = {
    .i2c_port      = I2C_NUM_0,
    .sda_io_num    = 10,
    .scl_io_num    = 11,
    .clk_source    = I2C_CLK_SRC_DEFAULT,
    .glitch_ignore_cnt = 7,
    .flags.enable_internal_pullup = true,
};
i2c_master_bus_handle_t bus;
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_cfg, &bus));

i2c_device_config_t dev_cfg = {
    .dev_addr_length = I2C_ADDR_BIT_LEN_7,
    .device_address  = 0x6B,
    .scl_speed_hz    = 400000,
};
i2c_master_dev_handle_t dev;
ESP_ERROR_CHECK(i2c_master_bus_add_device(bus, &dev_cfg, &dev));

读取寄存器(写地址后读数据):

c
static esp_err_t qmi_read(i2c_master_dev_handle_t dev,
                           uint8_t reg, uint8_t *buf, size_t len)
{
    return i2c_master_transmit_receive(dev, &reg, 1, buf, len, 100);
}

读取并换算 IMU 数据:

c
/* 初始化时写入量程寄存器 */
write_reg(QMI_REG_CTRL2, 0x13);  // ±4g,1000 Hz ODR
write_reg(QMI_REG_CTRL3, 0x63);  // ±1024 dps,1000 Hz ODR
write_reg(QMI_REG_CTRL7, 0x03);  // 使能加速度计 + 陀螺仪

/* 启动后执行一次静止校准(需保持静止约 100ms) */
qmi8658_calibrate_bias();

/* 读取数据(内部 5 样本平均,每 5 次调用才返回 true) */
qmi8658_data_t d;
if (qmi8658_read(&d)) {
    // d.accelX/Y/Z 单位 g,d.gyroX/Y/Z 单位 dps(已减去偏置)
    printf("ax=%.3f ay=%.3f az=%.3f  gx=%.2f gy=%.2f gz=%.2f  T=%.1f\n",
           d.accelX, d.accelY, d.accelZ,
           d.gyroX,  d.gyroY,  d.gyroZ, d.temp);
}

5.5 课程总结

本章掌握了 ESP-IDF I2C Master 新 API 的使用方式,学会了 QMI8658 的初始化(±4g / ±1024 dps 量程,CTRL2=0x13,CTRL3=0x63)和数据读取。5 样本平均降低了噪声,两阶段陀螺仪偏置校准(启动 100 样本 + 在线批量 1000 样本)保证了长时间运行的精度。IMU 数据是姿态解算的原始输入,第 10 章将在此基础上实现 Madgwick AHRS 算法。


Built for OSRCORE robot development board.