在本章中,我们将开始解锁 Raspberry Pi 和 GPIO(通用输入输出)背后的真实功率。GPIO 允许您通过使用可设置为输入或输出的管脚将 Raspberry Pi 连接到外部世界,并通过代码进行控制。
本章将介绍以下主题:
在本章中,我们首先探讨 Python 中特定于 Raspberry Pi 的库。我们将通过使用 Raspberry Pi 摄像头模块和 Pibrella 帽子的几个示例来演示这些。在继续使用 Fritzing 程序设计物理电路之前,我们将使用 Sense Hat emulator 尝试一些编码示例。使用一个试验板,我们将建立这个电路,并将其连接到我们的树莓 Pi。
在本章的结尾,我们将构建一个莫尔斯电码生成器,用莫尔斯电码传输我们在第 2 章中创建的类中的天气数据,该类使用 Raspberry Pi编写 Python 程序。本章需要一个下午才能完成。
完成本项目需要以下内容:
我们将把注意力转向与 Raspbian 一起预装的 Python 库或包。要从 Thonny 查看这些软件包,请单击工具|管理软件包。短暂延迟后,您应该会看到对话框中列出了许多程序包:
让我们探索其中的一些包。
Raspberry Pi 上的摄像头端口或 CSI 允许您将专门设计的 Raspberry Pi 摄像头模块连接到 Pi。该相机可以拍摄照片和视频,并具有延时摄影和慢动作视频录制功能。picamera
包允许我们通过 Python 访问摄像头。以下是通过摄像头端口连接到 Raspberry Pi 3 型号 B 的 Raspberry Pi 摄像头模块的图片:
将 Raspberry Pi 摄像头模块连接到 Pi,打开 Thonny,然后键入以下代码:
import picamera
import time
picam = picamera.PiCamera()
picam.start_preview()
time.sleep(10)
picam.stop_preview()
picam.close()
此代码导入picamera
和time
包,然后创建一个名为picam
的picamera
对象。从那里,我们开始预览,然后睡眠10
秒,然后停止预览,然后关闭相机。运行程序后,您应该会在屏幕上看到摄像头的10
秒预览。
枕头包用于 Python 的图像处理。要测试这一点,请将图像下载到与项目文件相同的目录中。在 Thonny 中创建新文件并键入以下内容:
from PIL import Image
img = Image.open('image.png')
print(img.format, img.size)
您应该看到在下面的命令行中打印的图像的格式和大小(括号中)。
Sense 帽子是一款精致的覆盆子 Pi 附加板。传感帽是 Astro Pi 套件的主要组成部分,该套件是一项让年轻学生为国际空间站设计树莓 Pi 的计划的一部分。
Astro Pi 竞赛于 2015 年 1 月正式向英国所有中小学适龄儿童开放。在国际空间站执行任务期间,英国宇航员蒂姆·皮克在空间站上部署了 Astro-Pi 计算机
获胜的 Astro-Pi 竞赛代码在轨道上加载到 Astro-Pi 上。生成的数据被收集并送回地球。
传感帽包含一组可用作显示器的 LED。传感帽上还装有以下传感器:
我们可以通过sense-hat
包访问传感帽上的传感器和 LED。对于没有 Sense 帽子的用户,可以使用 Raspbian 中的 Sense 帽子模拟器。我们使用sense-emu
软件包访问 Sense HAT 仿真器上的模拟传感器和 LED 显示屏。
要演示这一点,请执行以下步骤:
sense-hat-test.py
或类似名称。from sense_emu import SenseHat
sense_emulator = SenseHat()
sense_emulator.show_message('Hello World')
Hello World!
消息滚动,一次滚动一个字母(请参见上一个屏幕截图)。通过 GPIO,我们能够连接到外部世界。以下是 Raspberry Pi GPIO 引脚的示意图:
以下是这些引脚的说明:
红色引脚表示 GPIO 输出的电源。GPIO 提供 3.3 伏和 5 伏电压。
黑色引脚表示用于电气接地的引脚。如您所见,GPIO 上有 8 个接地引脚。
蓝色引脚用于在顶部(帽子上添加的覆盆子 Pi硬件。它们允许 Raspberry Pi 和帽子的电可擦除可编程只读存储器(EEPROM之间进行通信。
绿色引脚代表我们可以编程的输入和输出引脚。请注意,一些绿色 GPIO 引脚具有额外功能。我们将不讨论此项目的附加功能。
GPIO 是覆盆子 Pi 的核心。我们可以通过 GPIO 将 LED、按钮、蜂鸣器等连接到 Raspberry Pi。我们还可以通过专为树莓 Pi 设计的帽子访问 GPIO。其中一个名为Pibrella
,我们接下来将使用它来探索如何通过 Python 代码连接到 GPIO。
Raspberry Pi 1 Models A and B only have the first 26 pins (as shown by the dotted line). Models since then, including Raspberry Pi 1 Models A+ and B+, Raspberry Pi 2, Raspberry Pi Zero and Zero W, and Raspberry Pi 3 Model B and B+, have 40 GPIO pins.
Pibrella 是一款相对便宜的覆盆子皮帽子,可以轻松连接到 GPIO。以下是 Pibrella 的车载部件:
Pibrella 是为早期的 Raspberry Pi 模型设计的,因此只有 26 针输入。但是,它可以通过前 26 个引脚连接到更高型号
要安装 Pibrella 帽子,请将 Pibrella 上的插针连接器与 Raspberry Pi 上的前 26 个插针对齐,然后向下推。在下图中,我们正在 Raspberry Pi 3 B 型上安装 Pibrella:
Pibrella 在安装时应紧密贴合:
连接到 Pibrella 所需的库不是随 Raspbian 预先安装的(在撰写本文时),因此我们必须自己安装它们。为此,我们将使用来自终端的pip3
命令:
sudo pip3 install pibrella
Pibrella
库,访问 GPIO 无需知道 GPIO 引脚号。该功能被包装在我们导入代码的Pibrella
对象中。我们将做一个简短的演示pibrella-test.py
的新文件,或者将其命名为类似的名称。键入以下代码:import pibrella
import time
pibrella.light.red.on()
time.sleep(5)
pibrella.light.red.off()
pibrella.buzzer.success()
5
秒,然后在扬声器上播放一段简短的旋律。祝贺您,您现在已经跨入了物理计算世界的门槛。
用于访问 GPIO 的标准 Python 包称为RPi.GPIO
。描述其工作原理的最佳方法是使用一些代码(这仅用于演示目的;我们将在下一节中运行代码以访问 GPIO):
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.HIGH)
time.sleep(5)
GPIO.output(18, GPIO.LOW)
正如您所看到的,这段代码似乎有点混乱。我们将逐步解决这一问题:
RPi.GPIO
和time
库:import RPi.GPIO as GPIO
import time
BCM
:GPIO.setmode(GPIO.BCM)
GPIO.BOARD
。18
设置为输出,我们使用以下行:GPIO.setup(18, GPIO.OUT)
18
设置为HIGH
并持续5
秒,然后再将其设置为LOW
:GPIO.output(18, GPIO.HIGH)
time.sleep(5)
GPIO.output(18, GPIO.LOW)
如果我们设置了电路并运行了代码,我们会看到 LED 灯在关闭前5
秒亮起,类似于 Pibrella 示例
RPi.GPIO
的替代品是 GPIO 零包。与RPi.GPIO
一样,此软件包预装有 Raspbian。名称中的零表示零样板文件或设置代码(我们每次都被迫输入的代码)。
为了完成相同的任务,打开和关闭 LED5
秒,我们使用以下代码:
from gipozero import LED
import time
led = LED(18)
led.on()
time.sleep(5)
led.off()
与我们的RPi.GPIO
示例一样,此代码仅用于演示,因为我们尚未设置电路。很明显,GPIO 零代码比RPi.GPIO
示例简单得多。这段代码很容易解释。
在下面的部分中,我们将开始在带有 LED 的试验板上构建一个物理电路,并使用我们的代码来打开和关闭它。
Pibrella 帽子为我们提供了一种简单的 GPIO 编程方法,然而,Raspberry Pi 项目的最终目标是创建一个定制的工作电路。现在我们将采取步骤设计电路,然后使用试验板创建电路。
第一步是在计算机上设计电路。
Fritzing 是一款适用于 Windows、macOS 和 Linux 的自由电路设计软件。Raspberry Pi 商店中有一个版本,我们将在 Raspberry Pi 上安装:
Fritzing
:选择所有三个框并单击应用,然后单击确定。安装后,您应该能够从应用程序菜单|编程| Fritzing 加载 Fritzing。
单击“试验板”选项卡以访问“试验板设计”屏幕。屏幕中央有一个全尺寸的试验板。我们将使它更小,因为我们的电路小而简单。
点击试验板。在 Inspector 框中,您将看到一个名为 Properties 的标题。
单击“大小”下拉列表并选择“迷你”。
要将树莓 Pi 添加到电路中,请在搜索框中键入Raspberry Pi
。把树莓派 3 拖到我们的实验板下面。
从这里,我们可以将组件拖放到试验板上。
将 LED 和 330 欧姆电阻器添加到我们的试验板上,如下图所示。我们使用电阻器保护 LED 和 Raspberry Pi 免受可能导致损坏的过大电流的影响:
这是我们将为树莓圆周率建立的电路。
要构建我们的物理电路,首先要将组件插入到我们的实验板中。参考之前的图表,我们可以看到一些孔是绿色的。这表示电路中存在导通性。例如,我们通过同一垂直柱将 LED 的负支脚连接到 330 欧姆电阻器。因此,两个部件支腿通过试验板连接在一起。
当我们开始在试验板上放置组件时,我们会考虑到这一点:
It is a good practice to have the Raspberry Pi powered off when connecting jumpers to the GPIO.
如下图所示,整个电路类似于我们的烧结图(只有我们的面包板和覆盆子圆周率是侧向的):
我们现在已经准备好编程我们的第一个真正的 GPIO 电路。
我们将直接进入代码:
Hello LED.py
或类似名称。from gpiozero import LED
led = LED(18)
led.blink(1,1,10)
如果我们连接好电路并正确输入代码,我们应该会看到 LED 在 1 秒的间隔内闪烁 10 秒。gpiozero LED
对象中的闪烁功能允许我们设置on_time
(LED 保持亮起的秒数)、off_time
(LED 关闭的秒数)、n
或 LED 闪烁的次数,以及background
(设置为True
以允许其他代码在 LED 闪烁时运行)。
带有默认参数的blink
函数调用如下所示:
blink(on_time=1, off_time=1, n=none, background=True)
如果未将参数传递到功能中,LED 将以 1 秒的间隔不停闪烁。请注意,我们不需要像使用RPi.GPIO
包访问 GPIO 时那样导入time
库。我们只需在blink
函数中输入一个数字,以秒为单位表示我们希望 LED 亮起或熄灭的时间。
在第 2 章中使用 Raspberry Pi编写 Python 程序时,我们编写了模拟调用提供天气信息的 web 服务的代码。根据我们在本章学到的内容,让我们重温该代码,并对其进行物理计算升级。我们将使用 LED 闪烁莫尔斯电码表示我们的天气数据。
Many of us believe that the world only started to become connected in the 1990s with the World Wide Web. Little do we realize that we already had such a world beginning in the 19th century with the introduction of the telegraph and trans-world telegraph cables. The language of this so-called Victorian Internet was Morse code, with the Morse code operator as its gate keeper.
以下是闪烁莫尔斯电码表示天气数据的步骤:
MorseCodeGenerator
类:from gpiozero import LED
from time import sleep
class MorseCodeGenerator:
led = LED(18)
dot_duration = 0.3
dash_duration = dot_duration * 3
word_spacing_duration = dot_duration * 7
MORSE_CODE = {
'A': '.-', 'B': '-...', 'C': '-.-.',
'D': '-..', 'E': '.', 'F': '..-.',
'G': '--.', 'H': '....', 'I': '..',
'J': '.---', 'K': '-.-', 'L': '.-..',
'M': '--', 'N': '-.', 'O': '---',
'P': '.--.', 'Q': '--.-', 'R': '.-.',
'S': '...', 'T': '-', 'U': '..-',
'V': '...-', 'W': '.--', 'X': '-..-',
'Y': '-.--', 'Z': '--..', '0': '-----',
'1': '.----', '2': '..---', '3': '...--',
'4': '....-', '5': '.....', '6': '-....',
'7': '--...', '8': '---..', '9': '----.',
' ': ' '
}
def transmit_message(self, message):
for letter in message:
morse_code_letter = self.MORSE_CODE[letter.upper()]
for dash_dot in morse_code_letter:
if dash_dot == '.':
self.dot()
elif dash_dot == '-':
self.dash()
elif dash_dot == ' ':
self.word_spacing()
self.letter_spacing()
def dot(self):
self.led.blink(self.dot_duration,self.dot_duration,1,False)
def dash(self):
self.led.blink(self.dash_duration,self.dot_duration,1,False)
def letter_spacing(self):
sleep(self.dot_duration)
def word_spacing(self):
sleep(self.word_spacing_duration-self.dot_duration)
if __name__ == "__main__":
morse_code_generator = MorseCodeGenerator()
morse_code_generator.transmit_message('SOS')
gpiozero
和time
库导入我们的MorseCodeGenerator
类之后,我们将 GPIO 18 定义为我们的 LED,行为led=LED(18)
dot_duration = 0.3
行设置dot
的持续时间dot_duration
定义破折号的持续时间和单词之间的间距dot_duration
MORSE_CODE
的 Python 字典。我们用这本词典把字母翻译成摩尔斯电码transmit_message
函数逐步遍历消息的每个字母,然后遍历莫尔斯电码中的每个字符,这相当于使用dash_dot
变量dot
和dash
方法中,通过使用gpiozero
库中的blink
函数:def dot(self):
self.led.blink(self.dot_duration, self.dot_duration,1,False)
在dot
方法中,我们可以看到我们在dot_duration
中设置的持续时间内打开 LED,然后在相同的时间内关闭 LED。在blink
方法调用中,我们只闪烁一次,因为它是由数字1
设置的。我们还将背景参数设置为False
。
最后一个参数非常重要,如果我们将其保留为默认值True
,代码将在 LED 有机会闪烁之前继续运行。基本上,除非背景参数设置为False
,否则代码不会工作。
我们放弃了通常的测试信息Hello World
,而是使用标准SOS
,这是大多数普通莫尔斯电码爱好者所熟悉的。我们可以通过点击 Run 按钮来测试我们的课程,如果设置正确,我们将看到 Morse 电码中的 LED 闪烁 SOS。
现在,让我们回顾一下第 2 章中的CurrentWeather
课程使用 Raspberry Pi编写 Python 程序。我们将进行一些小的修改:
from MorseCodeGenerator import MorseCodeGenerator
class CurrentWeather:
weather_data={
'Toronto':['13','partly sunny','8 NW'],
'Montreal':['16','mostly sunny','22 W'],
'Vancouver':['18','thunder showers','10 NE'],
'New York':['17','mostly cloudy','5 SE'],
'Los Angeles':['28','sunny','4 SW'],
'London':['12','mostly cloudy','8 NW'],
'Mumbai':['33','humid and foggy','2 S']
}
def __init__(self, city):
self.city = city
def getTemperature(self):
return self.weather_data[self.city][0]
def getWeatherConditions(self):
return self.weather_data[self.city][1]
def getWindSpeed(self):
return self.weather_data[self.city][2]
def getCity(self):
return self.city
if __name__ == "__main__":
current_weather = CurrentWeather('Toronto')
morse_code_generator = MorseCodeGenerator()
morse_code_generator.transmit_message(current_weather.
getWeatherConditions())
我们首先导入MorseCodeGenerator
类(确保两个文件位于同一目录中)。由于我们没有与/
等效的摩尔斯电码,我们将weather_data
数据集中的公里/小时计算出来。本课程的其余部分与第 2 章中的内容相同,即使用 Raspberry Pi编写 Python 程序。在我们的测试部分,我们实例化了一个CurrentWeather
类和一个MorseCodeGenerator
类。使用CurrentWeather
类,我们将多伦多的天气条件传递到MorseCodeGenerator
类。
如果在输入密码时没有任何错误,我们应该看到莫尔斯电码中的 LED 闪烁partly sunny
。
本章涵盖了很多内容。最后,您应该对在 Raspberry Pi 上开发应用程序感到非常满意。
picamera
、Pillow
和sense-hat
库使您可以轻松地使用覆盆子 Pi 与外部世界进行通信。使用 Raspberry Pi 摄像头模块和picamera
,我们的 Pi 开创了一个全新的可能性世界。我们只谈到了picamera
能做的一小部分。此外,我们仅对Pillow
库中的图像处理进行了初步探讨。Sense HAT emulator 让我们节省了购买实际帽子和测试代码的开支。通过sense-hat
和 Raspberry Pi Sense 帽子,我们真正将触角扩展到了物理世界。
廉价的 Pibrella 帽子提供了一种进入物理计算世界的简单方法。通过安装pibrella
库,我们可以让 Python 代码访问各种各样的 LED、扬声器和按钮,所有这些都整齐地封装在一顶树莓派帽子中。
然而,物理计算的真正最终目标是构建电子电路,以弥合我们的树莓 Pi 与外部世界之间的差距。我们用 Fritzing circuit builder 开始了构建电子电路的旅程,该产品可从 Raspberry Pi 商店购买。从那里,我们在带有 LED 和电阻器的试验板上构建了第一个电路。
本章结束时,我们使用 Raspberry Pi 和 LED 电路创建了一个莫尔斯电码发生器。在新旧交替中,我们能够通过闪烁的 LED 以摩尔斯电码传输天气数据。
在第 4 章订阅 Web 服务中,我们将把 Web 服务融入我们的代码中,从而以一种称为物联网的概念将互联网世界与现实世界连接起来。
gpiozero
中的零是指什么?gpiozero
LEDblink
功能中的默认背景参数设置为什么?gpiozero
库访问 GPIO 要比使用RPi.GPIO
库容易得多。本章涵盖了许多概念,假设所需的技能不超过一般开发人员和修补者。为了进一步巩固对这些概念的理解,请通过谷歌搜索以下内容:
对于那些像我一样对过去的技术着迷的人来说,下面是一本关于维多利亚时代互联网的好书:汤姆·斯坦达奇的《维多利亚时代互联网》。