AHT20 簡介
?
- 2020 年上市,奧松生產(chǎn);3mm*3mm*1mm 超小體積;經(jīng)過標(biāo)定的數(shù)字信號,標(biāo)準(zhǔn) I2C 輸出格式;由一個電容式濕度傳感元件和一個標(biāo)準(zhǔn)的片上溫度傳感元件組成;采用 SMD 封裝適于回流焊;響應(yīng)迅速、抗干擾能力強;AHT20 的供電范圍為 2.0-5.5V, 推薦電壓為 3.3V。
?
?
應(yīng)用場景
它廣泛應(yīng)用于暖通空調(diào) 、除濕器、測試及檢測設(shè)備、消費品、汽車 、自動控制、數(shù)據(jù)記錄器、氣象站、家電、濕度調(diào)節(jié)、醫(yī)療及其他相關(guān)濕度檢測控制等領(lǐng)域。
?
封裝
?
傳感器性能
查看我們之前分享的網(wǎng)文,對比 DHT21 的參數(shù)如下:
DHT11 及 DHT21 溫濕度傳感器時序圖解析(STM32)
由上對比,AHT20 的精度要比 DHT21 的精度要好,而且價格又低了很多。
?
原理圖
手冊中推薦電路
?
開發(fā)板中的原理圖
與開發(fā)板連接情況如下:
管腳名稱 | 復(fù)用描述 |
---|---|
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 的鴻蒙驅(qū)動代碼,潤和公司的開源庫中已經(jīng)有了,我們就不重復(fù)造輪子了,直接使用,然后結(jié)合 AHT20 的數(shù)據(jù)手冊分析一下代碼。
潤和公司開源的鴻蒙 OS AHT20 數(shù)字溫濕度傳感器驅(qū)動庫:https://gitee.com/hihopeorg/harmonyos-aht20
?
如何編譯
- 在
~/harmony/code/code-1.0/applications/sample/wifi-iot/app
目錄下執(zhí)行git clone https://github.com/xusiwei/harmonyos-aht20
,獲取源碼。
- 修改編譯腳本
- 在
~/harmony/code/code-1.0
目錄下執(zhí)行:python build.py wifiiot
?
模塊的地址
I2C 發(fā)送的首字節(jié)包括 7 位的 I2C 設(shè)備地址 0x38 和一個 SDA 方向位 X(讀 R:'1',寫 W:'0')。
手冊中描述的模塊地址定義如下:
由上分析,我們得到讀數(shù)據(jù)操作的首字節(jié)AHT20_READ_ADDR
和寫數(shù)據(jù)操作的首字節(jié)AHT20_WRITE_ADDR
分別定義如下:
#define?AHT20_DEVICE_ADDR???0x38
#define?AHT20_READ_ADDR?????((0x38<<1)|0x1)
#define?AHT20_WRITE_ADDR????((0x38<<1)|0x0)
?
I2C 總線
AHT20 采用標(biāo)準(zhǔn)的 I2C 協(xié)議進行通訊。
對于 I2C 通信我們之前分享過網(wǎng)文:
STM32 I2C 通信操作 24C02 寫數(shù)據(jù)、讀數(shù)據(jù)
4 位數(shù)碼管顯示模塊驅(qū)動
?
I2C 寫函數(shù)
上圖中的AHT20_Write()
函數(shù)中調(diào)用了I2cWrite()
函數(shù)。
I2cWrite()
函數(shù)是系統(tǒng)中 I2C 進行寫操作的函數(shù),這個函數(shù)的參數(shù)含義解釋如下:
參數(shù) 1:WifiIotI2cIdx id ,這個參數(shù)是使用的 I2C 的 ID,這個參數(shù)可選下面枚舉中的一個值:
typedef?enum?{
????/**?I2C?hardware?index?0?*/
????WIFI_IOT_I2C_IDX_0,
????/**?I2C?hardware?index?1?*/
????WIFI_IOT_I2C_IDX_1,
}?WifiIotI2cIdx;
因為我們這里使用的是 I2C0,所以這個參數(shù)應(yīng)該為:WIFI_IOT_I2C_IDX_0 。
參數(shù) 2:unsigned short deviceAddr,這個參數(shù)是 I2C 總線下面的設(shè)備地址,因為這是一個寫操作,所以這個參數(shù)我們選用上面的宏定義:AHT20_WRITE_ADDR 。
參數(shù) 3:const WifiIotI2cData *i2cData ,這個參數(shù)是我們要發(fā)送的數(shù)據(jù),該變量的數(shù)據(jù)類型為一個結(jié)構(gòu)體類型:HalWifiIotI2cData ,該結(jié)構(gòu)體的定義如下。
/**
?*?@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 讀函數(shù)
上圖中的AHT20_Read()
函數(shù)中調(diào)用了I2cRead()
函數(shù)。
I2cRead()
函數(shù)是系統(tǒng)中 I2C 進行讀操作的函數(shù)。
I2cRead()
函數(shù)的參數(shù)與I2cWrite()
函數(shù)的參數(shù)類似,只是參數(shù) 3:const WifiIotI2cData *i2cData
,這個參數(shù)用于接收我們讀取到的數(shù)據(jù)。
?
常用命令
AHT20 常用的命令有:
- 初始化命令 ('1011’1110') ,即 0xBE;測量溫濕度命令('1010’1100'),即 0xAC;軟復(fù)位命令('1011’1010'),即 0xBA。
基本指令集
狀態(tài)位
通過發(fā)送 0x71 可以獲取一個字節(jié)的狀態(tài)字,狀態(tài)字各位的含義描述如下:
狀態(tài)字各位含義說明
傳感器讀取流程
- 上電后要等待 40ms,讀取溫濕度值之前, 首先要看狀態(tài)字的校準(zhǔn)使能位 Bit[3]是否為 1(通過發(fā)送 0x71 可以獲取一個字節(jié)的狀態(tài)字),如果不為 1,要發(fā)送 0xBE 命令(初始化),此命令參數(shù)有兩個字節(jié), 第一個字節(jié)為 0x08,第二個字節(jié)為 0x00。
AHT20 模塊的狀態(tài)判斷通過下面AHT20_Calibrate()
函數(shù)來判斷,具體執(zhí)行過程如下圖所示:
注:在第一步的校準(zhǔn)狀態(tài)檢驗只需要上電時檢查,在正常過程無需操作。
軟復(fù)位
上面代碼中有一個這樣的指令:AHT20_ResetCommand()
這個命令用于在無需關(guān)閉和再次打開電源的情況下,重新啟動傳感器系統(tǒng)。
在接收到這個命令之后,傳感器系統(tǒng)開始重新初始化,并恢復(fù)默認(rèn)設(shè)置狀態(tài),軟復(fù)位所需時間不超過 20 毫秒。
圖中灰色部分由 AHT20 控制。
#define?AHT20_CMD_RESET??????0xBA?//?軟復(fù)位命令
//?發(fā)送軟復(fù)位命令
static?uint32_t?AHT20_ResetCommand(void)
{
????uint8_t?resetCmd[]?=?{AHT20_CMD_RESET};
????return?AHT20_Write(resetCmd,?sizeof(resetCmd));
}
- 直接發(fā)送 0xAC 命令(觸發(fā)測量),此命令參數(shù)有兩個字節(jié),第一個字節(jié)為 0x33,第二個字節(jié)為 0x00。
觸發(fā)測量命令發(fā)送的數(shù)據(jù)如下:
具體使用的代碼如下:
#define?AHT20_CMD_TRIGGER???????0xAC?//?觸發(fā)測量命令
#define?AHT20_CMD_TRIGGER_ARG0??0x33
#define?AHT20_CMD_TRIGGER_ARG1??0x00
//?發(fā)送?觸發(fā)測量?命令,開始測量
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));
}
- 等待 75ms 待測量完成,忙狀態(tài) Bit[7]為 0,然后可以讀取六個字節(jié)。
注:傳感器在采集時需要時間,主機發(fā)出測量指令(0xAC)后,延時 75 毫秒以上再讀取轉(zhuǎn)換后的數(shù)據(jù)并判斷返回的狀態(tài)位是否正常。若狀態(tài)比特位[Bit7]為 0 代表設(shè)備閑,可正常讀取,為 1 時傳感器為忙狀態(tài),主機需要等待數(shù)據(jù)處理完成。
- 計算溫濕度值。
?
相對濕度轉(zhuǎn)換
上圖中藍色背景的六個字節(jié)數(shù)據(jù)中,紅色方框框住的為濕度數(shù)據(jù),組成一個 20bit 長度的一個整形數(shù);紫色方框框住的 20bit 為溫度數(shù)據(jù)。
濕度數(shù)據(jù)按下面代碼實現(xiàn)拼接:
#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,所以根據(jù)上圖公式,使用如下代碼即可獲得相對濕度 RH。
*humi?=?humiRaw?/?(float)AHT20_RESOLUTION?*?100;
?
溫度轉(zhuǎn)換
按如下方式合并溫度數(shù)據(jù)的 20bit 數(shù)據(jù):
uint32_t?tempRaw?=?buffer[3]?&?0x0F;
tempRaw?=?(tempRaw?<<?8)?|?buffer[4];
tempRaw?=?(tempRaw?<<?8)?|?buffer[5];
查看手冊,我們知道 20bit 的溫度數(shù)據(jù)跟℃的換算關(guān)系如下:
用代碼具體實現(xiàn)如下:
*temp?=?tempRaw?/?(float)AHT20_RESOLUTION?*?200?-?50;
?
結(jié)果展示
將上面編譯之后的結(jié)果下載驗證,輸出如下:
?
???????