행복한 하루

Raspberry Pi Pico + dht11를 이용한 온도 습도 테스트와 1 wire 통신 소스 분석 본문

RaspberryPi/Raspberry Pi Pico

Raspberry Pi Pico + dht11를 이용한 온도 습도 테스트와 1 wire 통신 소스 분석

변화의 물결 2022. 4. 26. 01:20

 

 

안녕하세요.

 

  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

https://twinw.tistory.com/162

 

DHT11_Datasheet_source.zip
2.16MB

 

Comments