Sử dụng Raspberry Pi 4 để đọc dữ liệu từ cảm biến nhiệt độ và độ ẩm DHT11 qua GPIO bằng Python
Giới thiệu
DHT11 là một cảm biến nhiệt độ và độ ẩm có đầu ra tín hiệu số đã được hiệu chuẩn. Độ chính xác về độ ẩm là ±5% RH, nhiệt độ là ±2°C, phạm vi đo độ ẩm từ 20-90% RH, nhiệt độ từ 0~50°C. Độ chính xác không cao nhưng giá thành rẻ. DHT11 sử dụng giao thức một dây (single bus). Điện áp cấp là 3.3~5V.
Đọc dữ liệu nhiệt độ và độ ẩm từ DHT11, DHT22, SHTC3 bằng Arduino: https://blog.zeruns.com/archives/527.html
Phương pháp tạo độ trễ vi giây trong Python: https://blog.zeruns.com/archives/623.html
Đường dẫn tải tài liệu kỹ thuật DHT11: https://url.zeruns.com/DHT11 Mã rút gọn: qefk
Mã nguồn
Kết nối mạch:
Tôi sử dụng Raspberry Pi 4, các phiên bản khác vui lòng tự tra cứu và điều chỉnh.
Giới thiệu chân GPIO của Raspberry Pi 4: https://url.zeruns.com/RPI4_GPIO
DHT11 Raspberry Pi
VCC---------5V (chân số 2)
DATA-------BCM18 (chân số 18 theo BCM, tương đương chân số 12)
GND--------Ground (chân số 6)
Mã nguồn:
import RPi.GPIO as GPIO
import time
def delayMicrosecond(t): # Hàm trễ vi giây
start,end=0,0 # Khai báo biến
start=time.time() # Ghi lại thời điểm bắt đầu
t=(t-3)/1000000 # Chuyển đổi đơn vị t sang giây, -3 là bù thời gian
while end-start<t: # Lặp cho đến khi chênh lệch thời gian lớn hơn hoặc bằng giá trị đặt
end=time.time() # Ghi lại thời điểm kết thúc
tmp=[] # Dùng để lưu dữ liệu đọc được
data = 18 # Chân DATA của DHT11 kết nối với chân GPIO của Raspberry Pi, sử dụng mã BCM
# https://blog.zeruns.com
a,b=0,0
def DHT11():
GPIO.setup(data, GPIO.OUT) # Thiết lập chân GPIO ở chế độ đầu ra
GPIO.output(data,GPIO.HIGH) # Đặt chân GPIO ở mức cao
delayMicrosecond(10*1000) # Trễ 10 miligiây
GPIO.output(data,GPIO.LOW) # Đặt chân GPIO ở mức thấp
delayMicrosecond(25*1000) # Trễ 25 miligiây
GPIO.output(data,GPIO.HIGH) # Đặt chân GPIO ở mức cao
GPIO.setup(data, GPIO.IN) # Thiết lập chân GPIO ở chế độ đầu vào
# https://blog.zeruns.com
a=time.time() # Ghi lại thời điểm bắt đầu vòng lặp
while GPIO.input(data): # Lặp liên tục cho đến khi đầu vào ở mức thấp
b=time.time() # Ghi lại thời điểm kết thúc
if (b-a)>0.1: # Kiểm tra xem thời gian lặp có vượt quá 0.1 giây không, tránh treo chương trình
break # Thoát khỏi vòng lặp
a=time.time()
while GPIO.input(data)==0: # Lặp liên tục cho đến khi đầu vào ở mức cao
b=time.time()
if (b-a)>0.1:
break
a=time.time()
while GPIO.input(data): # Lặp liên tục cho đến khi đầu vào ở mức thấp
b=time.time()
if (b-a)>=0.1:
break
for i in range(40): # Lặp 40 lần để nhận dữ liệu nhiệt độ và độ ẩm
a=time.time()
while GPIO.input(data)==0: # Lặp liên tục cho đến khi đầu vào ở mức cao
b=time.time()
if (b-a)>0.1:
break
# https://blog.zeruns.com
delayMicrosecond(28) # Trễ 28 vi giây
if GPIO.input(data): # Sau 28 vi giây, kiểm tra xem đầu vào vẫn ở mức cao không
tmp.append(1) # Ghi nhận bit nhận được là 1
a=time.time()
while GPIO.input(data): # Lặp liên tục cho đến khi đầu vào ở mức thấp
b=time.time()
if (b-a)>0.1:
break
else:
tmp.append(0) # Ghi nhận bit nhận được là 0
while True:
GPIO.setmode(GPIO.BCM) # Thiết lập chế độ BCM
GPIO.setwarnings(False)
del tmp[0:] # Xóa danh sách
time.sleep(1) # Trễ 1 giây
# https://blog.zeruns.com
DHT11()
humidity_bit=tmp[0:8] # Tách danh sách: bit 0-7 là dữ liệu độ ẩm nguyên
humidity_point_bit=tmp[8:16]# Độ ẩm thập phân
temperature_bit=tmp[16:24] # Nhiệt độ nguyên
temperature_point_bit=tmp[24:32] # Nhiệt độ thập phân
check_bit=tmp[32:40] # Dữ liệu kiểm tra
humidity_int=0
humidity_point=0
temperature_int=0
temperature_point=0
check=0
# https://blog.zeruns.com
for i in range(8): # Chuyển đổi nhị phân sang thập phân
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: # Kiểm tra dữ liệu có hợp lệ không
print("Nhiệt độ là ", temperature,"°C\nĐộ ẩm là ",humidity,"%")# In dữ liệu nhiệt độ và độ ẩm
print("https://blog.zeruns.com")
else:
print("lỗi")
time.sleep(1)
GPIO.cleanup()
Hình ảnh kết quả
Bài viết nên đọc
- Khuyến nghị VPS/máy chủ đám mây giá rẻ và hiệu quả: https://blog.zeruns.com/archives/383.html
- Các bài viết về Python: https://blog.zeruns.com/category/Python/
- Đọc dữ liệu nhiệt độ và độ ẩm từ DHT11, DHT22, SHTC3 bằng Arduino: https://blog.zeruns.com/archives/527.html
- Danh sách ưu đãi dành riêng cho sinh viên: https://blog.zeruns.com/archives/557.html
- Cách xây dựng blog cá nhân: https://blog.zeruns.com/archives/218.html
- Thiết lập môi trường phát triển ESP8266 và trình diễn dự án: https://blog.zeruns.com/archives/526.html


