초소형 온도 습도 센서 AHT25 – 사용방법 그리고 AHT10 센서와의 비교

초소형 온도 습도 센서 AHT25 – 사용방법 그리고 AHT10 센서와의 비교

AHT25 디지털 온도 습도 센서 소개

라즈베리파이 피코 보드나 아두이노, ESP32보드 등에서 사용할 수 있는 디지털 온도 습도 센서를 찾다가, AHT25라는 센서 모듈을 접하게 되었다.

이 센서 모듈은 무엇보다 길이가 1.5cm에 폭이 0.5cm밖에 안되는 극소형의 온도 습도 센서 모듈이라, 소형화가 필요한 장치에서는 아주 유리한 장점이 있다.

기존에 소개(https://blog.naver.com/mythee1/223277151483)한 매유 유사한 기능을 수행하는 온도 습도 센서인 AHT10 센서 모듈과 비교하면, 절반도 안 되는 크기이다.

왼쪽 AHT10 vs. 오른쪽 AHT 25

AHT25 센서 모듈 역시 핵심 센서칩은 다음과 같이 매우 작은 칩 자체이며, 보드에 부착된 모듈 형태로 판매된다.

뒷면은 별다른 부착물이 없는 깨끗한 상태이다.

특히 온도 및 습도 출력이 디지털 출력 방식이고, 데이터 통신방식도 I2C라 사용도 쉬운 모듈이다. (AHT10도 I2C 방식에 디지털 출력이다.)

AHT25의 주요 스펙을 찾아보면 다음과 같은데, 온도는 약 +/-0.3도, 습도는 2% 정도의 오차 범위의 정확도를 가진다고 한다.

참고로, 다음과 같은 AHT10센서의 주요 스펙과 비교해 보면, AHT10은 실제보다 온도 및 습도가 약간 높게 나오는 반면, AHT25는 비슷한 수준에서 오차의 정도는 비슷한 것으로 보인다.

Datasheet에는 측정 온도대 별로 발생하는 오차는 다음과 같은 그래프의 형태로 확인할 수 있다.

적용 가능한 온도는 섭씨 -40도에서 80도씨 정도인데, 우리가 일상생활에서 주로 접하는 온도 범위인 0-55도 정도의 구간에서는 대략 0.3도, 최대 0.5도 정도의 편차를 나타내는 것으로 표시되어 있다.

한편 습도의 경우도 다음과 같은 2개의 그래프로 정확성을 확인할 수 있다.

한 가지 사용상의 주의는 처음 사용 시 12시간 이상 습도가 75% 이상인 곳에 두어 안정화하여야 습도 데이터가 정확하다는 점이다.

보다 더 자세한 내용들은 다음 Datasheet을 참조하기 바란다.

첨부파일

Data Sheet AHT25 A2.pdf

파일 다운로드

AHT25 센서 사용 예제

AHT25를 라즈베리파이 피코에 연결하여 회로를 구성했다.

그런데 한 가지 AHT25의 사용상 문제는 핀의 간격이 일반적인 브레드 보드의 핀들 간격의 절반이라, 그대로 사용이 불가능했다.

여러 가지로 이 센서에 배선을 연결하는 것을 고민하다가, 마침 소형 모터의 단자에 사용되던 다음의 5선 소켓을 이용했다.

다른 센서 모듈들과 달리 AHT25는 센서 보드 자체에 단자에 대한 표기가 없다. 보드가 너무 작기 때문으로 보인다.

통신방식이 i2C로 단지 4핀이 사용되며 각 핀의 기능은 다음과 같다.

결론적으로 다음과 같이 회로를 구성했고.

SDA와 SCL은 각기 GP0과 GP1에 연결했고, 3.3V와 GND를 연결해 주었다.

관련 라이브러리는 다음 링크에서 찾을 수 있는데, 이를 이용하면 된다.

https://github.com/etno712/aht

참고로 라이브러리를 첨부해둔다.

첨부파일

aht.py

파일 다운로드

위의 라이브러리와 함께 간단한 사용 예제도 함께 제공되기는 하나, 라즈베리파이 피코에 그냥 사용하기에는 동작에 문제가 있어 다음과 같이 수정해 사용했다.

import utime
import machine
import aht

i2c = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0))
sensor = aht.AHT2x(i2c, crc=True)
while True:
if sensor.is_ready:
print("Humidity: {:.2f}".format(sensor.humidity))
print("Temperature: {:.2f}".format(sensor.temperature))
print("")
        utime.sleep(2)

동작하는 모습은 다음과 같다.

AHT25 vs. AHT10

이전에 소개한 AHT10 (https://blog.naver.com/mythee1/223277151483)과 온도 및 습도 측정 결과가 어떻게 다른지 궁금했다. 2가지 센서 모듈이 완전히 동일한 기능을 하는 것이고, 동일한 디지털 출력인데다가, 통신방식도 동일한 I2C이기 때문이었다. 심지어 스펙 상의 정확도도 비슷해 보였다. 표면적인 차이는 오로지 크기뿐이었기에, 사용상 어떤 특징이 있는지 궁금했다.

이 두 개의 디지털 온도 센서 모듈들을 동일한 온도 습도 조건이라 볼 수 있는 하나의 브레드 보드에 설치했다.

그리고 AHT10의 SDA와 SCL을 각기 GP14와 GP15에 연결했다.

마이크로파이썬 코드에서 AHT10은 I2C 채널 1로 통신채널을 지정했다.

그리고, 동시 측정을 위한 코드를 이용하여 동시에 온도와 습도를 측정하여 비교해 보았다.

두 가지 센서로부터 출력되는 값들은 다음과 같았는데, 온도는 약 1도 정도, 습도는 약 4% 정도 AHT10에서 높게 나타났다.

한편 이런 비교 측정 결과에 더해, 실내에서 사용하던 온도계도 함께 두고, 두 센서의 동시 측정 결과와 비교해 보았다. 그 결과, 재미있게도 AHT25의 측정값들은 오차 수준에서 온도계보다 조금 낮게, AHT10은 온도계보다 약간 높게 나타났다.

이런 결과들을 보면, 대략 0.5도의 허용오차 수준에서, 습도는 3-4%의 허용오차 수준에서라면 자신에게 편리한 어떤 것을 사용해도 무방할 듯하다.

참고로, 두 센서의 비교에는 다음 코드를 사용했다.

import utime
import sys
import machine
import aht

#---- CONSTANTS --------------------------------------------------------------
TP_ADDR = 0x38
TP_INIT = 0xE1
TP_READ = 0xAC

# float precision
PRECISION = 2
#-----------------------------------------------------------------------------

# read from the I2C bus, stopping after the nbytes
def bus_read(i2c, addr, nbytes=1):
if nbytes < 1:
return bytearray()   
    data = i2c.readfrom(addr, nbytes)
return data

# wirte on the I2C bus
def bus_write(i2c, addr, data):
    msg = bytearray()
    msg.append(data)
    i2c.writeto(addr, msg)

def read_values(i2c):
    # initialize the sensor
    bus_write(i2c, TP_ADDR, TP_INIT)
    # send measurement command
    bus_write(i2c, TP_ADDR, TP_READ)
    # sleep for 1 second - this should be shorter (75ms according to the
    # datasheet), but on my board the sensor was returning a busy/reading
    # state (MSB of the first response byte)
    utime.sleep(1)
    # read data from the sensor, stop after 7 ack/nbytes. See datasheet for reference
    data = bus_read(i2c, TP_ADDR, 7)
return data

def convert(i2c):
    data = read_values(i2c)
    # bt shifting of the binay data to rebuild the information
    bin_temp = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5]
    bin_rh= ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4
    # decimal conversion and rounding
    temp = round((((bin_temp / 1048576) * 200 ) - 50), PRECISION)
    rh   = round(((bin_rh / 1048576) * 100), PRECISION)
return temp, rh

def detect_sensor(i2c):
    sensor=i2c.scan()
if (int(sensor[0]) != 56):
print("AHT10 sensors not detected, check cablingnQuitting.")
        sys.exit(2)
return 0

# setup the bus
i2c = machine.I2C(0, scl=machine.Pin(1), sda=machine.Pin(0), freq=400000)
i2c25 = machine.I2C(1, scl=machine.Pin(15), sda=machine.Pin(14))
sensor = aht.AHT2x(i2c25, crc=True)

# continuous reading
while True:
detect_sensor(i2c)
    reading=convert(i2c)
print('------------------------------------')
print(f'Temperature       (AHT10): {reading[0]} °C')
print(f'Relative Humidity (AHT10): {reading[1]}%')
print('')
if sensor.is_ready:
print("Temperature      (AHT25): {:.2f}".format(sensor.temperature))
print("Humidity         (AHT25): {:.2f}".format(sensor.humidity))
print("")      
        utime.sleep(2)