DHT11數字溼溫度傳感器
1.性能指標和特性:
工作電壓範圍:3.5V-5.5V
工作電流:平均0.5mA
溼度測量範圍:20-90%RH
溫度測量範圍:0-50℃
溼度分辨率:1%RH 8 位
溫度分辨率:1℃ 8位
採樣週期:1S
2.DHT11 數據結構
DHT11數字溼溫度傳感器採用單總線數據格式。即,單個數據引腳端口完成輸
入輸出雙向傳輸。其數據包由5Byte(40Bit)組成。數據分小數部分和整數部分,具
體格式在下面說明。
一次完整的數據傳輸爲40bit,高位先出。
數據格式:8bit溼度整數數據+8bit溼度小數數據
+8bit溫度整數數據+8bit溫度小數數據
+8bit校驗和
校驗和數據爲前四個字節相加。
傳感器數據輸出的是未編碼的二進制數據。數據(溼度、溫度、整數、小數)之間
應該分開處理。如果,某次從傳感器中讀取如下5Byte數據:
byte4 byte3 byte2 byte1 byte0
00101101 00000000 00011100 00000000 01001001
整數 小數 整數 小數 校驗和
溼度 溫度 校驗和
由以上數據就可得到溼度和溫度的值,計算方法:
humi (溼度)= byte4 . byte3=45.0 (%RH)
temp (溫度)= byte2 . byte1=28.0 ( ℃)
jiaoyan(校驗)= byte4+ byte3+ byte2+ byte1=73(=humi+temp)(校驗正確)
注意:DHT11一次通訊時間最大3ms,主機連續採樣間隔建議不小於100ms。
使用公對公杜邦線直接與樹莓派連接:
DHT11的正極(+/VCC)連接4號引腳(5V);數據腳連接18號引腳(BCM 24);負極(-/GND)連接20號引腳(GND)。*注意勿將正負極接反,模塊會燒燬。
使用Adafruit 讀取DHT11 溫溼度傳感器
- 更新軟件包
sudo apt-get update
sudo apt-get install build-essential python-dev
- 從GitHub獲取Adafruit庫
sudo git clone
https://github.com/adafruit/Adafruit_Python_DHT.git
- 安裝完成後pi文件夾下新增Adafruit_Python_DHT文件夾,進入該文件夾安裝該庫。
cd Adafruit_Python_DHT
sudo python setup.py install
sudo python3 setup.py install
- 安裝完成後進入examples文件夾運行AdfruitDHT.py可以獲得結果。
cd examples
Python AdafruitDHT.py 11 24
*後面兩個數值11代表使用的是DHT11模塊,24代表着所接的GIPO引腳編號(BCM)。
---------------------------------------------------
手頭上正好有一個紅外蔽障傳感器,只爲測試簡單的接法:BCM=4 3.3v
#!/usr/bin/python
#-*-coding:utf-8-*-
import time
import RPi.GPIO as GPIO
import os
GPIO.setmode(GPIO.BCM)
GPIO_OUT=4
GPIO.setup(GPIO_OUT,GPIO.IN)
a=1
def warn():
print(a)
time.sleep(0.5)
while True:
if GPIO.input(GPIO_OUT)==0:
warn()
else:
print("i'm OK!!!")
GPIO.cleanup()
-----------------------------------------------------------------------------------------------
超聲波測距傳感器HC-SR04
import RPi.GPIO as GPIO
import time
Trig_Pin=20
Echo_Pin=21
GPIO.setmode(GPIO.BCM)
GPIO.setup(Trig_Pin,GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(Echo_Pin,GPIO.IN)
time.sleep(2)
def checkdist():
GPIO.output(Trig_Pin,GPIO.HIGH)
time.sleep(0.00015)
GPIO.output(Trig_Pin,GPIO.LOW)
while not GPIO.input(Echo_Pin):
pass
t1=time.time()
while GPIO.input(Echo_Pin):
pass
t2=time.time()
return (t2-t1)*340*100/2
try:
while True:
print "Distance:%0.2f cm" % checkdist()
time.sleep(1)
except KeyboardInterrupt:
GPIO.cheanup()
--------------------------------------------------------------------------------------------------------------
激光傳感器KY-008,寫個簡單的範例:當超聲測距低於20cm時打開激光槍
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
Trig_Pin=20
Echo_Pin=21
JiGuang_Pin=4
GPIO.setup(Trig_Pin,GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(Echo_Pin,GPIO.IN)
GPIO.setup(JiGuang_Pin,GPIO.OUT,initial=GPIO.LOW)
time.sleep(2)
def checkdist():
GPIO.output(Trig_Pin,GPIO.HIGH)
time.sleep(0.00015)
GPIO.output(Trig_Pin,GPIO.LOW)
while not GPIO.input(Echo_Pin):
pass
t1=time.time()
while GPIO.input(Echo_Pin):
pass
t2=time.time()
return (t2-t1)*340*100/2
def open():
GPIO.output(JiGuang_Pin,GPIO.HIGH)
time.sleep(0.5)
GPIO.output(JiGuang_Pin,GPIO.LOW)
time.sleep(0.5)
while True:
d1=checkdist()
print "Distance:%0.2f cm" % d1
time.sleep(1)
if d1<20:open()
GPIO.cheanup()
------------------------------------------------------------------------------------------
MQ-2有害氣體檢測傳感器
Python的GPIO庫只能接受引腳的高低電平的變化,因此只需要接線三個引腳就好:5V電源,地線,和DO接口,這是一款廣泛應用於家庭和工廠的氣體泄漏檢測裝置,適用於液化氣、甲烷、丙烷、丁烷、酒精、氫氣、煙霧等有害氣體的檢測。
#! /usr/bin/env python3
# encoding=utf-8
import RPi.GPIO as GPIO # 導入庫,並進行別名的設置
import time
CHANNEL=20 # 確定引腳口。按照真實的位置確定
GPIO.setmode(GPIO.BCM) # 選擇引腳系統,這裏我們選擇了BCM,也可以換BOARD
GPIO.setup(CHANNEL,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)
#初始化引腳,將引腳設置爲輸入下拉電阻,因爲在初始化的時候不確定的的引電平,因此這樣設置是用來保證精準,(但是也可以不寫“pull_up_down=GPIO.PUD_DOWN”)
# 帶有異常處理的主程序
try:
while True: # 執行一個while死循環
status=GPIO.input(CHANNEL) # 檢測引腳口的輸入高低電平狀態
#print(status) # 實時打印此時的電平狀態
if status == True: # 如果爲高電平,說明MQ-2正常,並打印“OK”
print ( ' 正常 ' )
else: # 如果爲低電平,說明MQ-2檢測到有害氣體,並打印“dangerous”
print ( ' 檢測到危險氣體 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ' )
time.sleep(0.1) # 睡眠0.1秒,以後再執行while循環
except KeyboardInterrupt: # 異常處理,當檢測按下鍵盤的Ctrl+C,就會退出這個>腳本
GPIO.cleanup() # 清理運行完成後的殘餘
HC-SR501人體感應模塊
代碼實例:感應到有人,二極管點亮
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(13, GPIO.OUT) #hc-sr501-out
GPIO.setup(7, GPIO.IN) #led
while True:
if GPIO.input(7)==1:
nowtime = time.strftime('%m-%d %H:%M:%S',time.localtime(time.time()))
print(nowtime)
print("狼來了!")
GPIO.output(13,GPIO.HIGH)
else:
pass
time.sleep(0.5)
GPIO.output(13,GPIO.LOW)
time.sleep(5)
傾斜傳感器
#!/usr/bin/env python
import RPi.GPIO as GPIO
TiltPin = 11 #YL-38
Rpin = 12 #led-red
Gpin = 13 #led-gren
def setup():
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(Gpin, GPIO.OUT) # Set Green Led Pin mode to output
GPIO.setup(Rpin, GPIO.OUT) # Set Red Led Pin mode to output
GPIO.setup(TiltPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set BtnPin's mode is input, and pull up to high level(3.3V)
GPIO.add_event_detect(TiltPin, GPIO.BOTH, callback=detect, bouncetime=200)
def Led(x): #控制雙色LED燈閃爍的函數
if x == 0:
GPIO.output(Rpin, 1) #紅燈亮
GPIO.output(Gpin, 0) #綠燈滅
if x == 1:
GPIO.output(Rpin, 0)
GPIO.output(Gpin, 1)
def Print(x): #打印按鍵是否傾斜的提示消息
if x == 0:
print ' *************'
print ' * Tilt! *'
print ' *************'
def detect(chn):
Led(GPIO.input(TiltPin)) #控制雙色LED燈閃爍
Print(GPIO.input(TiltPin)) #打印按鍵是否傾斜的提示消息
def loop():
while True:
pass
def destroy():
GPIO.output(Gpin, GPIO.LOW) # Green led off
GPIO.output(Rpin, GPIO.LOW) # Red led off
GPIO.cleanup() # Release resource
if __name__ == '__main__': # Program start from here
setup()
try:
loop()
except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
destroy()
雨滴傳感器(數字信號)
import RPi.GPIO as GPIO
import time
GPIO.setmod(GPIO.BCM)
GPIO.setup(4,GPIO.IN)
while True:
if GPIO.input(4):
print("no rain")
else:
print("rain")
time.sleep(1)
土壤溼度檢測傳感器
獲取溼度信息的方式(2種可同時使用):
從傳感器的D0引腳:土壤溼度大於某個閾值,則D0輸出0,否則輸出1
從傳感器的A0引腳:獲取到模擬量,更加精確。土壤溼度越大,獲取的模擬量值越大。
樹莓派使用D0
#!/usr/bin/python
#coding=utf-8
import RPi.GPIO as GPIO
import time
#針腳
channel = 21
GPIO.setmode(GPIO.BCM)
#定義針腳爲input口
GPIO.setup(channel, GPIO.IN)
#回調函數
def callback(channel):
if GPIO.input(channel):
print ('土壤有點幹')
else:
print ('土壤太溼了')
#添加簡單事件
GPIO.add_event_detect(channel, GPIO.BOTH, bouncetime=200)
#添加時間觸發的回調函數
GPIO.add_event_callback(channel, callback)
#保持主進程不退出
while True:
time.sleep(0.1)
ESP32單片機micropython:數字量輸出
from machine import Pin
import time
tr=23
g23 = Pin(tr, Pin.IN) #土壤23信號
def callback(tr):
if g23.value()==1:
print('太乾了')
else:
print('太溼了')
while 1:
time.sleep(1)
callback(tr)
ESP32單片機micropython:模擬量輸出
擴展:
————————————————————————————————————
有多種方式將GPIO的輸入導入到程序中,polling( 輪詢 )式 和 interrupt( 中斷 )式( edge detection 邊緣檢測 ),“輪詢”式如果程序在錯誤的時間讀取值,可能會錯過輸入。我們這裏採用中斷式。
如果您沒有將輸入引腳連接到任何東西,它將“浮動”。換句話說,讀取的值是未定義的,因爲它沒有連接到任何東西,直到你按下按鈕或開關。它可能會由於接收電源干擾而改變很大的值。
爲了解決這個問題,我們使用一個向上拉或向下拉電阻器。這樣,就可以設置輸入的默認值。可以使用硬件或者軟件實現上下拉電阻。在硬件方式中,常常在輸入通道與3.3V(上拉)或0V(下拉)之間使用10K電阻。GPIO模塊允許您在編程中這樣配置:
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
我們很多時候並不關心電平值, 而關心電平從低到高,或從高到低的變化(如編碼器測速/按鍵按下彈開等), 爲避免主程序忙於其它事情錯過引腳的電平改變, 有兩種方式:
wait_for_edge() 函數
event_detected() 函數
wait_for_edge()函數是爲了阻止程序的執行,直到檢測到邊緣爲止。換句話說,等待按鈕按下的示例可以改寫成:
GPIO.wait_for_edge(channel, GPIO.RISING)
注意檢測的邊緣參數有 GPIO.RISING, GPIO.FALLING , GPIO.BOTH (上升沿, 下降沿 或 升降沿), 這樣用幾乎不佔用CPU,如果你只希望在確定的時間段內查詢,可以使用 timeout 參數:
# wait for up to 5 seconds for a rising edge (timeout is in milliseconds)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
print('Timeout occurred')
else:
print('Edge detected on channel', channel)
event_detected()函數被設計用來與其他事物一起在循環中使用, 不同於polling輪詢, 它不會在CPU忙於處理其他事物時錯過輸入狀態的變化。 這使得使用Pygame 或 PyQt 時非常有用,因爲其中有一個主循環監聽和及時響應GUI事件的基礎。
只要檢測到指定參數的邊緣事件(上升沿, 下降沿 或 升降沿)發生時,調用GPIO.event_detected(channel)的值就爲"ture"(真)。
#Note that you can detect events for GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):
print('Button pressed')
不過需要自己新建一個線程去循環檢測event_detected()的值,還算是比較麻煩的。
可採用另一種辦法輕鬆檢測狀態,這種方式是直接傳入一個回調函數:GPIO通過在add_event_detect()函數中添加callback參數,RPI.GPIO爲回調函數運行第二個線程。這意味着回調函數可以與主程序同時運行,以立即響應邊緣。
例如:
def my_callback(channel):
print('This is a edge event callback function!')
print('Edge detected on channel %s'%channel)
print('This is run in a different thread to your main program')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)
# 這裏添加了回調函數callback這個參數,就不需要GPIO.event_detected(channel)函數了
如果你想要不止一個回調函數:
def my_callback_one(channel):
print('Callback one')
def my_callback_two(channel):
print('Callback two')
GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)
請注意,在這種情況下,回調函數是按順序運行的,而不是併發的。這是因爲只有一個線程用於回調,其中每個回調都按照它們被定義的順序運行。
由於存在開關抖動(用示波器可以看到),每次按下開關會調用多次回調函數,這不是我們希望的,有兩種方式處理開關抖動:
①在開關兩個引腳之間添加一個0.1uF的電容
②軟件消抖
③二者結合使用
使用軟件消抖時, 給回調函數添加一個彈跳時間的參數( bouncetime= ), 彈跳時間(參照單片機可以爲10~20ms)在ms級別, 下面的程序用200ms來消抖:
# add rising edge detection on a channel, ignoring further edges for 200ms for switch bounce handling
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)
由於某些原因, 你的程序可能不希望用邊緣檢測了,可以停止它們:
GPIO.remove_event_detect(channel)