espressif/bmi270_sensor

0.4.0

Latest
uploaded 8 hours ago
Official Espressif BMI270 driver for ESP32: Base wrist gestures, custom Circle/Toy motion, 6-axis IMU, native I2C and AUX.

Readme (zh)

# ESP-IDF BMI270 传感器组件

乐鑫官方 BMI270 组件,面向 ESP32 应用提供:**六轴运动检测、Bosch Base 腕部手势、定制 Circle/Toy 手势固件、原生 I2C 接入和 AUX 外接传感器扩展**。公开 C 接口和十一个完整示例覆盖画圈、敲击、抛接、推动、摇晃、滚动和旋转识别。

[English](README.md)

## v0.4.0 新变更

- 新增 `bmi270_sensor_create_from_master_bus_with_address()`,支持选择 0x68/0x69。

## v0.3.0

- 新增 `aux_bmm150` 和 `raw_data` 示例。
- 新增 `bmi270_sensor_create_from_master_bus()`,保留原有创建接口。
- 按实例释放 I2C 设备,总线仍由调用方持有。
- 修复 AUX 手动传输和 `bmi2_delay_us`。
- 删除未实现的 `bmi270_toy_*` 声明。

## 定制固件与二进制组件交付

**随组件提供的 Bosch Base 固件支持常见手表和可穿戴功能**,包括腕部手势、抬腕唤醒、计步和步态活动识别。需要这些功能时选择 Base,需要下列定制能力时选择 Circle 或 Toy。

**Circle 和 Toy 是乐鑫与 Bosch Sensortec 面向 ESP32 应用联合开发的 BMI270 固件变体。**它们不包含在 [Bosch 公开 BMI270 SensorAPI 仓库](https://github.com/boschsensortec/BMI270_SensorAPI)中。

这些变体连同 ESP-IDF 集成一起以预编译静态库(`.a`)交付,按支持的 ESP-IDF 版本和目标芯片各提供一份。应用链接匹配的静态库,传感器初始化时驱动把所选固件镜像加载到 BMI270。库实现为二进制形式,**公开头文件、配置类型、C 接口和示例源码均可阅读和使用。**请从 [bmi270_api.h](include/bmi270_api.h) 和[下方示例](#示例)开始。

## 选择固件变体

一颗 BMI270 同一时间运行一种固件变体,三套功能集不会合并。向任一创建接口传入该变体的配置符号,再使用匹配的功能接口。

| 变体 | 创建时传入的配置 | 主要能力 | 功能接口系列 |
| --- | --- | --- | --- |
| **Base(Bosch 标准固件)** | `bmi270_config_file` 或 `NULL` | 加速度计/陀螺仪、any/no/significant motion、步态检测与计步、步态活动识别、腕部手势和抬腕唤醒 | `bmi270_*` |
| **Circle** | `bmi270_circle_config_file` | 顺时针/逆时针画圈、可选旋转轴、单击/双击/三击、any/no motion | `bmi270_circle_*` |
| **Toy** | `bmi270_toy_config_file` | 拿起/放下、上抛/下落/接住、推动、摇晃、滚动、旋转角度;any/no motion、high/low-g 和敲击控制 | `bmi270_enable_toy_*`、`bmi270_get_toy_*` 及通用 `bmi2_*` 调用 |

Base 解析五种腕部手势:**`push_arm_down`、`pivot_up`、`wrist_shake_jiggle`、`flick_in` 和 `flick_out`**。[腕部手势测试](test_apps/main/bmi270_test.c)展示了功能配置、中断映射和结果读取。

Toy 功能通过 `bmi270_enable_toy_*` 和 `bmi270_get_toy_*` 辅助函数使用,其中 `bmi270_enable_toy_tap()` 提供单击/双击/三击使能控制,功能中断映射用 `bmi2_set_regs()` 和 `bmi2_set_int_pin_config()`。完整流程见 [toy_motion_main.c](examples/toy_motion/main/toy_motion_main.c)。

`variant_feature` 参数:Base 和 Circle 传入 `BMI2_GYRO_CROSS_SENS_ENABLE | BMI2_CRT_RTOSK_ENABLE`,Toy 传入 `0`,与随附示例一致。

三种变体都提供通用六轴数据和 AUX 接口:用 `bmi2_get_sensor_config()` / `bmi2_set_sensor_config()` 配置测量参数,用 `bmi2_sensor_enable()` 启用加速度计/陀螺仪,用 `bmi2_get_sensor_data()` 读取数据。

## 快速开始

### 组件与硬件要求

- **ESP-IDF 5.3 或更新版本**,且对应 IDF 主次版本和目标芯片有可用的预编译库。组件会自动选择匹配的静态库;ESP32-P4 还区分芯片版本。具体支持组合以发布包为准。
- BMI270 通过 I2C 连接,供电和 SDA/SCL 上拉合适。默认创建接口使用地址 **`0x68`**;原生 master 调用方可通过指定地址的创建接口选择 **`0x69`**。
- 按所选中断驱动示例的要求连接 INT1/INT2。
- 保持 `CONFIG_I2C_BUS_BACKWARD_CONFIG` 关闭。受支持的硬件后端是 ESP-IDF 当前的 I2C master 驱动。

在应用的 `idf_component.yml` 中添加依赖:

```yaml
dependencies:
  espressif/bmi270_sensor: "^0.4.0"
```

### 选择总线入口

| 应用已有的句柄 | 创建接口 | 设备传输速率 |
| --- | --- | --- |
| `i2c_bus_handle_t` | `bmi270_sensor_create()` | 沿用调用方的总线速率 |
| `i2c_master_bus_handle_t`,包括 Board Manager 创建的总线 | `bmi270_sensor_create_from_master_bus()` | 400 kHz,200 ms 传输超时 |

两个入口返回同一种 `bmi270_handle_t`,用于传感器和 AUX 操作。两种总线句柄类型不同,请分别传给对应的创建接口。
原生接口默认使用 0x68;SDO 选择 0x69 时,使用 `bmi270_sensor_create_from_master_bus_with_address()`。

### 读取一次六轴数据

用板卡引脚通过 `i2c_new_master_bus()` 创建原生总线,或从 Board Manager 获取。把该调用方持有的总线传给下面的函数。它选择 Base 固件,以默认测量配置启用加速度计和陀螺仪,等待新数据,打印有符号原始值,并只删除自己创建的传感器设备。

```c
#include "bmi270_api.h"
#include "esp_log.h"

void read_motion_once(i2c_master_bus_handle_t master_bus)
{
    bmi270_handle_t sensor = NULL;
    ESP_ERROR_CHECK(bmi270_sensor_create_from_master_bus(
        master_bus, &sensor, bmi270_config_file,
        BMI2_GYRO_CROSS_SENS_ENABLE | BMI2_CRT_RTOSK_ENABLE));

    const uint8_t sensors[] = {BMI2_ACCEL, BMI2_GYRO};
    int8_t result = bmi2_sensor_enable(sensors, 2, sensor);
    bool received = false;
    for (unsigned attempt = 0; attempt < 100 && result == BMI2_OK; attempt++) {
        bmi2_delay_us(10000, NULL);
        struct bmi2_sens_data data = {0};
        result = bmi2_get_sensor_data(&data, sensor);
        if (result == BMI2_OK && (data.status & BMI2_DRDY_ACC) &&
                (data.status & BMI2_DRDY_GYR)) {
            ESP_LOGI("motion", "acc=(%d,%d,%d) gyro=(%d,%d,%d)",
                     data.acc.x, data.acc.y, data.acc.z,
                     data.gyr.x, data.gyr.y, data.gyr.z);
            received = true;
            break;
        }
    }
    bmi2_error_codes_print_result(result);
    if (!received) {
        ESP_LOGW("motion", "No fresh six-axis sample received");
    }
    ESP_ERROR_CHECK(bmi270_sensor_del(&sensor));
}
```

已有 `i2c_bus_handle_t` 时,用 `bmi270_sensor_create()` 传入相同的固件和功能参数。先配置采样率和量程再启用测量,然后按配置的量程换算原始值。[raw_data](examples/raw_data/README.md) 是可直接构建的完整工程,涵盖 ODR/量程配置、物理量换算和 CSV 输出。

## 示例

每个示例都是完整工程,包含应用源码和板卡引脚配置说明。

| 应用场景 | 固件 | 完整示例 |
| --- | --- | --- |
| 读取六轴原始数据和物理量 | Base | [raw_data](examples/raw_data/README.md) |
| 通过 AUX 控制 BMM150 寄存器并读取原始磁数据 | Base(可选 Circle/Toy) | [aux_bmm150](examples/aux_bmm150/README.md) |
| 识别顺时针/逆时针画圈 | Circle | [circle_gesture](examples/circle_gesture/README.md) |
| 检测单击、双击和三击 | Circle | [multi_tap](examples/multi_tap/README.md) |
| 体验组合的玩具运动事件 | Toy | [toy_motion](examples/toy_motion/README.md) |
| 用中断检测运动 | Toy | [any_motion](examples/any_motion/README.md) |
| 检测手持状态下的推动 | Toy | [push_in_air](examples/push_in_air/README.md) |
| 检测桌面上的推动 | Toy | [push_on_table](examples/push_on_table/README.md) |
| 检测摇晃 | Toy | [shake](examples/shake/README.md) |
| 检测滚动 | Toy | [rolling](examples/rolling/README.md) |
| 读取旋转角度 | Toy | [rotation](examples/rotation/README.md) |

## 通过 AUX 扩展外接传感器

BMI270 的 AUX 接口可经 BMI270 连接外部传感器,例如 BMM150 磁力计:

```text
ESP32 -- I2C --> BMI270 -- AUX I2C --> 外部传感器
```

Base、Circle、Toy 三种固件以及两个总线入口,都可以通过同一句柄完成 AUX 配置和手动寄存器访问。

| 接口 | 用途 |
| --- | --- |
| `bmi270_aux_set_config()` | 配置 AUX 地址、手动模式、输出数据率和 burst 设置 |
| `bmi270_aux_get_config()` | 读回 AUX 配置 |
| `bmi270_aux_read()` | 在 AUX 手动模式下读取外部传感器寄存器 |
| `bmi270_aux_write()` | 在 AUX 手动模式下写入外部传感器寄存器 |
| `bmi270_get_dev()` | 获取 `struct bmi2_dev *`,供使用 Bosch BMI2 接口的适配器使用 |

先用 `bmi270_aux_config_t` 配置 AUX 手动模式,再调用寄存器读写辅助函数,之后通过该传输通道用外部传感器自己的驱动完成初始化和操作。公开的 [AUX 接口声明](include/bmi270_api.h)说明了参数,并给出 BMM150 配置参考。

[aux_bmm150 示例](examples/aux_bmm150/README.md)在 AtomS3R 上演示四个公开 AUX 接口,输出为原始计数。外部传感器的初始化、补偿、校准,以及任何姿态或传感器融合算法,属于外部驱动或应用的职责。

## 接口与资源生命周期

公开头文件是集成参考:

- [bmi270_api.h](include/bmi270_api.h):创建/删除、固件符号、手势配置、Toy 辅助函数和 AUX 接口。
- [bmi2.h](include/bmi2.h):通用测量、寄存器、FIFO、中断和传感器控制接口。
- [bmi2_defs.h](include/bmi2_defs.h):数据结构、配置常量和 Bosch 返回码。

**返回码:**创建和删除返回 `esp_err_t`,成功为 `ESP_OK`。Bosch 传感器、手势和 AUX 调用返回 `int8_t`,成功为 `BMI2_OK`,错误为负值,部分调用会返回正值警告。用 `bmi2_error_codes_print_result()` 诊断结果,并按所调用接口的定义处理警告。`bmi270_get_dev()` 返回设备指针。

**所有权:**总线由调用方持有。`bmi270_sensor_del()` 移除该实例的设备、释放句柄,成功后把句柄置为 NULL。删除总线前先删除所有传感器实例。原生传输为同步调用,未注册异步回调;每个实例的操作需与删除串行执行。

**错误恢复:**上面的简短示例用 `ESP_ERROR_CHECK()` 对 ESP-IDF 错误做快速失败处理。需要错误恢复的应用还应检查返回的句柄:创建失败通常返回 NULL 句柄,但初始化和设备移除都失败时,返回的非 NULL 句柄**仅用于重试 `bmi270_sensor_del()`**。删除失败同样保留句柄。等共享总线上的其他传输结束后再重试清理;只有创建成功后才能进行传感器操作。

## 延伸阅读

- [更新日志](CHANGELOG.md)
- [Bosch BMI270 产品信息](https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi270.html)
- [Bosch 公开 BMI270 SensorAPI](https://github.com/boschsensortec/BMI270_SensorAPI)

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "espressif/bmi270_sensor^0.4.0"

download archive

Stats

  • Archive size
    Archive size ~ 37.39 MB
  • Downloaded in total
    Downloaded in total 592.9k times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 0 times

Badge

espressif/bmi270_sensor version: 0.4.0
|