esp-iot-solution sensor_hub_monitor 示例全解析:基于 sensor_hub 的 I2C 传感器动态发现与数据采集 📅 发布时间:2026/9/20 22:30:01 👁 浏览次数: esp-iot-solution sensor_hub_monitor 示例全解析基于 sensor_hub 的 I2C 传感器动态发现与数据采集【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution本示例展示了如何在 ESP32 / ESP32-S2 上使用sensor_hub组件快速构建传感器应用通过 I2C 总线扫描结果动态发现并加载传感器驱动以默认参数开启采集并将结果通过事件机制上报。阅读本文后你将掌握iot_sensor_scan/iot_sensor_create/iot_sensor_start等核心 API 的用法、sensor_hub的轮询与事件架构以及如何基于板级初始化iot_board与menuconfig搭建一套可复用的多传感器监控程序。示例定位与整体流程sensor_hub_monitor位于 examples/sensors/sensor_hub_monitor其核心思路是让框架替开发者完成发现驱动 → 创建传感器 → 采集数据 → 上报事件的完整闭环。开发者只需要三件事初始化开发板拿到 I2C 总线句柄调用iot_sensor_scan()扫描当前工程中已注册的传感器驱动按驱动名创建传感器、注册事件处理器并启动。其主程序完整代码见 examples/sensors/sensor_hub_monitor/main/app_main.c整体执行顺序为iot_board_init() → 获取 I2C0 总线句柄 → iot_sensor_scan() → iot_sensor_create() → iot_sensor_handler_register() → iot_sensor_start() → 事件循环上报数据硬件需求与接线本示例默认支持common_components/boards组件中已收录的全部开发板以及任意使用 ESP32 或 ESP32-S2 的开发板使用其他开发板时可能需要按实际引脚简单修改默认支持sensor_hub中已添加的所有传感器驱动可以按下面的接线方式同时挂载一个或多个传感器。接线示意图如下所有传感器共用同一条 I2C 总线VCC / SCL / SDA / GND 并联ESP32/ESP32S2 BOARD Sensors (1) Sensors (2) .... -- -- | || VCC | || VCC [SCL IO] -------- | || SCL | || SCL [SDA IO] -------- | || SDA | || SDA | || GND | || GND -- --默认开发板为ESP32 DevkitC-V4其默认SCL引脚为22、默认SDA引脚为21。板级引脚与总线初始化由 examples/common_components/boards 组件统一管理通过iot_board_init()与iot_board_get_handle(BOARD_I2C0_ID)获取总线句柄见 app_main.c。编译与烧写1. 配置环境变量export IOT_SOLUTION_PATHPATH将PATH替换为esp-iot-solution仓库所在路径例如~/esp-iot-solution。2. 选择目标开发板idf.py menuconfig在Board Options - Choose Target Board中选择目标开发板。默认是ESP32 Devkit-V4。示例默认的sdkconfig.defaults中则预置了CONFIG_BOARD_ESP32_MESHKIT_SENSEy即 ESP32-MeshKit-Sense 板见 examples/sensors/sensor_hub_monitor/sdkconfig.defaults。3. 编译与烧写idf.py -p PORT build flash将PORT替换为实际串口端口号。关键配置项说明示例级配置Kconfig示例自身的配置定义在 examples/sensors/sensor_hub_monitor/main/Kconfig.projbuild配置项含义取值范围默认值CONFIG_SENSOR_EXAMPLE_PERIOD传感器最小采集间隔ms0 ~ 65535200该值通过SENSOR_PERIOD宏#define SENSOR_PERIOD CONFIG_SENSOR_EXAMPLE_PERIOD传入每个传感器的min_delay字段控制轮询采集周期。组件级配置sdkconfig.defaultssdkconfig.defaults中同时给出了sensor_hub组件与示例相关的完整配置组合传感器类型裁剪CONFIG_SENSOR_INCLUDED_IMUy、CONFIG_SENSOR_INCLUDED_HUMITUREy、CONFIG_SENSOR_INCLUDED_LIGHTy分别启用 IMU、温湿度、光照三类传感器 HAL 层采集任务CONFIG_SENSOR_TASK_PRIORITY_INHERITy继承调用者优先级、CONFIG_SENSOR_TASK_STACK_SIZE4096事件循环CONFIG_SENSORS_EVENT_QUEUE_SIZE32、CONFIG_SENSORS_EVENT_STACK_SIZE4096、CONFIG_SENSOR_EVENT_LOOP_AUTOy自动创建事件循环、CONFIG_SENSOR_DEFAULT_HANDLER未启用示例自带事件处理器板级CONFIG_BOARD_I2C0_INITy启用 I2C0 总线自动初始化。在iot_sensor_hub.c中传感器类型与驱动实现的绑定同样是编译期剪裁的s_sensor_impls[]数组仅在对应CONFIG_SENSOR_INCLUDED_*使能时才编译进humiture_create / imu_create / light_sensor_create等实现见 components/sensors/sensor_hub/iot_sensor_hub.c。源码剖析应用层如何驱动 sensor_hub1. 板级初始化与总线获取esp_err_t err iot_board_init(); // 按 menuconfig 选中的板卡完成外设初始化 bus_handle_t i2c0_bus_handle (bus_handle_t)iot_board_get_handle(BOARD_I2C0_ID); // 取 I2C0 总线句柄任何一步失败都会跳转到error_loop打印ERROR并挂起while(1) vTaskDelay(1000)便于串口排障见 app_main.c。2. 动态发现驱动iot_sensor_scan()iot_sensor_scan();iot_sensor_scan()的实现在 components/sensors/sensor_hub/iot_sensor_hub.c它遍历链接器段.sensor_hub_detect_fn中所有驱动注册的探测函数逐一调用并打印Find name driver, type: TYPE返回有效驱动数量。每个传感器驱动通过宏SENSOR_HUB_DETECT_FN(type_id, name_id, impl)自动注册探测函数该宏定义在 components/sensors/sensor_hub/include/iot_sensor_hub.h。为避免链接器把驱动裁剪掉驱动侧还需在CMakeLists.txt中通过target_link_libraries(${COMPONENT_LIB} INTERFACE -u symbol)强制保留符号。这就是按 I2C 扫描结果动态发现驱动的底层机制驱动自身声明了名字与类型扫描时根据驱动实现内部对 I2C 地址的探测结果决定是否加载。3. 创建传感器iot_sensor_create()以温湿度传感器 SHT3x 为例app_main.csensor_config_t sht3x_config { .bus i2c0_bus_handle, // I2C 总线句柄 .addr 0x44, // 器件 I2C 地址 .type HUMITURE_ID, // 传感器类型 .mode MODE_POLLING, // 采集模式轮询 .min_delay SENSOR_PERIOD, // 最小采集间隔默认 200 ms }; iot_sensor_create(sht3x, sht3x_config, sht3x_handle);sensor_config_t的完整字段见 components/sensors/sensor_hub/include/iot_sensor_hub.h字段说明busI2C/SPI 总线句柄addr传感器 I2C 地址type传感器类型取值见下方枚举mode采集模式MODE_DEFAULT/MODE_POLLING/MODE_INTERRUPTrange量程RANGE_DEFAULT/RANGE_MIN/RANGE_MEDIUM/RANGE_MAXmin_delay最小采集间隔ms轮询模式下即定时器周期intr_pin/intr_type中断模式下的 GPIO 引脚与触发类型传感器类型枚举定义在 components/sensors/sensor_hub/include/sensor_type.hNULL_ID、HUMITURE_ID温湿度、IMU_ID加速度/陀螺仪、LIGHT_SENSOR_ID光照/UV/颜色。iot_sensor_create()内部iot_sensor_hub.c按类型查找到对应 HAL 实现impl后依次执行impl-create()创建驱动实例impl-control()下发COMMAND_SET_MODE模式、COMMAND_SET_RANGE量程、COMMAND_SET_ODR输出频率此处即min_delay若驱动不支持对应命令会跳过返回ESP_ERR_NOT_SUPPORTED不算错误impl-control()下发COMMAND_SELF_TEST自检失败则报错将传感器节点加入全局链表分配事件位event_bit按模式初始化资源MODE_POLLING创建软件定时器xTimerCreateMODE_INTERRUPT配置 GPIO 中断若默认采集任务不存在则创建名为SENSOR_HUB的任务sensor_default_task打印Sensor created, Task name SENSOR_HUB, Type ...日志。4. 注册事件处理器与启动iot_sensor_handler_register(sht3x_handle, sensor_event_handler, sht3x_handler_handle); iot_sensor_start(sht3x_handle);iot_sensor_handler_register()为该传感器的事件基event_base形如sht3x_0x44注册回调任何事件 ID 都会触发iot_sensor_start()轮询模式下启动定时器并发送SENSOR_STARTED事件、将传感器从POWER_MODE_SLEEP唤醒到POWER_MODE_WAKEUP对应地iot_sensor_stop()/iot_sensor_delete()会发送SENSOR_STOPED事件、将器件置入睡眠并释放资源删除最后一个传感器时还会回收事件组与默认任务。5. 事件处理器与数据模型app_main.c中的sensor_event_handler覆盖了示例可能遇到的全部事件 ID核心代码如下app_main.ccase SENSOR_STARTED: ESP_LOGI(TAG, Timestamp %llu - %s_0x%x STARTED, ...); case SENSOR_HUMI_DATA_READY: ESP_LOGI(TAG, ... HUMI_DATA_READY - humiture%.2f, ..., sensor_data-humidity); case SENSOR_TEMP_DATA_READY: ESP_LOGI(TAG, ... TEMP_DATA_READY - temperature%.2f, ..., sensor_data-temperature); case SENSOR_ACCE_DATA_READY: ESP_LOGI(TAG, ... ACCE_DATA_READY - acce_x%.2f, acce_y%.2f, acce_z%.2f, ...);事件 ID 分为两类sensor_type.h通用事件SENSOR_STARTED0、SENSOR_STOPED1数据就绪事件SENSOR_ACCE_DATA_READY10、SENSOR_GYRO_DATA_READY、SENSOR_MAG_DATA_READY、SENSOR_TEMP_DATA_READY、SENSOR_HUMI_DATA_READY、SENSOR_BARO_DATA_READY、SENSOR_LIGHT_DATA_READY、SENSOR_RGBW_DATA_READY、SENSOR_UV_DATA_READY等。事件数据统一封装在sensor_data_t联合体中sensor_type.h包含timestamp微秒级来自esp_timer_get_time()、sensor_name、sensor_addr、event_id、min_delay并通过联合体暴露加速度/陀螺仪axis3_t、温湿度float、光照float、颜色rgbw_t、UVuv_t等载荷单位分别为 G、dps、dCelsius、百分比、lux 等。事件的分发由 components/sensors/sensor_hub/sensors_event.c 与 components/sensors/sensor_hub/include/sensor_event.h 提供底层复用 ESP-IDF 的esp_event循环队列大小与栈大小由上文CONFIG_SENSORS_EVENT_QUEUE_SIZE/CONFIG_SENSORS_EVENT_STACK_SIZE控制。6. 轮询采集的底层机制sensor_default_taskiot_sensor_hub.c是采集的核心每个轮询传感器对应一个周期性软件定时器定时器回调sensors_timer_cb设置事件组中该传感器的 bitiot_sensor_hub.c任务通过xEventGroupWaitBits等待事件位后对命中的传感器调用impl-acquire()采集一组数据并逐一为sensor_data_t填充时间戳、类型、名字、地址后通过sensors_event_post()发布事件。因此无论挂多少轮询传感器采集与上报都由单一SENSOR_HUB任务统一驱动采集周期由各传感器的min_delay即SENSOR_EXAMPLE_PERIOD决定。若选用MODE_INTERRUPT则改由 GPIO 中断 ISRsensors_intr_isr_handler置位触发采集。示例输出解读以同时挂载 VEML6040 光照传感器、SHT31 温湿度传感器、LIS2DH12 加速度计三个模块为例串口输出分三个阶段阶段 1发现 I2C 设备并推断驱动型号I (319) Board_Common: Board Init Done ! I (329) SENSOR_HUB: Find lis2dh12 driver, type: IMU I (329) SENSOR_HUB: Find sht3x driver, type: HUMITURE I (339) SENSOR_HUB: Find veml6040 driver, type: LIGHTSENSOR此即iot_sensor_scan()遍历驱动探测函数的输出。阶段 2创建并启动传感器I (349) SENSOR_HUB: Sensor created, Task name SENSOR_HUB, Type HUMITURE, Sensor Name sht3x, Mode MODE_POLLING, Min Delay 200 ms I (359) SENSOR_HUB: task: sensor_default_task created! I (369) SENSOR_LOOP: event loop created succeed I (379) SENSOR_LOOP: register a new handler to event loop succeed I (379) Sensors Monitor: Timestamp 850604 - sht3x_0x44 STARTEDSENSOR_HUB打印创建信息、SENSOR_LOOP打印事件循环与处理器注册信息、Sensors Monitor则是示例应用自己的 TAGapp_main.c中#define TAG Sensors Monitor。阶段 3周期采集并上报事件I (579) Sensors Monitor: Timestamp 1044096 - sht3x_0x44 HUMI_DATA_READY - humiture45.78 I (779) Sensors Monitor: Timestamp 1243127 - sht3x_0x44 TEMP_DATA_READY - temperature25.00 I (779) Sensors Monitor: Timestamp 1243127 - sht3x_0x44 HUMI_DATA_READY - humiture45.78 I (979) Sensors Monitor: Timestamp 1444101 - sht3x_0x44 TEMP_DATA_READY - temperature25.00每次采集间隔约为 200 msTimestamp单位为微秒与CONFIG_SENSOR_EXAMPLE_PERIOD默认值一致温湿度事件分别以HUMI_DATA_READY/TEMP_DATA_READY上报。进一步探索修改采集周期idf.py menuconfig中调整Sensor Monitor Example - sensor min delay(ms)更换/增加传感器在sensor_hub已支持的驱动中选择type与addr参照sht3x三段式create → handler_register → start扩展深度阅读框架sensor_hub组件的完整说明见 components/sensors/sensor_hub/README.md组件自带的虚拟传感器测试用例components/sensors/sensor_hub/test_apps可用于验证各类型驱动的采集与事件上报链路其他传感器示例仓库中还有 examples/sensors/ntc_temperature_sensor、examples/sensors/power_measure、examples/sensors/sensor_control_led 等单传感器示例可对照学习。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考