AHT20温湿度采集驱动(ESP32,Arduino)
AHT20温湿度采集驱动(ESP32,Arduino)
·
简单贴一个ESP32,Arduino框架使用的AHT20温湿度采集驱动。
AHT20是一个温湿度采集的小东西,
关于怎么写I2C器件的驱动之前的文章有介绍。
前言——AHT20基本参数
基本参数
-
测量范围:
-
温度:-40°C ~ +85°C
-
湿度:0% ~ 100% RH
-
-
测量精度(典型值):
-
温度:±0.3°C(在25°C时)
-
湿度:±2% RH(20% ~ 80% RH范围内)
-
-
分辨率:
-
温度:0.01°C
-
湿度:0.024% RH
-
-
响应时间:
-
湿度:8秒(τ63%响应时间)
-
温度:5秒(τ63%响应时间)
-
电气特性
-
工作电压:2.2V ~ 5.5V(宽电压设计)
-
功耗:
-
测量时:1.5mA(典型值)
-
待机时:0.2μA(低功耗模式)
-
-
通信接口:I²C接口(支持标准模式100kHz和快速模式400kHz)
-
输出数据:
-
温度:16位数字量
-
湿度:16位数字量
-
一、头文件AHT20.h
#ifndef AHT20_H
#define AHT20_H
#include <Arduino.h>
#include <Wire.h>
#define AHT20_ADDRESS 0x38 // AHT20固定I2C地址
class AHT20 {
public:
// 构造函数(指定Wire总线,可选指定引脚)
AHT20(TwoWire &wire = Wire, uint8_t sdaPin = SDA, uint8_t sclPin = SCL);
// 初始化传感器
bool begin();
// 读取温湿度数据
bool read(float* temperature, float* humidity);
// 单独读取温度
float readTemperature();
// 单独读取湿度
float readHumidity();
// 软复位传感器
bool reset();
private:
TwoWire* _wire;
uint8_t _sdaPin;
uint8_t _sclPin;
// 检查传感器状态
bool isCalibrated();
bool isBusy();
// 触发测量
bool triggerMeasurement();
// 读取原始数据
bool readRawData(uint32_t* humidity, uint32_t* temperature);
};
#endif
二、源文件AHT20.cpp
#include "AHT20.h"
AHT20::AHT20(TwoWire &wire, uint8_t sdaPin, uint8_t sclPin)
: _wire(&wire), _sdaPin(sdaPin), _sclPin(sclPin) {
}
bool AHT20::begin() {
_wire->begin(_sdaPin, _sclPin);
return reset();
}
bool AHT20::reset() {
_wire->beginTransmission(AHT20_ADDRESS);
_wire->write(0xBA); // 软复位命令
if (_wire->endTransmission() != 0) {
return false;
}
delay(20); // 等待复位完成
// 初始化校准
_wire->beginTransmission(AHT20_ADDRESS);
_wire->write(0xBE); // 初始化命令
_wire->write(0x08);
_wire->write(0x00);
if (_wire->endTransmission() != 0) {
return false;
}
delay(10); // 等待校准完成
return isCalibrated();
}
bool AHT20::read(float* temperature, float* humidity) {
if (!triggerMeasurement()) {
return false;
}
uint32_t rawHumidity, rawTemperature;
if (!readRawData(&rawHumidity, &rawTemperature)) {
return false;
}
if (humidity != nullptr) {
*humidity = (float)rawHumidity * 100 / 0x100000; // 转换为百分比
}
if (temperature != nullptr) {
*temperature = (float)rawTemperature * 200 / 0x100000 - 50; // 转换为摄氏度
}
return true;
}
float AHT20::readTemperature() {
float temperature;
if (read(&temperature, nullptr)) {
return temperature;
}
return NAN;
}
float AHT20::readHumidity() {
float humidity;
if (read(nullptr, &humidity)) {
return humidity;
}
return NAN;
}
bool AHT20::isCalibrated() {
_wire->beginTransmission(AHT20_ADDRESS);
_wire->write(0x71); // 读取状态字节
if (_wire->endTransmission() != 0) {
return false;
}
if (_wire->requestFrom(AHT20_ADDRESS, (uint8_t)1) != 1) {
return false;
}
uint8_t status = _wire->read();
return (status & 0x08) != 0; // 检查校准位
}
bool AHT20::isBusy() {
_wire->beginTransmission(AHT20_ADDRESS);
_wire->write(0x71); // 读取状态字节
if (_wire->endTransmission() != 0) {
return true; // 假设忙状态以防通信失败
}
if (_wire->requestFrom(AHT20_ADDRESS, (uint8_t)1) != 1) {
return true;
}
uint8_t status = _wire->read();
return (status & 0x80) != 0; // 检查忙位
}
bool AHT20::triggerMeasurement() {
_wire->beginTransmission(AHT20_ADDRESS);
_wire->write(0xAC); // 触发测量命令
_wire->write(0x33);
_wire->write(0x00);
if (_wire->endTransmission() != 0) {
return false;
}
// 等待测量完成
unsigned long start = millis();
while (isBusy()) {
if (millis() - start > 200) { // 超时200ms
return false;
}
delay(10);
}
return true;
}
bool AHT20::readRawData(uint32_t* humidity, uint32_t* temperature) {
if (_wire->requestFrom(AHT20_ADDRESS, (uint8_t)6) != 6) {
return false;
}
uint8_t data[6];
for (int i = 0; i < 6; i++) {
data[i] = _wire->read();
}
// 检查状态位
if (data[0] & 0x80) { // 忙状态
return false;
}
if (humidity != nullptr) {
*humidity = ((uint32_t)data[1] << 12) | ((uint32_t)data[2] << 4) | ((data[3] >> 4) & 0x0F);
}
if (temperature != nullptr) {
*temperature = (((uint32_t)data[3] & 0x0F) << 16) | ((uint32_t)data[4] << 8) | data[5];
}
return true;
}
三、调用方法
1、全局定义
总线号和IO引脚号根据你实际情况修改。
#define I2C_SDA_PinNum 5
#define I2C_SCL_PinNum 4
AHT20 aht20(Wire1, I2C_SDA_PinNum, I2C_SCL_PinNum);
2、初始化,放setup()中
if (!aht20.begin()) {
Serial.println("无法初始化AHT20传感器!");
while (1);
}
3、数据读取
float temperature_aht20 = aht20.readTemperature();
float humidity = aht20.readHumidity();
if (!isnan(temperature_aht20) && !isnan(humidity)) {
Serial.print("温度: ");
Serial.print(temperature_aht20);
Serial.print(" °C\t");
Serial.print("湿度: ");
Serial.print(humidity);
Serial.println(" %");
} else {
Serial.println("读取传感器数据失败!");
}
更多推荐



所有评论(0)