ESP-IoT-Solution 气体传感器方案:BME690 驱动组件全解析
2026/9/20 13:13:51 网站建设 项目流程
  • 物联网
  • 嵌入式
  • 驱动开发
  • 硬件开发

【免费下载链接】esp-iot-solution

Espressif IoT Library. IoT Device Drivers, Documentations and Solutions.

项目地址:https://gitcode.com/GitHub_Trending/es/esp-iot-solution
点击查看免费下载

本指南围绕 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/SPIBOSCH

从表格可见,仓库首先引入的是 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.hbme69x_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_i2cesp_driver_spi驱动,且头文件搜索路径包含组件根目录与common子目录,因此应用中直接#include "bme69x.h"#include "bme690_common.h"即可。

组件通过 Kconfig 暴露两个可调参数:

配置项类型默认值取值范围说明
BME690_I2C_TIMEOUT_VALUE_MSint501–1000I2C 通信超时时间(毫秒)
BME690_AMBIENT_TEMPint2510–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 → 地址0x76BME69X_I2C_ADDR_LOW
  • SDO = 1 → 地址0x77BME69X_I2C_ADDR_HIGH

接口选择由bme69x_interface_init()完成,传入BME69X_I2C_INTFBME69X_SPI_INTF。该函数会做三件事:

  1. struct bme69x_dev挂接对应的read/write回调(bme69x_i2c_read/writebme69x_spi_read/write);
  2. 配置delay_us延时回调(见下文);
  3. 写入环境温度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",其完整流程为:

  1. 初始化 I2C 总线(i2c_bus_create);
  2. bme69x_set_i2c_bus_handle(i2c_bus)注入总线句柄;
  3. bme69x_interface_init(&dev, BME69X_I2C_INTF)选择接口;
  4. bme69x_init(&dev)校验并校准;
  5. 结束后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_MODE0睡眠模式(默认)
BME69X_FORCED_MODE1强制模式:单次测量后自动回到睡眠
BME69X_PARALLEL_MODE2并行模式:按 ODR 周期连续测量

测试用例"bme690 forced mode test"演示了 forced 模式下的完整采集循环:

  1. bme69x_set_op_mode(BME69X_FORCED_MODE, &dev)触发单次测量;
  2. bme69x_get_meas_dur(BME69X_FORCED_MODE, &conf, &dev) + (heatr_dur * 1000)计算测量总耗时并延时等待;
  3. bme69x_get_data(BME69X_FORCED_MODE, &data, &n_fields, &dev)读取并补偿后的数据;
  4. struct bme69x_data中取出temperaturepressurehumiditygas_resistancestatus字段。

测试中每个样本间隔 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 testI2C初始化与反初始化
bme690 forced mode testI2C配置 + 加热器 + 10 次连续测量
bme690 self testI2C传感器自检
bme690 spi init-deinit testSPISPI 初始化与反初始化
bme690 spi forced mode testSPISPI 通路连续测量
bme690 spi self testSPISPI 通路自检

测试中还包含内存泄漏检测:setUp/tearDown记录并比对MALLOC_CAP_8BITMALLOC_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 为例):

  1. components/sensors/gas/bme690作为依赖组件加入工程(例如通过idf_component.yml声明,或放入工程的components目录);
  2. 在应用代码中包含bme69x.hbme690_common.h
  3. 初始化 I2C 总线(可用仓库的i2c_bus组件,参考 components/i2c_bus/README.md),并调用bme69x_set_i2c_bus_handle()注入句柄;
  4. 依次调用bme69x_interface_init()bme69x_init()bme69x_set_conf()bme69x_set_heatr_conf()
  5. 需要采样时进入 forced 模式、按测量时长等待、读取bme69x_get_data()结果;
  6. 通过menuconfig按需调整BME690_I2C_TIMEOUT_VALUE_MSBME690_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.

项目地址:https://gitcode.com/GitHub_Trending/es/esp-iot-solution
点击查看免费下载
上一篇:【亲测免费】 探索Adobe CEP扩展的无限可能 —— 样例库全解析
下一篇:推荐一款令人惊叹的开源项目:Svelte Apollo

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询