树莓派读取DHT11分析

在物联网时代,用的最多的是啥?传感器。
相信大家都入手过不少传感器。,DHT11作为一款比较常用的温湿度传感器,估计没有人会说没听过,不会用,最近我带儿子玩树莓派的时候发现了一个问题,那就是网上使用树莓派读取DHT11的python代码同质化太严重,而且说是给树莓派使用的,但实际上每段代码只适合少许型号的树莓派使用。例如:

 这段代码在树莓派3b上工作的不错,但是在树莓派4b上就完全不能用了,读出的结果为255(全1)。

对照Datasheet我们很容易分析出原因,考虑申请原创,这里就不大段抄文了,简单说一下原理,在读取数据的时候,如果有一个较长时间的持续高电平,读取此位为1,否则就是0。如下:


根据手册来说:“0”的高电位持续时间是26~28us,“1”的高电位持续时间是70us。在上面的代码中,是以循环是否超过8次作为该位0、1的区分,这是树莓派3b中比较适合的数字了(相信也是反复试验出来的)。
但因为不同树莓派的SoC主频不同,显然如果换一款树莓派(比如树莓派4b)这个数值肯定是需要根据实际修改的,将其循环次数k记录下来:
[7, 8, 8, 25, 25, 8, 8, 9, 8, 8, 8, 9, 8, 8, 9, 8, 8, 8, 8, 26, 26, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 24, 24, 8, 8, 8, 8]
从数值上来看7、8、9应该是0,24、25、26应该是1,那么直接把刚才的代码第25行改成if k<15:再尝试,根据传感器的要求,每次读取时间间隔超过1s,多次读取,发现大多数时候读取的结果是正确的,但也有错得比较离谱的情况:


这是为什么呢?
其实原因很简单,树莓派的SoC工作频率并不固定,因此循环周期也是不同的,以树莓派4b为例,它的频率可以在600MHz~1500MHz间变化。


这样,每次循环所用的时间肯定是有比较大差异的。
如果不用循环,直接读取两次时间差值是否可行呢?
经过验证,是可以的,使用time.time.time_ns()函数就行。但有个小小问题,python的效率比较低,在树莓派上,即使原始值是“0”(只有不到30us),经过两次调用这个函数并且做差值运算以后,花费的时间依然超过了70us。当然这并不是什么大问题,我们直接尝试将两次调用的时间相减(实测大概是50us),作为基础数值加到30us中,因此将上述循环计数改成时间计数:


在一定程度上可以抵御树莓派主频自动变化造成读数错误的风险。
实测,依然有一定出错概率。因此最合适的方案就是,多读几次,把校验错误和明显不符合常识的数值(比如湿度大于100)丢弃,这样结果相对准确。
代码很简单,这里就不献丑了,仅提出一个思路,请大家自行展开尝试。
---------------------
作者:tobot
链接:https://bbs.21ic.com/icview-3186340-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值