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)

更多推荐