傳感器概述
DHT11是一款有已校準數字信號輸出的溫濕度傳感器。 其精度濕度±5%RH, 溫度±2℃,量程濕度20-90%RH, 溫度0~50℃。分為3個接口,分別為:VCC, DATA, GND。
產品圖片
主要用途
檢測環境溫濕度
GPIO控制DHT11溫濕度傳感器實操
引腳接線
我用的是三個頭的dht11傳感器,因此連線方式是:
VCC(或正極) — 樹莓派的3v電源
GND (地線或者負極)— 樹莓派的gnd接口
DATA (D或者out) —樹莓派的GPIO引腳
1.VCC接上3V,可以選擇1口或者17口
2.DATA接上GPIO口,我選的是GPIO4,第7口
3.GND接上接地口,我選的是第14口
模塊原理圖
硬件連接
硬件只涉及樹莓派、DHT11傳感器。
DHT11的信號引腳連接樹莓派的GPIO17, DHT11的Vdd(+)和GND引腳(-)分別連接樹莓派的電源正極和GND引腳。
實際線路
安裝 Python3
本項目使用 Python3 進行開發,一般情況下,樹莓派系統會內置 Python3,如果不確定系統內是否已經安裝,可以使用下面的命令進行確認。
python3 --version
如果顯示 Python 3.x.x(x 表示數字)則表示已經安裝,否則請使用 apt 命令安裝
sudo apt install python3
從源代碼編譯安裝python3.9
如果你需要安裝的Python版本不在apt倉庫中,你可以從源代碼編譯安裝。
wget https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tar.xz
tar -xf Python-3.9.1.tar.xz
cd Python-3.9.1
./configure --enable-optimizations
make -j 4
sudo make altinstall
使用altinstall可以避免與系統自帶的Python版本沖突。
使用Pyenv管理Python版本
管理多個Python版本,可以使用pyenv。需要安裝pyenv和pyenv-virtualenv:
1、安裝依賴項:
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
2、安裝pyenv:
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
3、配置環境變量(將以下內容添加到你的/.bashrc或/.profile文件中):
export PATH="HOME/.pyenv/bin:PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
4、重新加載配置文件:
source ~/.bashrc
5、使用pyenv安裝最新版本的Python:
pyenv install -l # 查看可用的Python版本
pyenv install 3.9.0 # 安裝特定版本,例如3.9.0,
或者使用最新的穩定版號,如 pyenv install 3.9 或 pyenv install 3.10 等。
pyenv global 3.9.0 # 設置全局Python版本為3.9.0,或者使用最新的穩定版號。
Adafruit DHT庫下載
sudo apt-get install git-core
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
sudo apt-get install build-essential python-dev
sudo python3 setup.py install
注:安裝失敗,Adafruit_Python_DHT庫無法安裝成功,樹莓派4b主板不支持。
關于虛擬環境
所謂虛擬環境是在python中把我們環境做成一個沙箱,不跟其他環境沖突。
另外,在類似樹莓派這樣的環境中不允許直接安裝python的庫,我們又需要用這些庫,我們可以安裝一個python的虛擬環境,由于虛擬環境不會影響外部環境,所以我可以在虛擬環境中安裝python庫。
python的虛擬環境安裝步驟:
#創建一個文件夾用來安裝虛擬環境:
mkdir adafruit_env
cd adafruit_env
安裝虛擬環境:
sudo apt-get install python3-venv
創建虛擬環境:
python3 -m venv adafruit_env
激活虛擬環境:
source adafruit_env/bin/activate
退出虛擬環境:
deactivate
開啟樹莓派1-Wire接口
控制臺終端輸入命令
sudo raspi-config
選擇確認退出即可。
安裝adafruit-circuitpython-dht庫
先進入虛擬環境
使用pip安裝adafruit-circuitpython-dht庫。打開終端,然后輸入以下命令:
pip3 install adafruit-circuitpython-dht
GPIO控制傳感器讀取數據
編寫Python獲取溫濕度代碼,命名為demo1.py
代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import numpy as np
import time
import sys
DHTPIN = 17
GPIO.setmode(GPIO.BCM)
def read_dht11_dat():try:GPIO.setup(DHTPIN, GPIO.OUT)GPIO.output(DHTPIN, GPIO.LOW)time.sleep(0.02)GPIO.output(DHTPIN, GPIO.HIGH)GPIO.setup(DHTPIN, GPIO.IN)# Wait for sensor responsetimeout = time.time() + 0.1while GPIO.input(DHTPIN) == GPIO.LOW:if time.time() > timeout:raise RuntimeError("Sensor response timeout (LOW)")timeout = time.time() + 0.1while GPIO.input(DHTPIN) == GPIO.HIGH:if time.time() > timeout:raise RuntimeError("Sensor response timeout (HIGH)")# Read 40 bits of datadata = []for _ in range(40):# Wait for start of bittimeout = time.time() + 0.001while GPIO.input(DHTPIN) == GPIO.LOW:if time.time() > timeout:raise RuntimeError("Bit start timeout")# Measure duration of high pulsestart = time.time()timeout = start + 0.001while GPIO.input(DHTPIN) == GPIO.HIGH:if time.time() > timeout:breakduration = time.time() - startdata.append(1 if duration > 0.00005 else 0)# Convert bits to valuesm = np.logspace(7, 0, 8, base=2, dtype=int)data_array = np.array(data)humidity = m.dot(data_array[0:8])humidity_point = m.dot(data_array[8:16])temperature = m.dot(data_array[16:24])temperature_point = m.dot(data_array[24:32])check = m.dot(data_array[32:40])tmp = humidity + humidity_point + temperature + temperature_pointif check == tmp and humidity + temperature < 1000: # Sanity checkreturn humidity, temperaturereturn Falseexcept Exception as e:print(f"Error reading sensor: {str(e)}", file=sys.stderr)return Falsedef main():print("Raspberry Pi DHT11 Temperature test program\n")time.sleep(1)try:while True:result = read_dht11_dat()if result:humidity, temperature = resultprint(f"humidity: {humidity}%, Temperature: {temperature}C\n")else:print("Data are wrong, skip\n")time.sleep(1)except KeyboardInterrupt:passdef destroy():GPIO.cleanup()if __name__ == '__main__':try:main()finally:destroy()
運行腳本程序
可以看到humidity 和 Temperature數據打印在控制臺。