Python 使用 Python 读取 Raspberry Pi GPIO 传感器数据详解

第 7 章*设置 U*p a Raspberry Pi Web 服务器中,我们使用 GPIO Zero 库打开伺服并点亮 LED。在本章中,我们将使用 GPIO Zero 从 GPIO 端口读取输入。首先,我们将从一个简单的按钮开始,然后转到被动红外PIR)运动传感器和蜂鸣器。

具备从 GPIO 读取感官数据的能力将使我们能够构建物联网家庭安全仪表板。到本章结束时,我们应该非常熟悉使用连接到 GPIO 的组件编程 Raspberry Pi。

本章将介绍以下主题:

在本章中,我们将创建两种不同类型的报警系统。我们将从学习如何从按钮读取 GPIO 感官数据开始。然后,我们将学习如何与 PIR 传感器和距离传感器交互。最后,我们将学习如何连接一个主动蜂鸣器。

完成本章大约需要 3 小时。

为完成本项目,需要以下各项:

  • Raspberry Pi 3 型(2015 型或更新型)
  • USB 电源
  • 计算机显示器
  • USB 键盘
  • USB 鼠标
  • 试验板
  • 跨接导线
  • PIR 传感器
  • 距离传感器
  • 主动蜂鸣器
  • 发光二极管
  • 按钮(瞬时)
  • 按钮(闭锁)
  • 钥匙开关(可选)

来自GPIO Zero库的Button为我们提供了一种与连接到 GPIO 的典型按钮进行交互的简单方法。本节将介绍以下内容:

  • 使用带有按钮的 GPIO Zero
  • 同时使用 Sense HAT emulator 和 GPIO Zero 按钮
  • 长按按钮切换 LED

使用 GPIO 连接按钮相对容易。以下是显示流程的连接图:

连接按钮,以便使用跨接导线将一端接地。将另一端连接到 Raspberry Pi 上的 GPIO 4。

在 Thonny 中,创建一个新文件并将其命名为button_press.py。然后,在文件中键入以下内容并运行它:

from gpiozero import Button
from time import sleep

button = Button(4)
while True:
    if button.is_pressed:
     print("The Button on GPIO 4 has been pressed")
     sleep(1)

现在,无论何时按下按钮,您都可以在 shell 中看到消息"The Button on GPIO 4 has been pressed"。该代码将持续运行,直到您单击重置按钮。

让我们看一下代码。我们首先从GPIO Zero导入Button,从time库导入sleep

from gpiozero import Button
from time import sleep

然后我们创建一个新的button对象,并使用以下代码将其分配给 GPIO 引脚4

button = Button(4)

我们的连续循环检查按钮当前是否被按下,如果按钮是:

while True:
    if button.is_pressed:
     print("The Button on GPIO 4 has been pressed")
     sleep(1)

我们每天都使用按钮,无论是选择电梯楼层还是启动汽车。现代技术允许我们将按钮与它控制的物理设备分离。换句话说,按下按钮可以启动许多与按钮无关的不同事件。我们可以用我们的按钮和感知帽模拟器来模拟这种分离

I can just picture some of you wondering what separating a button from what it is controlling actually means. To help you visualize it, picture a latching push-button that controls a light. When the button is pressed down, the circuit is completed and electricity runs through the leads on the push-button. With the use of controllers and computers such as the Raspberry Pi, all that the push-button is required to do is change its state. The controller or computer takes that state and performs actions that are completely separated from the push-button itself.

从 Raspbian 中的编程菜单加载 Sense HAT emulator。在 Thonny 中创建一个新的 Python 文件,并将其命名为sense-button.py。在文件中输入以下代码,完成后单击运行图标:

from gpiozero import Button
from sense_emu import SenseHat
from time import sleep

button = Button(4)
sense = SenseHat()

def display_x_mark(rate=1):
    sense.clear()
    X = (255,0,0)
    O = (255,255,255)
    x_mark = [
              X,O,O,O,O,O,O,X,
              O,X,O,O,O,O,X,O,
              O,O,X,O,O,X,O,O,
              O,O,O,X,X,O,O,O,
              O,O,O,X,X,O,O,O,
              O,O,X,O,O,X,O,O,
              O,X,O,O,O,O,X,O,
              X,O,O,O,O,O,O,X
    ]
    sense.set_pixels(x_mark)

while True:
    if button.is_pressed:
        display_x_mark()
        sleep(1)
    else:
        sense.clear()

如果您的代码中没有任何错误,当您按下按钮时,您应该会看到 Sense HAT emulator 上的显示变为白色背景上的红色X

让我们稍微解释一下前面的代码。我们首先导入代码所需的库:

from gpiozero import Button
from sense_emu import SenseHat
from time import sleep

然后,我们创建新的按钮和感知帽模拟器对象。我们的button再次连接到 GPIO 引脚4

button = Button(4)
sense = SenseHat()

display_x_mark方法通过SenseHat方法set_pixels在显示器中创建X

def display_x_mark(rate=1):
    sense.clear()
    X = (255,0,0)
    O = (255,255,255)
    x_mark = [
              X,O,O,O,O,O,O,X,
              O,X,O,O,O,O,X,O,
              O,O,X,O,O,X,O,O,
              O,O,O,X,X,O,O,O,
              O,O,O,X,X,O,O,O,
              O,O,X,O,O,X,O,O,
              O,X,O,O,O,O,X,O,
              X,O,O,O,O,O,O,X
    ]
    sense.set_pixels(x_mark)

XO变量用于保存色码,(255,0,0)为红色,(255,255,255)为白色。变量x_mark创建一个 8 x 8 的模式,该模式与 Sense HAT emulator 屏幕的分辨率相匹配。x_mark被传递到SenseHAT对象的set_pixels方法中。

我们的连续循环检查按钮的is_pressed状态,如果状态返回true,则调用display_x_mark方法。然后,此方法在白色背景下打印红色X

当按钮未处于按下状态时,用sense.clear()清除显示:

while True:
    if button.is_pressed:
        display_x_mark()
        sleep(1)
    else:
        sense.clear()

有了GPIO Zero库,我们不仅可以检测按钮被按下的时间,还可以检测按钮被按下的时间。我们将使用hold_time属性和when_held方法来确定按钮是否被按下了一段时间。如果超过此持续时间,则我们将打开和关闭 LED。

下面是我们程序的电路图。保持按钮连接到 GPIO 引脚 4。将 GPIO 引脚 17 用于 LED,如下所示:

在 Thonny 中创建一个新文件,并将其命名为buttonheld-led.py。键入以下内容并单击“运行”:

from gpiozero import LED
from gpiozero import Button

led = LED(17)
button = Button(4)
button.hold_time=5

while True:
    button.when_held = lambda: led.toggle()

按住按钮5秒。您应该会看到 LED 开关打开。现在再次按住它5秒。LED 应关闭。

我们已经在前面的示例中介绍了代码的前四行。让我们看看按钮的保持时间设置在哪里:

button.hold_time=5

该行将按钮的保持时间设置为5秒。when_held方法在我们的连续循环中被调用:

button.when_held = lambda: led.toggle()

使用 lambda,我们可以创建一个匿名函数,以便我们可以调用LED对象led上的toggle()。这将打开和关闭 LED

使用运动传感器的报警系统是我们社会普遍存在的一部分。使用我们的覆盆子 Pi,它们非常容易构建。本节我们将介绍以下内容:

  • 什么是 PIR 传感器?
  • 使用GPIO buzzer
  • 建立基本的报警系统

PIR 传感器是一种运动传感器,用于检测运动。PIR 传感器的应用基本上是基于安全系统的运动检测。PIR 代表被动红外,PIR 传感器包含一个探测低辐射的晶体。PIR 传感器实际上分为两半,因为检测运动的是两半之间的差异。以下是廉价 PIR 传感器的照片:

In the preceding photo, we can see the positive (+), negative (-), and signal (S) pins. This particular PIR sensor sits well on a breadboard.

以下是 PIR 电路的接线图。正极引脚连接至 Raspberry Pi 上的 5 V 直流输出。负极引脚连接至接地(GND),信号连接至 GPIO 引脚 4:

在 Thonny 中创建一个新的 Python 文件,并将其命名为motion-sensor.py。键入以下代码并运行它:

from gpiozero import MotionSensor
from time import sleep

motion_sensor = MotionSensor(4)

while True:
    if motion_sensor.motion_detected:
        print('Detected Motion!')
        sleep(2)
    else:
        print('No Motion Detected!')
        sleep(2)

当您靠近 PIR 传感器时,您应该会看到一条信息,上面写着Detected Motion!。试着保持静止,看看你是否能在 shell 中显示消息No Motion Detected!

我们的代码首先从GPIO Zero库导入MotionSensor类:

from gpiozero import MotionSensor

导入sleep类后,我们创建了一个新的MotionSensor对象,名为motion_sensor,并附加了编号4,以便我们的程序查找 GPIO 引脚 4 上的信号:

motion_sensor = MotionSensor(4)

在我们的连续循环中,我们用这条线检查motion_sensor的运动:

if motion_sensor.motion_detected:

从这里开始,我们在代码中定义要打印到 shell 的消息。

通常,有两种类型的电子蜂鸣器:主动和被动。有源蜂鸣器有一个内部振荡器,当向其施加直流电时会发出声音。被动蜂鸣器需要交流电或交流电才能发出声音。被动蜂鸣器基本上是小型电磁扬声器。辨别区别的最简单方法是使用直流电源并听声音。就我们的代码而言,我们将使用一个有源蜂鸣器,如下图所示:

GPIO Zero库中有一个buzzer类。我们将使用这个类通过我们的主动蜂鸣器产生刺耳的警报声。如下图所示配置电路。主动蜂鸣器上的正极导线连接到 GPIO 针脚 17:

在 Thonny 中创建一个新的 Python 文件,并将其命名为buzzer-test1.py。键入以下代码并运行它:

from gpiozero import Buzzer
from time import sleep

buzzer = Buzzer(17)

while True:
    buzzer.on()
    sleep(2)
    buzzer.off()
    sleep(2)

根据您选择的激活蜂鸣器,您应该听到刺耳的声音两秒钟,然后是 2 秒钟的静音。以下线路接通蜂鸣器:

buzzer.on()

同样,前面代码中的这一行关闭蜂鸣器:

buzzer.off()

buzzer对象上使用toggle方法可以简化代码。在 Thonny 中创建一个新的 Python 文件。叫它buzzer-test2.py。键入以下内容并运行它:

from gpiozero import Buzzer
from time import sleep

buzzer = Buzzer(17)

while True:
    buzzer.toggle()
    sleep(2)

你应该得到同样的结果。第三种方法是使用来自buzzer对象的beep方法。在 Thonny 中创建一个新的 Python 文件。叫它buzzer-test3.py。键入以下内容并运行它:

from gpiozero import Buzzer

buzzer = Buzzer(17)

while True:
    buzzer.beep(2,2,10,False)

buzzer应开启2秒,然后关闭2秒,并重复此操作共10次。beep方法采用以下四个参数:

  • on_time:这是声音开启的秒数。默认值为1秒。

  • off_time:这是声音关闭的秒数。默认值为1秒。

  • n:这是流程将运行的次数。默认为None,表示永远。

  • background:决定是否启动后台线程运行流程。True值在后台线程中运行进程并立即返回。当设置为False时,在流程完成之前不会返回(请注意,当nNone时,该方法不会返回)

现在,让我们围绕蜂鸣器构建一个基本的报警系统。将 PIR 传感器连接至 GPIO 引脚 4,并将锁定按钮连接至 GPIO 引脚 8。以下是我们系统的电路图:

在 Thonny 中创建一个新文件并将其命名为basic-alarm-system.py。键入以下内容并单击运行:

from gpiozero import MotionSensor
from gpiozero import Buzzer
from gpiozero import Button
from time import sleep

buzzer = Buzzer(17)
motion_sensor = MotionSensor(4)
switch = Button(8)

while True:
    if switch.is_pressed:
        if motion_sensor.motion_detected:
            buzzer.beep(0.5,0.5, None, True)
            print('Intruder Alert')
            sleep(1)
        else:
            buzzer.off()
            print('Quiet')
            sleep(1)
    else:
        buzzer.off()
        sleep(1)

我们在这里所做的是用我们的组件创建一个报警系统。我们使用一个锁定按钮来打开和关闭报警系统。我们可以很容易地用钥匙开关来代替闭锁按钮。下图显示了此更改:

该电路可以很容易地转移到项目箱中用作报警系统。

我们将通过修改原始的Hello LED代码继续探索传感器。在本项目中,我们将结合距离传感器和 PIR 传感器,并根据这些传感器的值闪烁 LED。这个电路不仅会告诉我们有人正在接近,还会告诉我们他们有多近。

本节将介绍以下内容:

  • 配置距离传感器
  • Hello LED提升到另一个层次

我们将首先配置距离传感器并运行一些代码。下面是我们距离传感器电路的电路图:

以下是要进行的连接:

  • 来自运动传感器的 VCC 连接到 Raspberry Pi 的 5 V DC 输出
  • GPIO 针脚 17 连接到距离传感器上的 Trig
  • 距离传感器上的回波连接到 330 欧姆电阻器
  • 距离传感器上的 GND 连接到 Raspberry Pi 和 470 欧姆电阻器上的 GND
  • 330 欧姆电阻器的另一端从距离传感器上的回波引脚连接到 470 欧姆电阻器(两个电阻器形成一个分压器电路)
  • Raspberry Pi 的 GPIO 引脚 18 连接至电阻器的交叉点

该电路中值得注意的是由两个电阻器产生的分压器。我们使用此分配器连接 GPIO 引脚 18。

在 Thonny 中创建一个新的 Python 文件,并将其命名为distance-sensor-test.py。键入以下代码并运行它:

from gpiozero import DistanceSensor
from time import sleep

distance_sensor = DistanceSensor(echo=18, trigger=17)
while True:
    print('Distance: ', distance_sensor.distance*100)
    sleep(1)

您应该会看到类似于以下屏幕截图的输出。将手或任何其他物体放在距离传感器前面时,打印到外壳上的值应发生变化,如下所示:

Be sure to have the distance sensor on a secure, non-moving surface, such as a breadboard.

我们最初的Hello LED!系统是一个简单的电路,其中包括制作一个 LED,连接到 GPIO 端口,闪烁打开和关闭。自创建该电路以来,我们已经涵盖了更多内容。我们将学习并创建一个新的Hello LED电路。通过该电路,我们将创建一个报警系统,其中,LED 闪烁频率指示与报警的距离。

以下是我们新的Hello LED系统的电路图:

这可能看起来有点复杂,电线到处走;然而,这是一个相当简单的电路。距离传感器部件与以前相同。对于其他组件,按如下方式连接:

  • PIR 传感器的正极引脚连接至试验板上的 5V DC
  • PIR 传感器的负极引脚连接至试验板上的 GND
  • PIR 传感器的信号引脚连接到 GPIO 引脚 4
  • LED 的正极引脚通过 220 欧姆电阻器连接到 GPIO 引脚 21
  • LED 的负极引脚连接至试验板上的 GND

在 Thonny 中创建一个新的 Python 文件,并将其命名为hello-led.py。键入以下代码并运行它:

from gpiozero import DistanceSensor
from gpiozero import MotionSensor
from gpiozero import LED
from time import sleep

distance_sensor = DistanceSensor(echo=18, trigger=17)
motion_sensor = MotionSensor(4)
led = LED(21)

while True:  
    if(motion_sensor.motion_detected):
        blink_time=distance_sensor.distance
        led.blink(blink_time,blink_time,None,True)
    sleep(2)

一旦检测到运动,LED 应立即开始闪烁。当您的手越来越靠近距离传感器时,LED 闪烁的频率将加快

我们现在应该非常熟悉与传感器和树莓 Pi 的交互。这一章应该被认为是一个轻松使用树莓圆周率建立感觉回路的练习。

我们将在第 9 章构建家庭安全仪表板中使用这些知识,在这里我们将创建物联网家庭安全仪表板。

  1. 主动式蜂鸣器和被动式蜂鸣器的区别是什么?
  2. 对还是错?我们检查button.is_pressed参数,确认我们的按钮是否被按下。
  3. 对还是错?我们需要一个分压器电路来连接 PIR 传感器。
  4. 我们可以使用哪三种不同的方法来打开和关闭主动蜂鸣器?
  5. 对还是错?按钮必须直接连接到电路才能发挥作用。
  6. 我们使用哪个DistanceSensor参数检查物体与距离传感器的距离?
  7. 我们使用 Sense HAT emulator 中的哪种方法将像素打印到屏幕上?
  8. 我们如何设置我们的MotionSensor从 GPIO 引脚 4 读取?
  9. 对还是错?基本的报警系统对于我们的 Raspberry Pi 来说太复杂了。
  10. 对还是错?Sense HAT emulator 可用于与连接到 GPIO 的外部传感器进行交互。

查阅 GPIO Zero 文档https://gpiozero.readthedocs.io/en/stable/ 了解有关使用此库的更多信息。

教程来源于Github,感谢apachecn大佬的无私奉献,致敬!

技术教程推荐

从0开始学微服务 -〔胡忠想〕

数据分析实战45讲 -〔陈旸〕

TensorFlow快速入门与实战 -〔彭靖田〕

浏览器工作原理与实践 -〔李兵〕

雷蓓蓓的项目管理实战课 -〔雷蓓蓓〕

用户体验设计实战课 -〔相辉〕

郭东白的架构课 -〔郭东白〕

现代React Web开发实战 -〔宋一玮〕

运维监控系统实战笔记 -〔秦晓辉〕