1 AHT10介绍
AHT10,新一代温湿度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊的双列扁平无引脚SMD封装,底面4 x 5mm ,高度1.6mm。传感器输出经过标定的数字信号,标准I2C格式。
AHT10 配有一个全新设计的ASIC专用芯片、一个经过改进的MEMS半导体电容式湿度传感元件和一个标准的片上温度传感元件,其性能已经大大提升甚至超出了前一代传感器的可靠性水平,新一代温湿度传感器,经过改进使其在恶劣环境下的性能更稳定。
AHT10读取流程如下:
1.上电后要等待40ms,读取温湿度值之箭,首先要看状态字的校准使能位Bit[3]是否为1(通过发送0x71可以获取一个字节的状态字),如果不为1,要发送0XEi命令(初始化),此命令参数有两个字节,第一个字节为0x08,第二个字节为0x00。
2.直接发送0xAC命令(触发测量),此命令参数有两个字节,第一个字节为0x33,第二个字节为0x00。
3.等待80ms待测量完成,忙状态Bit[7]为0,然后可以读取六个字节(发0X71即可以读取)。

Figure 1‑1 主机读取 AHT10流程
温度湿度读取时序如下:

Figure 1‑2 AHT10读取时序
注:传感器在采集时需要时间,主机发出测量指令(0xAC)后,延时80毫秒以上再读取转换后的数据并判断返回的状态位是否正常。若状态比特位[Bit7]为0代表数据可正常读取,为1时传感器为忙状态,主机需要等待数据处理完成。
AHT10在睡眠模式下,传感器一直等待主机发送测量命令。CPU此时只执行温湿度测量指令,其余指令无法唤醒传感器进行数据采集。
主机发送采集命令后即可唤醒AHT10进行数据采集,启动采集只需要发送7位从机地址,第八位写0即可。
采集数据时,传感器内部的数字信号处理器会对采集到的温湿度数据进行计算,并且内部算法对数据进行校正运算:采集结束后,传感器的输出寄存器会将数据进行更新,
测量周期由湿度和温度转换后的数字信号处理器(DSP)校正计算。在测量周期结束时,数字电源关闭之前输出寄存器将被更新。测量数据以14位的输出,数据位以右对齐。
AHT10输出的温湿度数据为6个字节,真实的相对湿度(%)和温度(℃)数据通过以下公式进行计算。
相对湿度:

温度转换:

2 实验详解
2.1 实验目的
1) 通过实验掌握CanMV K230芯片GPIO 的配置方法
2) 掌握温湿度传感器AHT10的原理与使用
2.2 实验相关电路图
AHT10模块相关电路如下图所示:

Figure 2‑1 AHT10模块相关电路图
AHT10接到CanMV K230的I2C2。

Figure 2‑2 CanMV K230的I2C2
2.3 AHT10数据读取
2.3.1 I2C 模块API
1、构造函数
i2c = I2C(id, freq=100000)
【参数】
- id: I2C ID, [0
4] (I2C.I2C0I2C.I2C4)
- freq: I2C时钟频率
2、scan
i2c.scan()
扫描I2C总线上的从机
【参数】
无
【返回值】
list 对象, 包含了所有扫描到的从机地址
3、 readfrom
i2c.readfrom(addr, len, True)
从总线读取数据
【参数】
- addr: 从机地址
- len: 数据长度
- stop: 是否产生停止信号,保留,目前只能使用默认值Ture
【返回值】
读取到的数据,bytes 类型
4、readfrom_into
i2c.readfrom_into(addr, buf, True)
读取数据并放到制定变量中
【参数】
- addr: 从机地址
- buf: bytearray类型, 定义了长度,读取到的数据存放在此
- stop: 是否产生停止信号,保留,目前只能使用默认值Ture
【返回值】
无
5、writeto
i2c.writeto(addr, buf, True)
发送数据到从机
【参数】
- addr: 从机地址
- buf: 需要发送的数据
- stop: 是否产生停止信号,保留,目前只能使用默认值Ture
【返回值】
成功发送的字节数
6、readfrom_mem
i2c.readfrom_mem(addr, memaddr, nbytes, mem_size=8)
读取从机寄存器
【参数】
- addr: 从机地址
- memaddr: 从机寄存器地址
- nbytes: 需要读取的长度
- mem_size: 寄存器宽度, 默认为8位
【返回值】
返回bytes类型的读取到的数据
7、readfrom_mem_into
i2c.readfrom_mem_into(addr, memaddr, buf, mem_size=8)
读取从机寄存器值到指定变量中
【参数】
- addr: 从机地址
- memaddr: 从机寄存器地址
- buf: bytearray类型, 定义了长度,读取到的数据存放在此
- mem_size: 寄存器宽度, 默认为8位
【返回值】
无
7、writeto_mem
i2c.writeto_mem(addr, memaddr, buf, mem_size=8)
写数据到从机寄存器
【参数】
- addr: 从机地址
- memaddr: 从机寄存器地址
- buf: 需要写的数据
- mem_size: 寄存器宽度, 默认为8位
【返回值】
无
9、 deinit
i2c.deinit()
释放i2c资源
【参数】
无
【返回值】
无
2.3.2 12C读取AHT10
代码如下:
from machine import Pin
from machine import FPIOA, I2C
import time
HARD_I2C = True
AHT10_ADDR = 0x38
AHT10_TRIG_MEAS = 0xAC
class AHT10:
def __init__(self, hard_flag=True, i2c_bus=2, sda_pin=12, scl_pin=11, freq=400000):
if hard_flag:
fpioa = FPIOA()
fpioa.set_function(scl_pin, FPIOA.IIC2_SCL)
fpioa.set_function(sda_pin, FPIOA.IIC2_SDA)
self.i2c=I2C(i2c_bus, freq = freq)
print(self.i2c.scan())
else:
self.i2c = I2C(i2c_bus, scl=scl_pin, sda=sda_pin, freq=freq)
print(self.i2c.scan())
def aht10_get_data(self):
self.i2c.writeto(AHT10_ADDR, bytearray([AHT10_TRIG_MEAS])) # AHT10_TRIG_MEAS
timeout = 100
while timeout > 0:
status = self.i2c.readfrom(AHT10_ADDR, True)[0]
if not (status & 0x80): # 检查忙标志
break
time.sleep_ms(10)
timeout -= 1
if timeout <= 0:
raise OSError("AHT10 测量超时")
data = self.i2c.readfrom(AHT10_ADDR, 6)
hum_raw = ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4
temp_raw = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5]
humidity = (hum_raw / (2**20)) * 100
temperature = (temp_raw / (2**20)) * 200 - 50
return temperature, humidity
def run(self):
while True:
temp, hum = self.aht10_get_data()
print(f"温度: {temp:.1f}°C, 湿度: {hum:.1f}%")
time.sleep(2) # AHT10最小测量间隔0.5秒
if __name__ == '__main__':
ah = AHT10(True, 2, 12, 11, 400 * 1000)
ah.run()
2.3.3 实验现象
将aht10接到I2C2。
终端打印信息如下:

抓取I2C的波形。

符合预期。