首页 编程教程正文

树莓派第四课之DHT11湿温度传感器

piaodoo 编程教程 2020-02-22 22:15:59 1532 0 python教程

本文来源吾爱破解论坛

第一课,温度传感器https://www.52pojie.cn/thread-902898-1-1.html
第二课,继电器https://www.52pojie.cn/thread-903925-1-1.html
第三课,舵机https://www.52pojie.cn/thread-911228-1-1.html

第四课,DHT11湿温度传感器终于来了

懒了这么久,今天把欠的账还还。第四课,DHT11温湿度传感器,话说有了这玩意可以做自动煮蛋器啊,呀呸,自动孵蛋器,孵蛋器。肉比蛋好吃嘛,呀呸,小动物那么可爱,怎么可以吃小动物,多放孜然,谢谢。


这一期呢,我试了几种不同的方式,最后发现还是网上流传的方式准确率比较高,但是数据读取错误率依旧有30%-50%左右,暂时没找到更好的解决方案,所以说,这期主要讲怎么使用树莓派进行高低电平通信的问题,实际使用中建议采用C语言。

放心,数据读取错误程序是会发现的,不会回传错误数据

解决高低电平通信问题,无非就是两点,发消息和收消息。
发消息上次讲了,GPIO.output(端口号, GPIO.HIGH/ GPIO.LOW)就可以设置引脚的高低电平了,上一节课已经学习过了。

GPIO.HIGH是高电平, GPIO.LOW是低电平。再用time.sleep(秒数)设置下暂停的时间,就能控制波形、频率等等。
如下例程:[Python] 纯文本查看 复制代码

# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO #引入GPIO模块,重命名为GPIO
import time #引入time模块
GPIO.setmode(GPIO.BCM) #设置gpio引脚编号模式,有两种编号模式可供选择,自己随意设置就好
GPIO.setup(13, GPIO.OUT) #设置13号口为输出模式
while True: #进入死循环
    GPIO.output(13, GPIO.HIGH) #13号口输出高电平
    time.sleep(0.02) #程序暂停0.02秒
    GPIO.output(13, GPIO.LOW) #13号口输出高电平
    time.sleep(0.02) #程序暂停0.02秒
GPIO.cleanup() #关闭所有端口


这样,程序在死循环里,每隔0.02秒就将电平翻转,那不就是周期为0.04秒的方波了吗。

这就是发送信号,很简单吗,但是怎么接收信号呢?

这时候同学们肯定发现,上面有一句这个[Python] 纯文本查看 复制代码
GPIO.setup(13, GPIO.OUT) #设置13号口为输出模式


那我把GPIO.OUT改为GPIO.IN不就行了。

似乎Python会帮我们处理一切心意,但是可以吗?我们先做测试。

我们初步设想是这样1.     将一个端口设置为接收模式。2.     编写一个程序,输出这个模式接收到的信息。3.     我们手动将该端口接到高低电平上,观看效果。

好的,那我们就来试试吧。[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO #引入GPIO模块,重命名为GPIO
import time
GPIO.setmode(GPIO.BCM) #设置gpio引脚编号模式,有两种编号模式可供选择,自己随意设置就好
GPIO.setup(6, GPIO.IN) #设置6号口为输入模式
print(GPIO.input(6)) #输出6号口的状态


启动!
我们发现,我们将6号口置于高电平,则显示是1,置于低电平则显示是0.那么,我们成功了吗?
我们修改下程序,让他不断去侦测,显示。[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO #引入GPIO模块,重命名为GPIO
import time
GPIO.setmode(GPIO.BCM) #设置gpio引脚编号模式,有两种编号模式可供选择,自己随意设置就好
GPIO.setup(6, GPIO.IN) #设置13号口为输出模式
while True:
    print(GPIO.input(6))


运行后我们发现,程序会非常快速的输出,即使你的电平没有变化,他依然是快速输出。比如你置为高电平,则一直输出1,以最快速的方式

其中将6号口悬空,会发生误判断,则随机显示0或1。

好了,我们继续修改测试程序,让他无变化则不显示。[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO #引入GPIO模块,重命名为GPIO
import time
GPIO.setmode(GPIO.BCM) #设置gpio引脚编号模式,有两种编号模式可供选择,自己随意设置就好
GPIO.setup(6, GPIO.IN) #设置13号口为输出模式
while True:
    i=GPIO.input(6)
    if i != GPIO.input(6):
        print(GPIO.input(6))
        i=GPIO.input(6)

这样的话,只有在端口发生变化的时候才显示,果然不错。

好了,基础学会了,我们去了解下DHT11传感器的通信方式吧。

啥是DHT11传感器?

1.jpg (70.59 KB, 下载次数: 1)

下载附件  保存到相册

2019-4-12 13:24 上传



估价的话5-6元
它能够测量环境里的温度,湿度数据

DHT11建议每次查询数据的间隔时间要大于2秒钟,否则可能会出现数据不准确的情况。


首先由主机发送起始信号,起始信号为低电平,时间大于18ms

然后传感器开始应答,先输出80μs的低电平,然后输出80μs的高电平,提醒主机准备接收信号。

随后传感器开始传输数据,共发射四十位数据,前八位为温度数据整数位,再往后八位为温度数据小数位,再往后八位是湿度数据整数位,再往后八位是湿度数据小数位,再往后八位是校验位
数据0的表示方式为:50μs的低电平和 26-28μs的高电平。
数据1的表示方式为:50μs的低电平加 70μs的高电平。


校验方式为:
数据传送正确时校验和数据等于“ 8bit 湿度整数数据 +8bit 湿度小数数据+8bi 温度整数数据 +8bit 温度小数数据 ”所得结果的末8位。



说吧,现在多少人去厕所哭了。

网上有人给了一个点子,检测到低电平变为高电平后,开始进入循环,每循环一次就计数加一,如果输入是0,计数会少些,如果输入是1,计数会多些。
经过测试,输入是0时,计数往往低于8次,计数是1时,计数往往多于8次,如此就可以断别。

哦,对了,1秒=1,000,000微秒。

所以,1微秒等于0.000001秒。

对了,上面的参数哪里去挖?后山去挖,可以去网上百度该模块的技术手册,也可以去找淘宝卖家要。

这一次的流程比较复杂,大家注意看流程图

哇,夭寿了,因为用户组限制,这次流程图太大了,传不上去啊,压缩了还看个毛啊,全模糊了怎么看。

流程图和代码一起传了百度网盘,大家去那看吧。

好了,流程图看好了以后,大家心里大概已经清楚了,代码基本上每一步都有注释,大家可以看下。
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO #引入GPIO模块,重命名为GPIO
import time#引入时间模块
channel=6#设置端口号
j=0#初始化计数器为0
data=[]#初始化数据存储数组

GPIO.setmode(GPIO.BCM) #设置gpio引脚编号模式,有两种编号模式可供选择,自己随意设置就好
time.sleep(1)#程序暂停一秒钟
GPIO.setup(channel, GPIO.OUT) #设置6号口为输出模式
GPIO.output(channel, GPIO.LOW)#6号口输出低电平,即发送触发信号
time.sleep(0.02)#低电平维持0.02秒
GPIO.output(channel, GPIO.HIGH)#输出高电平,标志低电平结束
GPIO.setup(channel, GPIO.IN)#设置端口模式为输入
while GPIO.input(channel)==GPIO.LOW:#跳过初始状态的低电平
    pass
while GPIO.input(channel)==GPIO.HIGH:#跳过初始状态的高电平
    pass

#进入循环
while j < 40:#仅仅存储40个数据
	k = 0
	while GPIO.input(channel) == GPIO.LOW:#跳过低电平
		continue
	
	while GPIO.input(channel) == GPIO.HIGH:#如果是高电平,则进入循环,高电平结束时停止
		k += 1#计数器自增
		if k > 100:#如果高电平计数器大于100,则跳出循环,数据错误
			break
	
	if k < 8:#如果计数器数值小于8次,则认为值为0
		data.append(0)
	else:#否则认为值为1
		data.append(1)
 
	j += 1#数据位数计数器加一

#按位切割数据
humidity_bit = data[0:8]
humidity_point_bit = data[8:16]
temperature_bit = data[16:24]
temperature_point_bit = data[24:32]
check_bit = data[32:40]
 
humidity = 0
humidity_point = 0
temperature = 0
temperature_point = 0
check = 0

#计算各个数据结果和校验值
for i in range(8):
	humidity += humidity_bit[i] * 2 ** (7 - i)
	humidity_point += humidity_point_bit[i] * 2 ** (7 - i)
	temperature += temperature_bit[i] * 2 ** (7 - i)
	temperature_point += temperature_point_bit[i] * 2 ** (7 - i)
	check += check_bit[i] * 2 ** (7 - i)
#计算检查值
tmp = humidity + humidity_point + temperature + temperature_point

 
if check == tmp:
    print('数据正确')
    print("温度: "+str(temperature)+", 湿度: "+str(humidity))
else:
	print('数据错误')
	print("温度: "+str(temperature)+",湿度: "+str(humidity)+"校验值: "+str(check)+" 检查值: "+str(tmp))
 
GPIO.cleanup()



这时候可能有人已经要跳出来喊,你是抄袭的。事实上,我并不是抄袭,我引用了网上主流的代码,对其加以修改和注释,其原版仅仅能够在python2.X版本下运行,我将其升级到了python3,同时完善了注释和流程解释。可以说,当前互联网上针对于这个代码最详细,最准确的教程就在我这了。相信意义党也应该觉得这次教程编写的有意义吧。

因为网上对该代码抄袭严重,质量参差不齐,实在难以找到原作者是谁,故无法声明原作者的原著链接,但在此对原作者表示感谢。本次教程本人不声明版权,大家可以引用转载。

流程图和代码都在这里:链接:https://pan.baidu.com/s/13hHWYNpaxhjUlDN1DnKlUw 提取码:jkk8

这里只有代码,流程图放压缩包就超过用户组限制了…… 嗨学网 DHT11.zip (1.19 KB, 下载次数: 4) 2019-4-12 13:32 上传 点击文件名下载附件
下载积分: 吾爱币 -1 CB


愤怒,愤怒,图片传不上去好痛苦,严重影响教程质量,希望吾爱的文件大小限制放宽些,太痛苦了这样。

版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:https://www.piaodoo.com/8032.html

搜索