【树莓派真好玩】九:实战操作 (DHT11温湿度测量以及简单的报警器)

in #hive-1050173 years ago

之前的章节我们学习了很多树莓派的基础知识,这节我们来进行一个小小的实战操作,使用树莓派以及DHT11测量温湿度,以及实现个简单的温湿度报警器。

20211112_102118.jpg

原本以为这个应该是这个狠容易的事,毕竟以前在Arduino上没少折腾DHT11,想必树莓派上应该不会麻烦多少,结果发现可能不麻烦,但是走了很多弯路呢,听我慢慢道来。

DHT11硬件连接

常见的DHT11有两种,一种是带电路板的(三针),一种是简单的DHT11模块(四针),其中四线的模块正面视图的第三只针脚没啥用。另外信号管脚需要上拉,电路板那种模块信号脚和VCC之间加了个10K的上拉电阻。

DHT11-Pinout-for-three-pin-and-four-pin-types-2.jpg

我用的是四针的模块,所以要自己加个上拉电阻,用面包板连接后实物图如下:
20211112_102147.jpg

安装支持库

其实我相信用GPIO Zero Python库也能实现,不过没有找到现成的封装,懒得去做移植,网上不少例子都是用的Adafruit_DHT的库,咱也试试。

安装啥的都没问题,结果发现运行时出一堆错误:

image.png

其中主要一条错误信息如下:

ImportError: cannot import name 'Beaglebone_Black_Driver' from 'Adafruit_DHT' (/usr/local/lib/python3.7/dist-packages/Adafruit_DHT/init.py)

我分析一下代码,是代码不支持树莓派4所导致的,网上看到一些修改方案,比如说这条:

...
elif match.group(1) == 'BCM2711':
    #Pi 4b
    return 3
else:
    return None

我觉得这个修改应该可行,不过搜索信息时发现,Adafruit_Python_DHT其实已经被adafruit放弃了:

This library has been deprecated! We are leaving this up for historical and research purposes but archiving the repository.

We are now only supporting the use of our CircuitPython libraries for use with Python.

所以还是不折腾这个了,用官方推荐的新库才是正道啊。

安装:

sudo pip3 install adafruit-circuitpython-dht
sudo apt-get install libgpiod2

示例代码

import time
import board
import adafruit_dht

# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT11(board.D4)

while True:
    try:
        # Print the values to the serial port
        temperature_c = dhtDevice.temperature
        temperature_f = temperature_c * (9 / 5) + 32
        humidity = dhtDevice.humidity
        print(
            "Temp: {:.1f} F / {:.1f} C    Humidity: {}% ".format(
                temperature_f, temperature_c, humidity
            )
        )

    except RuntimeError as error:
        # Errors happen fairly often, DHT's are hard to read, just keep going
        print(error.args[0])
        time.sleep(2.0)
        continue
    except Exception as error:
        dhtDevice.exit()
        raise error

    time.sleep(2.0)

以上代码来自这里并略作修改。

运行代码

将上述代码保存为dht11_test.py,并执行如下指令,就可以运行啦:

python3 dht11_test.py

这里列举一下我遇到的问题,避免大家踩坑。

踩坑一

弄完代码后,我随手使用如下指令运行:

python dht11_test.py

结果被提示:

  File "dht11_test.py", line 2, in <module>
    import board
ImportError: No module named board

检查了一下发现,这是因为我树莓派上有python2 和python3两个版本,支持库装的是python3版本,所以要用python3指令来执行。

踩坑二

使用python3执行指令后,出现了如下提示:

DHT sensor not found, check wiring

检查后,发现原来示例代码中使用的是GPIO 18,而我使用的是GPIO 4,所以要做对应的修改。将board.D18改为board.D4

踩坑三

执行后出现如下提示:

Received unplausible data. Try again.

这又是啥错误呢?莫非是我DHT11坏掉了?果断换枚DHT11,结果依旧失败。仔细检查代码,我才发现,原本示例代码中使用的是DHT22。所以需要将这句:

dhtDevice = adafruit_dht.DHT22(board.D4)

修改为:

dhtDevice = adafruit_dht.DHT11(board.D4)

执行效果

使用修改后的代码,运行效果如下:

image.png

哈,我书房的温湿度,还不错吧。

简单的报警器

接下来我们尝试给这个温湿度测量仪(这个测量仪有些昂贵,哈哈哈)加上一个报警功能。比如说当温度高于某一阈值,报警器就会哗哗哗地叫。

为了实现这个功能,我们首先要搞定蜂鸣器,这次我使用的是一枚有源蜂鸣器模块(无源的死活没搞定,我晕)。
20211112_102135.jpg

从上图可见,蜂鸣器模块有三个有用的管脚(NC无用):

  • SIG(信号、数据针脚)
  • VCC(+、正极)
  • GND(—、负极)

我们只需将VCC接到3.3V上,GND接到Ground上,SIG接任意GPIO就可以啦。我这里接的是GPIO 22。

连线后效果如图:
20211112_102118.jpg

以下为简单测试代码,让蜂鸣器哔哔哔叫5秒后关闭:

import time
from gpiozero import Buzzer

bz = Buzzer(22)
bz.beep(0.2, 0.1)
time.sleep(5)
bz.off()

其中beep函数声明如下:

beep(on_time=1, off_time=1, n=None, background=True)

我们也可以传入n值来控制beep的次数,比如这段代码让蜂鸣器响beep十次:

import time
from gpiozero import Buzzer

bz = Buzzer(22)
bz.beep(0.2, 0.1, 10)
time.sleep(5)

接下来将上述代码集成到温湿度的代码中,完整代码如下:

import time
import board
import adafruit_dht

from gpiozero import Buzzer
bz = Buzzer(22)

# Initial the dht device, with data pin connected to:
dhtDevice = adafruit_dht.DHT11(board.D4)

while True:
    try:
        # Print the values to the serial port
        temperature_c = dhtDevice.temperature
        temperature_f = temperature_c * (9 / 5) + 32
        if temperature_c >= 30.0:
            bz.beep(0.2, 0.1, 10)

        humidity = dhtDevice.humidity
        print(
            "Temp: {:.1f} F / {:.1f} C    Humidity: {}% ".format(
                temperature_f, temperature_c, humidity
            )
        )

    except RuntimeError as error:
        # Errors happen fairly often, DHT's are hard to read, just keep going
        print(error.args[0])
        time.sleep(2.0)
        continue
    except Exception as error:
        dhtDevice.exit()
        raise error

    time.sleep(2.0)

为了测试,我用电吹风吹我的DHT11,使其升温到30摄氏度以上,蜂鸣器就会开始报警啦:

image.png

其它一些补充

其实温湿度模块或者蜂鸣器模块可以拿来做好多好玩的事情,比如温湿度模块可以结合一块LCD 1602做一个实时显示温湿度的温湿度计,也可以将采集到的温湿度数据写入到网络数据库中,加一些其它模块做个小小的气象站。

蜂鸣器的场景就更多了,很多需要监控&提醒的地方都可以加上蜂鸣器模块,比如监控燃气泄漏,或者监控应用程序运行等等。

这里我们只是演示了基本的操作,剩下的,大家可以自行发挥啦。


好了,这次的分享先到这里,后续内容,敬请期待哦。
(注:本系列文章同步首发于https://hive.blog & 电子产品世界官方论坛

相关链接

Sort:  

无缘的要用频率驱动,一般是2k Hz(咦?貌似几年前也是和一个大婶说3的同样一件事😂)

以前用的是香蕉派M3+无源蜂鸣器,遇到的问题是声音小
而这次用树莓派缺死活不响(频率肯定没问题),Google了一下,有说树莓派IO驱动电流弱的缘故,建议加三极管,我也不会弄啊
然后从Intel Edison套件里找了个有源蜂鸣器模块,折腾半天总算搞响了😭

img_5433.png
没用过树莓派,查了一下驱动电流可到十几毫安。像我平常用的蜂鸣器参数如下:

img_5434.png

驱动电流几毫安时就可以响了。还有一种很薄的压电片,驱动电流就更小了。当然不同的蜂鸣器差别挺大,你那可能是巨无霸

English translation?

树莓派教会了我,人就是天赋三六九等的,同是九年义务教育,你为何如此优秀

不明觉厉 我只能默默关掉显示器……