- 物联网
- 嵌入式
- 驱动开发
- 硬件开发
【免费下载链接】esp-iot-solution
Espressif IoT Library. IoT Device Drivers, Documentations and Solutions.
本指南围绕 ESP-IoT-Solution 中气体传感器(Gas Sensor)的适配方案展开,核心讲解已集成的 BOSCH BME690 驱动组件:它是一款集空气质量、温度、湿度、气压检测于一体的环境传感器,支持 I2C 与 SPI 双总线接入,广泛适用于环境监测、工业安全、智能家居等场景。读完本文,你将掌握 BME690 在 ESP-IDF 平台上的组件结构、I2C/SPI 接入方式、核心 API 调用流程、加热器配置与自检方法,并能基于仓库中的测试用例快速搭建自己的气体检测应用。
气体传感器在 ESP-IoT-Solution 中的定位
ESP-IoT-Solution 在components/sensors目录下按传感器类别组织驱动,其中components/sensors/gas即为气体传感器适配目录。根据 docs/zh_CN/sensors/gas.rst 的说明,气体传感器用于检测空气质量、特定气体浓度、温湿度、气压等一种或多种功能,典型应用包括环境监测、工业安全与智能家居。
当前仓库已完成适配的气体传感器列表如下:
| 名称 | 功能 | 总线 | 供应商 | 硬件抽象层 |
|---|---|---|---|---|
| BME690 | 空气质量、温湿度、气压 | I2C/SPI | BOSCH | — |
从表格可见,仓库首先引入的是 BOSCH 的 BME690 环境传感器。其余行(硬件抽象层列)在仓库当前状态下为空,说明该传感器以“BOSCH SensorAPI 原厂驱动 + ESP 平台适配层”的方式直接集成,尚未为其封装额外的统一 HAL 接口,读者在使用时直接调用 BME69X API 即可。
BME690 传感器与驱动组件概述
传感器本身能做什么
BME690 是 Bosch Sensortec 面向移动设备与可穿戴设备设计的集成环境传感器,尺寸紧凑(3.0 x 3.0 x 0.93 mm³、8 引脚 LGA 封装),低功耗、长期稳定性和 EMC 鲁棒性好。其突出特点是首次在同一芯片内集成高线性、高精度的气体、气压、湿度和温度传感器。
根据 components/sensors/gas/bme690/README.md,BME690 内置的气体传感器可检测宽范围气体,用于测量空气质量以保障个人健康,可检测的气体包括涂料、清漆、脱漆剂、清洁用品、家具、办公设备、胶水、粘合剂和酒精中的挥发性有机化合物(VOC),例如甲醛等。其典型应用场景包括:
- 空气质量测量
- 个性化气象站
- 情境感知(如皮肤湿度检测、房间变化检测)
- 健身监测 / 健康管理(如干燥或高温预警)
- 体积与气流测量
- 家居自动化控制(如 HVAC)
- GPS 增强(缩短首次定位时间、航位推算、坡度检测)
- 室内导航(楼层变化检测、电梯检测)
- 运动场景下的海拔追踪与卡路里消耗
驱动组件的来源与适配方式
components/sensors/gas/bme690/组件基于 Bosch Sensortec 官方 BME690_SensorAPI(v1.0.3)移植而来,并针对 ESP 平台对common/目录做了修改。组件文件构成如下:
components/sensors/gas/bme690/ ├── bme69x.c / bme69x.h / bme69x_defs.h # Bosch 原厂 SensorAPI 核心 ├── common/ │ ├── bme690_common.c # ESP 平台接口适配(I2C/SPI) │ └── bme690_common.h ├── test_apps/ # Unity 测试应用与 pytest 脚本 ├── Kconfig # 组件配置项 ├── CMakeLists.txt # 组件构建定义 ├── idf_component.yml └── README.md其中bme69x.h、bme69x_defs.h是 Bosch 原厂 API 与数据类型定义,common/bme690_common.h则提供 ESP 平台所需的接口桥接,详见下文。
构建依赖与组件配置(Kconfig)
组件的 CMakeLists.txt 声明了源码与依赖:
idf_component_register( SRCS "bme69x.c" "common/bme690_common.c" INCLUDE_DIRS "." "common" REQUIRES "esp_driver_i2c" "esp_driver_spi" )也就是说,使用该组件时工程需要具备esp_driver_i2c与esp_driver_spi驱动,且头文件搜索路径包含组件根目录与common子目录,因此应用中直接#include "bme69x.h"与#include "bme690_common.h"即可。
组件通过 Kconfig 暴露两个可调参数:
| 配置项 | 类型 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|
BME690_I2C_TIMEOUT_VALUE_MS | int | 50 | 1–1000 | I2C 通信超时时间(毫秒) |
BME690_AMBIENT_TEMP | int | 25 | 10–50 | 环境温度(摄氏度),用于定义加热器温度 |
其中BME690_AMBIENT_TEMP会被写入传感器设备结构体的amb_temp字段,用于气体加热(heater)温度的校准计算,见 common/bme690_common.c 中bme69x_interface_init()的bme->amb_temp = CONFIG_BME690_AMBIENT_TEMP;。
I2C 与 SPI 双总线接入
设备地址与接口选择
BME690 的 I2C 地址由 SDO 引脚决定(定义于 bme69x_defs.h):
- SDO = 0 → 地址
0x76(BME69X_I2C_ADDR_LOW) - SDO = 1 → 地址
0x77(BME69X_I2C_ADDR_HIGH)
接口选择由bme69x_interface_init()完成,传入BME69X_I2C_INTF或BME69X_SPI_INTF。该函数会做三件事:
- 为
struct bme69x_dev挂接对应的read/write回调(bme69x_i2c_read/write或bme69x_spi_read/write); - 配置
delay_us延时回调(见下文); - 写入环境温度
amb_temp。
I2C 适配层实现要点
在 common/bme690_common.c 中,I2C 通路基于仓库自带的i2c_bus组件实现:
bme69x_set_i2c_bus_handle()注入外部创建好的i2c_bus_handle_t总线句柄;bme69x_interface_init()内部通过i2c_bus_device_create(i2c_bus, dev_addr, 100000)以100 kHz 时钟挂载设备;- 寄存器读写最终调用
i2c_bus_read_bytes()/i2c_bus_write_bytes()完成,失败时返回BME69X_E_COM_FAIL; bme69x_interface_deinit()仅删除设备句柄、清空总线句柄,不会反初始化 I2C 总线本身(总线生命周期由调用方管理)。
SPI 适配层实现要点
SPI 通路基于esp_driver_spi驱动:
bme69x_set_spi_device_handle()注入外部创建好的spi_device_handle_t设备句柄;- 读操作时寄存器地址置位 bit7(
reg_addr | BME69X_SPI_RD_MSK),写操作时清除 bit7(reg_addr & BME69X_SPI_WR_MSK); - 读写通过
spi_device_transmit()以全双工事务完成,内部动态分配事务缓冲; - 适配层对参数做了防御性校验:空指针返回
BME69X_E_NULL_PTR,长度非法返回BME69X_E_INVALID_LENGTH。
延时实现
bme69x_delay_us()对微秒级与毫秒级延时做了区分处理:
- 周期 < 1000 µs:使用
esp_rom_delay_us()忙等,保证微秒精度; - 周期 ≥ 1000 µs:换算后调用
vTaskDelay()让出 CPU(向上取整),避免阻塞 RTOS 调度。
核心 API 与数据采集流程
初始化
bme69x_init()是使用所有其他 API 之前的入口:它会读取芯片 ID 以校验传感器,并完成校准参数加载。对应测试用例见 bme690_test.c 中的"bme690 init-deinit test",其完整流程为:
- 初始化 I2C 总线(
i2c_bus_create); bme69x_set_i2c_bus_handle(i2c_bus)注入总线句柄;bme69x_interface_init(&dev, BME69X_I2C_INTF)选择接口;bme69x_init(&dev)校验并校准;- 结束后
bme69x_interface_deinit()清理。
配置传感器(过采样 / 滤波 / 输出速率)
bme69x_set_conf()用于设置过采样、滤波与输出速率,测试中使用的配置为:
struct bme69x_conf conf; conf.filter = BME69X_FILTER_OFF; // 滤波关闭 conf.odr = BME69X_ODR_NONE; // 非周期输出(仅用于 forced 模式) conf.os_hum = BME69X_OS_16X; // 湿度过采样 16 倍 conf.os_pres = BME69X_OS_1X; // 气压过采样 1 倍 conf.os_temp = BME69X_OS_2X; // 温度过采样 2 倍 rslt = bme69x_set_conf(&conf, &bme690_dev);湿度采用最高 16 倍过采样,说明测试场景对湿度精度要求最高;读者可按功耗与精度权衡调整过采样倍数(BME69X_OS_1X~BME69X_OS_16X)。
配置气体加热器
气体测量依赖内置加热器,bme69x_set_heatr_conf()用于配置加热温度与时长:
struct bme69x_heatr_conf heatr_conf; heatr_conf.enable = BME69X_ENABLE; // 使能加热 heatr_conf.heatr_temp = 300; // 加热温度 300°C heatr_conf.heatr_dur = 100; // 加热时长 100ms rslt = bme69x_set_heatr_conf(BME69X_FORCED_MODE, &heatr_conf, &bme690_dev);工作模式
BME690 支持以下工作模式(见 bme69x_defs.h):
| 宏定义 | 值 | 说明 |
|---|---|---|
BME69X_SLEEP_MODE | 0 | 睡眠模式(默认) |
BME69X_FORCED_MODE | 1 | 强制模式:单次测量后自动回到睡眠 |
BME69X_PARALLEL_MODE | 2 | 并行模式:按 ODR 周期连续测量 |
测试用例"bme690 forced mode test"演示了 forced 模式下的完整采集循环:
bme69x_set_op_mode(BME69X_FORCED_MODE, &dev)触发单次测量;- 用
bme69x_get_meas_dur(BME69X_FORCED_MODE, &conf, &dev) + (heatr_dur * 1000)计算测量总耗时并延时等待; bme69x_get_data(BME69X_FORCED_MODE, &data, &n_fields, &dev)读取并补偿后的数据;- 从
struct bme69x_data中取出temperature、pressure、humidity、gas_resistance与status字段。
测试中每个样本间隔 1 秒(vTaskDelay(pdMS_TO_TICKS(1000))),连续采集 10 组数据并打印。值得注意的是输出代码根据BME69X_USE_FPU宏自动切换浮点与整数打印格式,说明组件兼容无 FPU 的芯片配置。
自检
bme69x_selftest_check()可对低气体型号(low gas variant)的 BME69X 执行自检。测试用例"bme690 self test"与"bme690 spi self test"分别验证了 I2C 与 SPI 通路下的自检流程,返回BME69X_OK即通过。
错误码
bme69x_check_rslt()(声明于 common/bme690_common.h)可将 API 返回码映射为可读日志,涵盖:
BME69X_OK:成功BME69X_E_NULL_PTR:空指针BME69X_E_COM_FAIL:通信失败BME69X_E_INVALID_LENGTH:长度参数错误BME69X_E_DEV_NOT_FOUND:未找到设备BME69X_E_SELF_TEST:自检失败BME69X_W_NO_NEW_DATA:暂无新数据(警告)
测试与验证
组件自带完整的 Unity 测试应用,位于 test_apps/main/bme690_test.c,共 6 个用例,覆盖 I2C 与 SPI 两条通路:
| 测试用例 | 接口 | 验证内容 |
|---|---|---|
| bme690 init-deinit test | I2C | 初始化与反初始化 |
| bme690 forced mode test | I2C | 配置 + 加热器 + 10 次连续测量 |
| bme690 self test | I2C | 传感器自检 |
| bme690 spi init-deinit test | SPI | SPI 初始化与反初始化 |
| bme690 spi forced mode test | SPI | SPI 通路连续测量 |
| bme690 spi self test | SPI | SPI 通路自检 |
测试中还包含内存泄漏检测:setUp/tearDown记录并比对MALLOC_CAP_8BIT与MALLOC_CAP_32BIT堆余量,阈值设为 -500 字节。测试硬件基于ESP-SensairShuttle板,默认引脚分配为:
- I2C:SCL=GPIO3,SDA=GPIO2,频率 100 kHz;SDO=GPIO9(置 0 以选用地址 0x76);
- SPI:CS=GPIO10,MISO=GPIO9,MOSI=GPIO2,CLK=GPIO3,SPI2_HOST,模式 0,时钟 1 MHz。
对应的自动化测试脚本为 pytest_bme690.py,可用于 CI 环境。
在你的工程中接入 BME690
在 ESP-IDF 工程中接入该组件的典型步骤(以 I2C 为例):
- 将
components/sensors/gas/bme690作为依赖组件加入工程(例如通过idf_component.yml声明,或放入工程的components目录); - 在应用代码中包含
bme69x.h与bme690_common.h; - 初始化 I2C 总线(可用仓库的
i2c_bus组件,参考 components/i2c_bus/README.md),并调用bme69x_set_i2c_bus_handle()注入句柄; - 依次调用
bme69x_interface_init()→bme69x_init()→bme69x_set_conf()→bme69x_set_heatr_conf(); - 需要采样时进入 forced 模式、按测量时长等待、读取
bme69x_get_data()结果; - 通过
menuconfig按需调整BME690_I2C_TIMEOUT_VALUE_MS与BME690_AMBIENT_TEMP。
对于 SPI 接入,则先初始化 SPI 总线并spi_bus_add_device(),随后调用bme69x_set_spi_device_handle(),再走相同初始化流程,完整可参考测试用例中的 SPI 分支。
小结
ESP-IoT-Solution 的components/sensors/gas目录以 BME690 作为气体传感器的首个适配对象,采用“Bosch 原厂 SensorAPI 核心 + ESP 平台适配层”的架构,兼顾了 API 权威性与 ESP-IDF 生态的易用性。适配层封装了 I2C/SPI 双总线读写、RTOS 友好的延时、句柄注入与去初始化等细节,配合Kconfig可调参数、6 个覆盖双总线的 Unity 测试用例以及自动化的 pytest 脚本,开发者可以快速、可靠地把空气质量 + 温湿度 + 气压监测能力集成到自己的智能家居、环境监测或工业安全应用中。
- 物联网
- 嵌入式
- 驱动开发
- 硬件开发
【免费下载链接】esp-iot-solution
Espressif IoT Library. IoT Device Drivers, Documentations and Solutions.
相关推荐
ESP IoT Solution 气体传感器指南:基于 BME690 的多合一环境检测实践
ESP IoT Solution 气体传感器指南:基于 BME690 的多合一环境检测实践 导读 本文以 esp iot solution 仓库中 gas.rs
物联网嵌入式驱动开发硬件开发ESP IoT Solution 中的 BME690 环境传感器驱动:Bosch BME69X SensorAPI 的 ESP32 移植实践
ESP IoT Solution 中的 BME690 环境传感器驱动:Bosch BME69X SensorAPI 的 ESP32 移植实践 本文基于 esp
物联网嵌入式驱动开发硬件开发esp-iot-solution 中 AHT20 温湿度传感器 I2C 驱动组件使用指南
esp iot solution 中 AHT20 温湿度传感器 I2C 驱动组件使用指南 导读 本文围绕 esp iot solution 仓库中的 AHT20
物联网嵌入式驱动开发硬件开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考