라즈베리 파이 4에서 Python을 사용하여 GPIO를 통해 DHT11 온습도 센서에서 데이터 읽기
소개
DHT11은 교정된 디지털 신호 출력을 제공하는 온습도 센서입니다. 습도 정확도는 ±5%RH, 온도 정확도는 ±2℃이며, 측정 범위는 습도 20~90%RH, 온도 0~50℃입니다. 정확도는 낮지만 가격이 저렴합니다. DHT11은 싱글 바스 통신을 사용하며, 작동 전압은 3.3~5V입니다.
Arduino로 DHT11, DHT22, SHTC3 온습도 데이터 읽기: https://blog.zeruns.com/archives/527.html
Python으로 마이크로초 단위 지연 구현 방법: https://blog.zeruns.com/archives/623.html
DHT11 데이터시트 다운로드 주소: https://url.zeruns.com/DHT11 비밀번호: qefk
소스 코드
회로 연결:
저는 라즈베리 파이 4를 사용했습니다. 다른 버전은 자체적으로 확인하여 수정하세요.
라즈베리 파이 4 GPIO 핀 설명: https://url.zeruns.com/RPI4_GPIO
DHT11 라즈베리 파이
VCC---------5V (2번 핀)
DATA-------BCM18 (BCM 번호 18번 핀, 즉 12번 핀)
GND--------Ground (6번 핀)
소스 코드:
import RPi.GPIO as GPIO
import time
def delayMicrosecond(t): # 마이크로초 단위 지연 함수
start,end=0,0 # 변수 선언
start=time.time() # 시작 시간 기록
t=(t-3)/1000000 # 입력 t를 초 단위로 변환, -3은 시간 보정
while end-start<t: # 시간 차이가 설정값 이상이 될 때까지 반복
end=time.time() # 종료 시간 기록
tmp=[] # 읽은 데이터를 저장할 리스트
data = 18 # DHT11의 DATA 핀이 연결된 라즈베리 파이 GPIO 핀 (BCM 번호 사용)
# https://blog.zeruns.com
a,b=0,0
def DHT11():
GPIO.setup(data, GPIO.OUT) # GPIO 핀을 출력 모드로 설정
GPIO.output(data,GPIO.HIGH) # GPIO 출력을 고전압으로 설정
delayMicrosecond(10*1000) # 10밀리초 지연
GPIO.output(data,GPIO.LOW) # GPIO 출력을 저전압으로 설정
delayMicrosecond(25*1000) # 25밀리초 지연
GPIO.output(data,GPIO.HIGH) # GPIO 출력을 고전압으로 설정
GPIO.setup(data, GPIO.IN) # GPIO 핀을 입력 모드로 설정
# https://blog.zeruns.com
a=time.time() # 루프 시작 시간 기록
while GPIO.input(data): # 입력이 저전압이 될 때까지 반복
b=time.time() # 종료 시간 기록
if (b-a)>0.1: # 루프 시간이 0.1초를 초과하지 않았는지 확인 (무한 루프 방지)
break # 루프 탈출
a=time.time()
while GPIO.input(data)==0: # 입력이 고전압이 될 때까지 반복
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data): # 입력이 저전압이 될 때까지 반복
b=time.time()
if (b-a)>=0.1:
break
for i in range(40): # 40번 반복하여 온습도 데이터 수신
a=time.time()
while GPIO.input(data)==0: # 입력이 고전압이 될 때까지 반복
b=time.time()
if (b-a)>0.1:
break
# https://blog.zeruns.com
delayMicrosecond(28) # 28마이크로초 지연
if GPIO.input(data): # 28마이크로초 후에도 여전히 고전압인지 확인
tmp.append(1) # 수신된 비트를 1로 기록
a=time.time()
while GPIO.input(data): # 입력이 저전압이 될 때까지 반복
b=time.time()
if (b-a)>0.1:
break
else:
tmp.append(0) # 수신된 비트를 0으로 기록
while True:
GPIO.setmode(GPIO.BCM) # BCM 번호 모드 설정
GPIO.setwarnings(False)
del tmp[0:] # 리스트 초기화
time.sleep(1) # 1초 지연
# https://blog.zeruns.com
DHT11()
humidity_bit=tmp[0:8] # 리스트 분할: 0~7비트는 습도 정수 데이터
humidity_point_bit=tmp[8:16]# 습도 소수점
temperature_bit=tmp[16:24] # 온도 정수
temperature_point_bit=tmp[24:32] # 온도 소수점
check_bit=tmp[32:40] # 검사 비트
humidity_int=0
humidity_point=0
temperature_int=0
temperature_point=0
check=0
# https://blog.zeruns.com
for i in range(8): # 이진수를 십진수로 변환
humidity_int+=humidity_bit[i]*2**(7-i)
humidity_point+=humidity_point_bit[i]*2**(7-i)
temperature_int+=temperature_bit[i]*2**(7-i)
temperature_point+=temperature_point_bit[i]*2**(7-i)
check+=check_bit[i]*2**(7-i)
humidity=humidity_int+humidity_point/10
temperature=temperature_int+temperature_point/10
check_tmp=humidity_int+humidity_point+temperature_int+temperature_point
if check==check_tmp and temperature!=0 and temperature!=0: # 데이터 정상 여부 확인
print("Temperature is ", temperature,"C\nHumidity is ",humidity,"%")# 온습도 데이터 출력
print("https://blog.zeruns.com")
else:
print("error")
time.sleep(1)
GPIO.cleanup()
실행 결과
추천 읽기
- 가성비 높고 저렴한 VPS/클라우드 서버 추천: https://blog.zeruns.com/archives/383.html
- Python 관련 기사: https://blog.zeruns.com/category/Python/
- Arduino로 DHT11, DHT22, SHTC3 온습도 데이터 읽기: https://blog.zeruns.com/archives/527.html
- 학생 전용 할인 혜택 전체: 교육 할인: https://blog.zeruns.com/archives/557.html
- 개인 블로그 구축 방법: https://blog.zeruns.com/archives/218.html
- ESP8266 개발 환경 구축 및 프로젝트 데모: https://blog.zeruns.com/archives/526.html


