加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • 应用场景
    • 传感器性能
    • 原理图
    • 程序源码
    • 如何编译
    • 模块的地址
    • I2C 总线
    • I2C 写函数
    • I2C 读函数
    • 常用命令
    • 状态位
    • 传感器读取流程
    • 结果展示
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

跟着小哈一起读AHT20温湿度传感器驱动源码

2020/11/26
495
阅读需 4 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

AHT20 简介

 

  • 2020 年上市,奥松生产;3mm*3mm*1mm 超小体积;经过标定的数字信号,标准 I2C 输出格式;由一个电容式湿度传感元件和一个标准的片上温度传感元件组成;采用 SMD 封装适于回流焊;响应迅速、抗干扰能力强;AHT20 的供电范围为 2.0-5.5V, 推荐电压为 3.3V。

 

 

应用场景

它广泛应用于暖通空调 、除湿器、测试及检测设备、消费品、汽车 、自动控制、数据记录器、气象站、家电、湿度调节、医疗及其他相关湿度检测控制等领域。

 

封装

 

传感器性能

查看我们之前分享的网文,对比 DHT21 的参数如下:

DHT11 及 DHT21 温湿度传感器时序图解析(STM32)

由上对比,AHT20 的精度要比 DHT21 的精度要好,而且价格又低了很多。

 

原理图

手册中推荐电路

 

开发板中的原理图

开发板连接情况如下:

管脚名称 复用描述
GPIO_13 GPIO_13/ADC6/PWM4_OUT/I2C0_SDA/ UART0_LOG_TXD
GPIO_14 GPIO_14/PWM5_OUT/I2C0_SCL/ UART0_LOG_RXD

由上我们知道,这个 AHT20 使用的 Hi3861 芯片的 I2C0。

 

程序源码

AHT20 的鸿蒙驱动代码,润和公司的开源库中已经有了,我们就不重复造轮子了,直接使用,然后结合 AHT20 的数据手册分析一下代码。

润和公司开源的鸿蒙 OS AHT20 数字温湿度传感器驱动库:https://gitee.com/hihopeorg/harmonyos-aht20

 

如何编译

  1. ~/harmony/code/code-1.0/applications/sample/wifi-iot/app目录下执行git clone https://github.com/xusiwei/harmonyos-aht20 ,获取源码。

  1. 修改编译脚本

  1. ~/harmony/code/code-1.0目录下执行:python build.py wifiiot

 

模块的地址

I2C 发送的首字节包括 7 位的 I2C 设备地址 0x38 和一个 SDA 方向位 X(读 R:'1',写 W:'0')。

手册中描述的模块地址定义如下:

由上分析,我们得到读数据操作的首字节AHT20_READ_ADDR和写数据操作的首字节AHT20_WRITE_ADDR分别定义如下:

#define AHT20_DEVICE_ADDR   0x38
#define AHT20_READ_ADDR     ((0x38<<1)|0x1)
#define AHT20_WRITE_ADDR    ((0x38<<1)|0x0)

 

I2C 总线

AHT20 采用标准的 I2C 协议进行通讯。

对于 I2C 通信我们之前分享过网文:

STM32 I2C 通信操作 24C02 写数据、读数据

4 位数码管显示模块驱动

基于鸿蒙 OS 移植 OLED 驱动程序

 

I2C 写函数

上图中的AHT20_Write()函数中调用了I2cWrite()函数。

I2cWrite()函数是系统中 I2C 进行写操作的函数,这个函数的参数含义解释如下:

参数 1:WifiIotI2cIdx id ,这个参数是使用的 I2C 的 ID,这个参数可选下面枚举中的一个值:


typedef enum {
    /** I2C hardware index 0 */
    WIFI_IOT_I2C_IDX_0,
    /** I2C hardware index 1 */
    WIFI_IOT_I2C_IDX_1,
} WifiIotI2cIdx;

因为我们这里使用的是 I2C0,所以这个参数应该为:WIFI_IOT_I2C_IDX_0 。

参数 2:unsigned short deviceAddr,这个参数是 I2C 总线下面的设备地址,因为这是一个写操作,所以这个参数我们选用上面的宏定义:AHT20_WRITE_ADDR 。

参数 3:const WifiIotI2cData *i2cData ,这个参数是我们要发送的数据,该变量的数据类型为一个结构体类型:HalWifiIotI2cData ,该结构体的定义如下。


/**
 * @brief Defines I2C data transmission attributes.
 */
typedef struct {
    /** Pointer to the buffer storing data to send */
    unsigned char *sendBuf;
    /** Length of data to send */
    unsigned int  sendLen;
    /** Pointer to the buffer for storing data to receive */
    unsigned char *receiveBuf;
    /** Length of data received */
    unsigned int  receiveLen;
} HalWifiIotI2cData;

 

I2C 读函数

上图中的AHT20_Read()函数中调用了I2cRead()函数。

I2cRead()函数是系统中 I2C 进行读操作的函数。

I2cRead()函数的参数与I2cWrite()函数的参数类似,只是参数 3:const WifiIotI2cData \*i2cData ,这个参数用于接收我们读取到的数据。

 

常用命令

AHT20 常用的命令有:

  • 初始化命令 ('1011’1110') ,即 0xBE;测量温湿度命令('1010’1100'),即 0xAC;软复位命令('1011’1010'),即 0xBA。

基本指令集

状态位

通过发送 0x71 可以获取一个字节的状态字,状态字各位的含义描述如下:

状态字各位含义说明

传感器读取流程

  1. 上电后要等待 40ms,读取温湿度值之前, 首先要看状态字的校准使能位 Bit[3]是否为 1(通过发送 0x71 可以获取一个字节的状态字),如果不为 1,要发送 0xBE 命令(初始化),此命令参数有两个字节, 第一个字节为 0x08,第二个字节为 0x00。

AHT20 模块的状态判断通过下面AHT20_Calibrate()函数来判断,具体执行过程如下图所示:

注:在第一步的校准状态检验只需要上电时检查,在正常过程无需操作。

软复位

上面代码中有一个这样的指令:AHT20_ResetCommand()

这个命令用于在无需关闭和再次打开电源的情况下,重新启动传感器系统。

在接收到这个命令之后,传感器系统开始重新初始化,并恢复默认设置状态,软复位所需时间不超过 20 毫秒。

图中灰色部分由 AHT20 控制。

#define AHT20_CMD_RESET      0xBA // 软复位命令
// 发送软复位命令
static uint32_t AHT20_ResetCommand(void)
{
    uint8_t resetCmd[] = {AHT20_CMD_RESET};
    return AHT20_Write(resetCmd, sizeof(resetCmd));
}
  1. 直接发送 0xAC 命令(触发测量),此命令参数有两个字节,第一个字节为 0x33,第二个字节为 0x00。

触发测量命令发送的数据如下:

具体使用的代码如下:

#define AHT20_CMD_TRIGGER       0xAC // 触发测量命令
#define AHT20_CMD_TRIGGER_ARG0  0x33
#define AHT20_CMD_TRIGGER_ARG1  0x00

// 发送 触发测量 命令,开始测量
uint32_t AHT20_StartMeasure(void)
{
    uint8_t triggerCmd[] = {AHT20_CMD_TRIGGER, AHT20_CMD_TRIGGER_ARG0, AHT20_CMD_TRIGGER_ARG1};
    return AHT20_Write(triggerCmd, sizeof(triggerCmd));
}
  1. 等待 75ms 待测量完成,忙状态 Bit[7]为 0,然后可以读取六个字节。

注:传感器在采集时需要时间,主机发出测量指令(0xAC)后,延时 75 毫秒以上再读取转换后的数据并判断返回的状态位是否正常。若状态比特位[Bit7]为 0 代表设备闲,可正常读取,为 1 时传感器为忙状态,主机需要等待数据处理完成。

  1. 计算温湿度值。

 

相对湿度转换

上图中蓝色背景的六个字节数据中,红色方框框住的为湿度数据,组成一个 20bit 长度的一个整形数;紫色方框框住的 20bit 为温度数据。

湿度数据按下面代码实现拼接:

#define AHT20_RESOLUTION            (1<<20)  // 2^20

uint32_t humiRaw = buffer[1];
humiRaw = (humiRaw << 8) | buffer[2];
humiRaw = (humiRaw << 4) | ((buffer[3] & 0xF0) >> 4);

通过手册我们得知相对湿度的计算公式如下:

上面代码求得的 humiRaw 即为上图公式中的 Srh,所以根据上图公式,使用如下代码即可获得相对湿度 RH。

*humi = humiRaw / (float)AHT20_RESOLUTION * 100;

 

温度转换

按如下方式合并温度数据的 20bit 数据:

uint32_t tempRaw = buffer[3] & 0x0F;
tempRaw = (tempRaw << 8) | buffer[4];
tempRaw = (tempRaw << 8) | buffer[5];

查看手册,我们知道 20bit 的温度数据跟℃的换算关系如下:

用代码具体实现如下:

*temp = tempRaw / (float)AHT20_RESOLUTION * 200 - 50;

 

结果展示

将上面编译之后的结果下载验证,输出如下:

 

​​​​​​​

相关推荐

电子产业图谱

公众号『嵌入式从0到1』,号主:程序员小哈,是一个软硬件全栈开发工程师(12年工作经验的老司机),电子发烧友论坛鸿蒙版块版主,公众号内容专注于嵌入式学习。坚持原创,写有图、有视频的保姆级教程文章,篇篇有干货。做一个讲清楚,说明白,大家学得会的交流平台。