Skip to content

Chapter 5: QMI8658 IMU (I2C Readout)

5.1 Key Points

  • ESP-IDF v5.x I2C master bus-device API
  • QMI8658 register map and initialization sequence
  • Accelerometer and gyroscope ranges and sensitivities
  • Raw data conversion to physical units

5.2 Course Content

QMI8658 is a six-axis IMU that integrates a three-axis accelerometer and a three-axis gyroscope. It communicates with ESP32-S3 through I2C. OSRCORE configures it for high-rate motion sensing, providing input data for attitude estimation.

5.3 Basic Learning

I2C Master API Structure

ESP-IDF v5.x uses a bus-device model:

  • i2c_new_master_bus() creates an I2C bus handle.
  • i2c_master_bus_add_device() attaches a device to the bus.
  • i2c_master_transmit() and i2c_master_transmit_receive() perform transfers.

Important QMI8658 Registers

RegisterAddressDescription
WHO_AM_I0x00Chip ID, expected 0x05
CTRL10x02SPI/I2C configuration
CTRL20x03Accelerometer range and ODR
CTRL30x04Gyroscope range and ODR
CTRL70x08Enable accelerometer and gyroscope
AX_L0x35Accelerometer X low byte, start of data block

Unit Conversion

text
acceleration_g = raw_int16 / 4096.0     // ±8g, 4096 LSB/g
gyro_dps       = raw_int16 / 16.0       // ±2048 dps, 16 LSB/dps
temperature_c  = raw_int16 / 256.0 + 25.0

5.4 Program Study

Create the I2C bus and add the device:

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));

Read registers by writing the register address and then reading data:

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);
}

Print converted IMU data:

c
qmi8658_data_t d;
if (qmi8658_read(&d)) {
    printf("ax=%.3f ay=%.3f az=%.3f  gx=%.2f gy=%.2f gz=%.2f  T=%.1f\n",
           d.ax, d.ay, d.az, d.gx, d.gy, d.gz, d.temp);
}

5.5 Summary

This chapter explained the ESP-IDF I2C master API and how to initialize and read the QMI8658 IMU. The IMU data is used later by the Madgwick AHRS algorithm.


Built for OSRCORE robot development board.