在第 7 章*设置 U*p a Raspberry Pi Web 服务器中,我们使用 GPIO Zero 库打开伺服并点亮 LED。在本章中,我们将使用 GPIO Zero 从 GPIO 端口读取输入。首先,我们将从一个简单的按钮开始,然后转到被动红外(PIR)运动传感器和蜂鸣器。
具备从 GPIO 读取感官数据的能力将使我们能够构建物联网家庭安全仪表板。到本章结束时,我们应该非常熟悉使用连接到 GPIO 的组件编程 Raspberry Pi。
本章将介绍以下主题:
在本章中,我们将创建两种不同类型的报警系统。我们将从学习如何从按钮读取 GPIO 感官数据开始。然后,我们将学习如何与 PIR 传感器和距离传感器交互。最后,我们将学习如何连接一个主动蜂鸣器。
完成本章大约需要 3 小时。
为完成本项目,需要以下各项:
来自GPIO Zero
库的Button
为我们提供了一种与连接到 GPIO 的典型按钮进行交互的简单方法。本节将介绍以下内容:
使用 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)
X
和O
变量用于保存色码,(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,它们非常容易构建。本节我们将介绍以下内容:
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
时,在流程完成之前不会返回(请注意,当n
为None
时,该方法不会返回)
现在,让我们围绕蜂鸣器构建一个基本的报警系统。将 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
提升到另一个层次我们将首先配置距离传感器并运行一些代码。下面是我们距离传感器电路的电路图:
以下是要进行的连接:
该电路中值得注意的是由两个电阻器产生的分压器。我们使用此分配器连接 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
系统的电路图:
这可能看起来有点复杂,电线到处走;然而,这是一个相当简单的电路。距离传感器部件与以前相同。对于其他组件,按如下方式连接:
在 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 章构建家庭安全仪表板中使用这些知识,在这里我们将创建物联网家庭安全仪表板。
button.is_pressed
参数,确认我们的按钮是否被按下。DistanceSensor
参数检查物体与距离传感器的距离?MotionSensor
从 GPIO 引脚 4 读取?查阅 GPIO Zero 文档https://gpiozero.readthedocs.io/en/stable/ 了解有关使用此库的更多信息。