本文来源吾爱破解论坛
第一课,温度传感器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)
下载附件 保存到相册
估价的话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
这里只有代码,流程图放压缩包就超过用户组限制了……
下载积分: 吾爱币 -1 CB
愤怒,愤怒,图片传不上去好痛苦,严重影响教程质量,希望吾爱的文件大小限制放宽些,太痛苦了这样。
版权声明:
本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。