안녕하세요.
hdt11 온도, 습도 센서를 아두이노에서 다루어 보았는데, Raspberry Pi Pico에서도 테스트를 해보자 생각이 들었습니다.
Python으로 된 온도와 습도를 가져오는 부분의 소스 설명은 많이 있지만, 실제적으로 hdt11에 1 wire 통신 쪽을 설명해 주는 자료는 많이 없어서 간단하게 Datasheet 보면서 python으로 된 소스를 확인해 보았습니다.
1. hdt11 연결
핀 설명 : SIG 핀, VCC(3~5.5V), GND 핀으로 구성되어 있으며 hdt11 모듈 자체로 구매하면 SIG 핀 Pull-Up 저항을 부착할 것을 권하고 있습니다. 작은 모듈 타입으로 된 것을 구매하면 저항 붙여서 3핀으로 되어있습니다.
- Raspberry Pi Pico - hdt11
3V3 - VCC
GND - GND
GP17 - SIG (GP17 아니더라도 원하는 핀으로 변경 가능)
2. 소스 분석
2.1 hdt11.py 소스 분석
기본 소스는 https://github.com/ikornaselur/pico-libs/tree/master/src/dht11 있는 것을 사용하였습니다.
그리고 함수명을 중심으로 내용을 설명하도록 하겠습니다.
1) def __init__(self, pin):
신호 핀과 클래스 멤버 변수들을 초기화합니다.
2) def _send_init_signal(self):
데이터를 받기 위해서 초기신호를 만듭니다. 데이터 시트에 나와 있는 것처럼 MCU에서 초기에 High 상태에서 Low 상태로 바꾼 후 최소 18ms 정도 유지해야 합니다.
3) def _capture_pulses(self):
MCU에서 데이터 신호를 받겠다는 보낸 후 DHT11의 데이터(펄스)를 받기 위해서 입력 핀으로 설정을 바꿉니다. 예상되는 필요 펄스의 개수는 84개로 정해져 있는데 이것은 아래와 같이 계산된 것으로 생각됩니다. 84개의 bytearray의 변수를 생성
펄스가 변했는지 안 했는지(Start to transmit bit에서 data bit로 High상태가 된 것)를 구분하면서 펄스 간의 시간을 구해서 변수에 저장합니다. 그리고 펄스 개수가 많거나 적으면 에러 처리를 하고 앞에 4비트 시간을 제외하고 펄스마다의 시간 저장한 80개 바이트 배열을 리턴합니다. 4 + (5 * 8 * 2) = 84
- 5 byte : 온도, 습도, 체크섬 - 데이터 구조
- 8 bit : 비트로 계산하기 변환
- 2 : 데이터 비트 전송 후 Low 상태 유지 펄스 포함(Start to transmit)
- 4bit : DHT response 시작 데이터 (정확한 값은 모르겠음)
4) def _convert_pulses_to_buffer(self, pulses):
펄스 시간을 가지고 0과 1을 구분합니다. HIGH_LEVEL = 50us 보다 긴 시간은 1로 바꿔고 저장할 변수에 1비트씩 shift 연산 후 OR 연산자로 마지막 값에 추가합니다. 작다면 그냥 0 값이 shift 된다고 생각하면 됩니다.
- for문에서 2개씩 넘어가는 것은 Start to transmit bit 시간을 건너뛰기 위해서 사용합니다.
- 펄스 데이터를 80개 데이터를 출력해 보면 Data bit + Start to transmit bit + Data bit...로 되어 있는 것을 확인할 수 있습니다.
- unsigned char 형태의 배열을 생성하고 binary로 뭉쳐 있는 40bit(5byte) 데이터를 1byte 단위로 끊어서 buffer에 1byte씩 추가합니다. 버퍼에 들어 있는 값을 보면 다음과 같습니다.
- 0번 byte (41) : Integral relative humidity data
- 1번 byte (0): Decimal relative humidity data
- 2번 byte (25): Integral temperature data
- 3번 byte (8): Decimal temperature data
- 4번 byte (74): Checksum
5) def _verify_checksum(self, buffer):
마지막으로 체크섬을 검사할 수 있도록 4byte 값을 더해서 마지막 체크섬 바이트 값과 같은지 비교해서 정상 값인지 검사합니다.
2.2 main.py 소스
- 센서 전원 공급 1초 정도 기다려 주고, SIG 핀을 출력 핀으로 Pull-Down 모드로 설정해 주고 DHT11 클래스의 인스턴스를 생성 후 sensor 변수의 온도, 습도 property를 출력합니다.
from machine import Pin
import utime
from dht import DHT11, InvalidChecksum
# Wait 1 second to let the sensor power up
utime.sleep(1)
pin = Pin(17, Pin.OUT, Pin.PULL_DOWN)
sensor = DHT11(pin)
try:
print("Temperature: {}".format(sensor.temperature))
print("Humidity: {}".format(sensor.humidity))
except InvalidChecksum:
print("Checksum from the sensor was invalid")
참고로 인터넷 자료 찾으면서 ATmega128로 dht11 제어하는 설명 중 데이터 시트 내용을 잘 분석한 내용이 있어서 핵심적인 부분을 가져왔습니다.
“- 데이터 선이 사용되지 않을 때(자유로운 상태, free status)는 high-level voltage를 유지한다. MCU와 DHT11 사이의 통신이 시작되면 MCU는 데이터 선의 신호 레벨을 high에서 low으로 설정하며, 이 과정은 최소 18ms가 소요되어야만 MCU의 신호를 DHT11가 감지할 수 있으며, 그 후 MCU는 전압을 끌어올려(high) DHT11의 응답을 20-40us 기다려야 한다.
- DHT11이 start 신호를 감지하면, low-level voltage의 응답신호를 80us동안 전송한다.(즉, 데이터 선이 low-level voltage일 때는 DHT11이 응답 신호를 보내고 있다는 것을 의미한다) 그런 다음 DHT11은 데이터 선의 신호 레벨을 low에서 high로 설정하고, 데이터 전송 준비를 위해 80us 동안 해당 상태를 유지한다.
- DHT11이 MCU로 데이터를 전송할 때, 모든 데이터의 비트는 50us의 low-level voltage에서 시작하고 다음 high-level voltage의 길이에 따라 데이터 비트가 "0"인지 "1"인지 결정한다. "
- "[ATmega128] DHT11(온습도 센서) 제어 " 내용 중
위의 소스들 말고도 Adafruit_Python_DHT 등 이너넷에 여러 소스가 있으니 본인이 사용하기 편한 혹은 이해하기 쉬운 것으로 사용하시면 됩니다. 그리고 dht22 버전과 조금 소스가 다를 수 있으니 호환되는 소스를 찾아서 내용 추가해서 사용하시면 됩니다.
감사합니다.
<참고 사이트>
1. dht11 소스
https://github.com/ikornaselur/pico-libs/tree/master/src/dht11
2. MicroPython: ESP32/ESP8266 with DHT11/DHT22 Temperature and Humidity Sensor
https://randomnerdtutorials.com/esp32-esp8266-dht11-dht22-micropython-temperature-humidity-sensor/
3. DHT11 DHT22 with Raspberry Pi Pico using MicroPython
https://microcontrollerslab.com/dht11-dht22-raspberry-pi-pico-micropython-tutorial/
4. [ATmega128] DHT11(온습도 센서) 제어
https://jdselectron.tistory.com/69
5. adafruit/Adafruit_Python_DHT
https://github.com/adafruit/Adafruit_Python_DHT
6. [ARTIK 050] DHT11(온습도) - Digital Communication
'Embedded > Raspberry Pi Pico' 카테고리의 다른 글
Raspberry Pi Pico(라즈베리파이 피코) W5100S-EVB-PICO 테스트하기(C/C++ 버전) (0) | 2024.08.15 |
---|---|
Raspberry Pi Pico(라즈베리파이 피코) 간단하게 C/C++ SDK 설치 및 빌드해보기 (0) | 2024.08.13 |
Raspberry Pi Pico 내부 온도 센서 값 읽기 (0) | 2024.08.09 |
Raspberry Pi Pico “RP2 Boot” 장치 드라이버 경고가 나타날 경우 (0) | 2024.08.07 |
[번역 프로젝트] Getting started with Raspberry Pi Pico (Power your Raspberry Pi Pico) – 10 (마지막 편) (0) | 2024.08.05 |