esp-iot-solution 中 AHT20 温湿度传感器 I2C 驱动组件使用指南
【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution
导读
本文围绕 esp-iot-solution 仓库中的 AHT20 驱动组件 展开,系统讲解如何在乐鑫 ESP-IDF 工程中通过 I2C 总线接入 ASAIR AHT20 温湿度传感器:从总线初始化、设备地址选择到温湿度数据读取与资源回收的完整流程。读完本文,你将掌握该组件的全部公开 API 用法,理解其底层测量命令、状态位校验、CRC 校验与 20bit 原始数据解析原理,并能在自己的项目中直接复用这套驱动。
组件概览:AHT20 与兼容型号
aht20是 esp-iot-solution 中一款基于 I2C 接口的温湿度传感器驱动组件,位于 components/sensors/humiture/aht20,核心功能由 aht20.c 实现,对外接口定义在 include/aht20.h。
根据组件 README 与 CHANGELOG.md 的说明:
- 组件不仅支持 AHT20,还兼容 AHT30(v1.0.0 起在说明中补充了 AHT30 描述),以及 AHT21(官方标注 AHT21 已 deprecated,不推荐在新设计中选用);
- 芯片关键参数在 priv_include/aht20_reg.h 中定义:型号名为
ASAIR AHT20,供电电压范围 2.2V ~ 5.5V,工作温度范围 -40℃ ~ 125℃; - 组件版本为 v2.0.0(2025-08-08 发布),该版本引入了对
i2c_bus通用总线组件的支持,将底层 I2C 通信完全委托给 espressif/i2c_bus 组件(依赖版本^1.4.0)。
组件的依赖信息见 idf_component.yml:要求IDF 版本 >= 4.3,并依赖cmake_utilities与espressif/i2c_bus(public: true,即使用方可以直接访问其头文件)。
I2C 总线初始化
AHT20 驱动本身不管理 I2C 总线,而是复用 esp-iot-solution 的i2c_bus组件。因此使用前必须先在应用侧创建总线句柄,这一步骤与 AHT20 的驱动代码无关,属于标准前置操作。
#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number for I2C master clock */ #define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number for I2C master data */ #define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ const i2c_config_t i2c_bus_conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_io_num = I2C_MASTER_SCL_IO, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ }; i2c_bus_handle_t i2c_bus = i2c_bus_create(I2C_MASTER_NUM, &i2c_bus_conf);要点说明:
I2C_MASTER_SCL_IO/I2C_MASTER_SDA_IO在测试工程中由 Kconfig 配置项提供(默认 SCL=40、SDA=41,见 test_apps/main/Kconfig.projbuild),实际项目中可根据硬件接线替换为具体 GPIO 编号;- 总线时钟频率
I2C_MASTER_FREQ_HZ设为 100000(100 kHz 标准模式),符合 AHT20 数据手册对标准 I2C 速率的要求; - 内部上下拉
GPIO_PULLUP_ENABLE建议保持开启,因为传感器模块通常不带强上拉; i2c_bus_create返回的总线句柄需判空检查,失败时返回NULL。该接口的完整定义可参考 components/i2c_bus/include/i2c_bus.h。
创建 AHT20 设备句柄
总线就绪后,通过aht20_new_sensor在指定总线上创建 AHT20 设备句柄。设备配置结构体aht20_i2c_config_t定义于 include/aht20.h:
aht20_i2c_config_t i2c_conf = { .bus_inst = i2c_bus, // I2C bus instance .i2c_addr = AHT20_ADDRRES_0, // Device address }; aht20_dev_handle_t handle; aht20_new_sensor(&i2c_conf, &handle);设备地址如何确定?AHT20 的 I2C 7 位地址由芯片的CE(A0)引脚决定,定义在 include/aht20.h:
| 宏定义 | 地址值 | CE 引脚电平 |
|---|---|---|
AHT20_ADDRRES_0 | 0x38 | CE 拉低 |
AHT20_ADDRESS_1 | 0x39 | CE 拉高 |
从源码看,aht20_new_sensor的实现(aht20.c)本质上是调用i2c_bus_device_create(bus_inst, i2c_addr, 0)在总线上挂载一个地址为 0x38/0x39 的子设备,第三个参数 0 表示不覆盖总线时钟频率(沿用总线默认时钟)。创建成功时句柄非空;若失败,函数打印i2c_bus_device_create failed并返回ESP_FAIL。同时该函数会打印芯片型号与版本号、供电电压范围、工作温度范围等日志,便于上电确认器件身份。
aht20_dev_handle_t为void *类型,对调用方透明,内部实际是i2c_bus_device_handle_t。
读取温湿度数据
创建句柄后,即可周期性调用aht20_read_temperature_humidity获取实时数据。该 API 同时输出原始值(raw)与换算后的物理量,见 include/aht20.h:
uint32_t temperature_raw, humidity_raw; float temperature, humidity; aht20_read_temperature_humidity(handle, &temperature_raw, &temperature, &humidity_raw, &humidity); ESP_LOGI(TAG, "%-20s: %2.2f %%", "humidity is", humidity); ESP_LOGI(TAG, "%-20s: %2.2f degC", "temperature is", temperature);参数说明:
temperature_raw/humidity_raw:传感器返回的 20bit 原始 ADC 数据,可用于自行换算或调试比对;temperature/humidity:驱动换算后的物理量,湿度单位为 %RH,温度单位为摄氏度;- 返回值:
ESP_OK表示读取成功;ESP_ERR_INVALID_ARG表示句柄非法;ESP_ERR_NOT_FINISHED表示数据未就绪;I2C 通信失败或 CRC 校验失败也会返回对应错误码。
源码级原理:一次温湿度读取的完整链路
深入 aht20.c 的实现,可以看到一次读取包含四个关键步骤:
1. 发送测量触发命令。驱动向命令寄存器写入AHT20_START_MEASURMENT_CMD(0xAC,定义于 aht20_reg.h),并携带两个参数字节0x33, 0x00,要求传感器进行一次温湿度测量。命令写完后驱动主动vTaskDelay(pdMS_TO_TICKS(100))等待 100ms——这是数据手册规定的测量时间余量,属于阻塞等待,实际应用中如需非阻塞流程可自行调度。
2. 读取状态字节并检查标志位。驱动先读 1 字节状态,依据 aht20_reg.h 定义的位含义进行三重校验:
BIT(AT581X_STATUS_Calibration_Enable)(bit3):校准已启用(1)才算数据有效;BIT(AT581X_STATUS_CRC_FLAG)(bit4):CRC 标志位为 1 表示校验通过;BIT(AT581X_STATUS_BUSY_INDICATION)(bit7):忙标志必须为 0,即设备空闲。
三者同时满足才进入数据读取,否则打印data is not ready并返回ESP_ERR_NOT_FINISHED。
3. 读取 7 字节数据并做 CRC 校验。数据帧为 6 字节有效数据 + 1 字节 CRC。驱动用aht20_calc_crc对前 6 字节计算 CRC8(多项式 0x31,初值 0xFF,即 CRC-8/MAXIM),并与第 7 字节比对,不一致返回crc is error。
4. 解析 20bit 原始数据并换算物理量。AHT20 的温湿度各占 20bit,在 6 字节数据中交叉存放:
- 湿度:由字节 1、2、3 拼接成 24bit 后右移 4 位得到 20bit 原始值,换算公式
humidity = raw * 100 / 1048576(1048576 = 2^20),将 0~2^20 的原始值映射到 0~100 %RH; - 温度:由字节 3 低 4 位 + 字节 4、5 拼接得到 20bit 原始值,换算公式
temperature = raw * 200 / 1048576 - 50,将原始值映射到 -50℃ ~ +150℃ 区间(实际有效量程以芯片数据手册为准)。
这套解析逻辑完全对齐 AHT20 数据手册规定的数据格式,如果你需要自行移植或二次开发,可参照 aht20.c 中的位拼接与换算代码。
资源清理
传感器使用完毕(或进入低功耗休眠前)应释放资源,与创建过程对称:
aht20_del_sensor(handle); i2c_bus_delete(&i2c_bus);aht20_del_sensor内部调用i2c_bus_device_delete释放设备句柄(aht20.c),失败时打印i2c_bus_device_delete failed并返回对应错误码;i2c_bus_delete释放整条总线资源。注意:先删设备、再删总线,顺序不可颠倒,否则会留下悬垂引用。
测试验证与内存泄漏检查
仓库为组件提供了完整的单元测试工程,位于 test_apps,入口为 main/aht20_test.c,配套 pytest_aht20.py 可实现自动化测试。
测试用例sensor aht20 test完整走了一遍「总线创建 → 传感器创建 → 读取温湿度(断言返回ESP_OK)→ 删除传感器 → 删除总线」的生命周期;同时通过setUp/tearDown对比测试前后的MALLOC_CAP_8BIT与MALLOC_CAP_32BIT堆空闲内存(阈值 -400 字节),验证驱动在创建/删除过程中不存在内存泄漏。这套测试代码本身就是一份可直接参考的最小可运行示例,比 README 中的片段更完整。
测试工程的 sdkconfig.defaults 关闭了任务看门狗(兼容 IDF 4.4 与 5.0 两种写法),并启用 USB Serial/JTAG 控制台,便于在开发板上直接运行测试菜单。
集成到你的工程
在 ESP-IDF 工程中启用该组件有两条途径:
- 本地路径引用:将 components/sensors/humiture/aht20 目录加入工程的
EXTRA_COMPONENT_DIRS,esp-iot-solution 仓库本身就是按组件目录组织,可直接复用; - IDF Component Manager:通过
idf_component.yml声明依赖espressif/aht20(组件清单见 idf_component.yml),由构建系统自动拉取。
无论哪种方式,i2c_bus组件(espressif/i2c_bus,版本^1.4.0)都会作为传递依赖自动引入。按照「总线初始化 → 传感器创建 → 周期读取 → 资源清理」四步即可完成一次完整的 AHT20 温湿度采集闭环,整个过程不依赖具体板卡,仅需根据硬件原理图确认 SCL/SDA 引脚与 CE 引脚的地址电平。
【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考