樹莓派處理溫溼度監控,紅外蔽障傳感器,超聲波測距傳感器,激光傳感器,有害氣體檢測,人體感應器,傾斜開關,雨滴傳感器,土壤監測

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章