跳到主要内容

本页总览

高阶用法

以下示例演示了 GPIO Zero 库的部分功能。请注意,所有配方都是假设 Python 3 编写的。在 Python 2 下可能也能运行,但并不保证!

LED板 (LEDBoard)

您可以逐个遍历 LEDBoard 对象中的 LED:

from gpiozero import LEDBoard



from time import sleep



leds = LEDBoard(5, 6, 13, 19, 26)



for led in leds:



led.on()



sleep(1)



led.off()

LEDBoard 还支持索引。这意味着你可以使用 leds[i] 访问单个 LED 对象,其中 i 是一个从 0 到(不包括)LED 数量的整数:

from gpiozero import LEDBoard



from time import sleep



leds = LEDBoard(2, 3, 4, 5, 6, 7, 8, 9)



leds[0].on() # first led on



sleep(1)



leds[7].on() # last led on



sleep(1)



leds[-1].off() # last led off



sleep(1)

这也意味着您可以使用切片来访问 LED 的子集:

from gpiozero import LEDBoard



from time import sleep



leds = LEDBoard(2, 3, 4, 5, 6, 7, 8, 9)



for led in leds[3:]: # leds 3 and onward



led.on()



sleep(1)



leds.off()



for led in leds[:2]: # leds 0 and 1



led.on()



sleep(1)



leds.off()



for led in leds[::2]: # even leds (0, 2, 4...)



led.on()



sleep(1)



leds.off()



for led in leds[1::2]: # odd leds (1, 3, 5...)



led.on()



sleep(1)



leds.off()

在构建 LEDBoard 对象时,可以对其 LED 对象进行命名。这意味着可以通过名称访问各个 LED:

from gpiozero import LEDBoard



from time import sleep



leds = LEDBoard(red=2, green=3, blue=4)



leds.red.on()



sleep(1)



leds.green.on()



sleep(1)



leds.blue.on()



sleep(1)

LEDBoard 对象还可以嵌套在其他 LEDBoard 对象中:

from gpiozero import LEDBoard



from time import sleep



leds = LEDBoard(red=LEDBoard(top=2, bottom=3), green=LEDBoard(top=4, bottom=5))



leds.red.on() ## both reds on



sleep(1)



leds.green.on() # both greens on



sleep(1)



leds.off() # all off



sleep(1)



leds.red.top.on() # top red on



sleep(1)



leds.green.bottom.on() # bottom green on



sleep(1)

多字符7段显示屏

上一章演示的 7 段显示器通常有多字符版本(通常 4 个字符)。这种显示屏是多路复用的,即 LED 引脚通常与单字符显示屏相同,但所有字符共享。然后,每个字符都有自己的公共线路,该线路可以接地(在共阴极显示屏的情况下),以启用该特定字符。通过快速依次激活每个字符,可以使眼睛误以为同时显示了四个不同的字符。

在此类电路中,您不应试图将单个字符(在有小数点的情况下,可能有多达 8 个 LED 处于激活状态)的所有电流都汇入单个 GPIO。相反,应使用一些适当的晶体管(或类似元件,如光耦合器)将数字的阴极与地相连,并通过 GPIO 控制该元件。

7段多字符显示屏 接线图115510101515202025253030353540404545505055556060AABBCCDDEEFFGGHHIIJJRaspberry Pi Model 2 v1.1© Raspberry Pi 2014http://www.raspberrypi.orgPowerHDMIAudioUSB 2xUSB 2xETHERNETDSI (DISPLAY)CSI (CAMERA)GPIO

该电路演示了一个 4 字符 7 段(实际上是 8 段,带小数点)显示屏,由 Pi 的 GPIO 控制,4 个 2N-3904 NPN 晶体管控制数字。

注意

强烈建议您查看特定多字符 7 段显示器的数据表。这些显示器的引脚输出差别很大,很可能与上面面包板上显示的不同。因此,下面提供了该电路的原理图,请根据您的显示器进行调整。

7段多字符显示屏 数据表2121212121217 SEGMENT4DIGITYOUNGSUNABCDEFGDPABCDEFGDPABCDEFGDPABCDEFGDPCOLAPOS2DIG26DIG38DIG44COL-A10APOS-A14A16B13C3D5E11F15G7DP12COL-C9APOS-C1DIG1212112312312312321212121GPIO14UART0_TXDGPIO15UART0_RXDGPIO18PCM_CLKGPIO23GPIO24GPIO25GPIO8SPI0_CE0_NGPIO7SPI0_CE1_NID_SC I2C ID EEPROM GPIO12GPIO16GPIO20GPIO21GPIO2SDA1I2CGPIO3SCL1I2CGPIO4GPIO17GPIO27GPIO22GIPO10 SPI0_MOSI GPIO9SPI0_MISOGPIO11SPI0_SCLKID_SD I2C ID EEPROMGPIO5GPIO5GPIO6GPIO13GPIO19GPIO26GND3V35VRaspberryPiModel 2 v1.1R1-R8330ΩQ1-Q42N 3904R9-R1233kΩ

以下代码可用于在显示屏上滚动信息:

from itertools import cycle



from collections import deque



from gpiozero import LEDMultiCharDisplay



from signal import pause



display = LEDMultiCharDisplay(



LEDCharDisplay(22, 23, 24, 25, 21, 20, 16, dp=12), 26, 19, 13, 6)



def scroller(message, chars=4):



d = deque(maxlen=chars)



for c in cycle(message):



d.append(c)



if len(d) == chars:



yield ''.join(d)



display.source_delay = 0.2



display.source = scroller('GPIO 2ER0 ')



pause()

谁在家指示灯

使用一些 绿-红 LED 灯对,可以根据能成功 ping 到的 IP 地址显示谁在家。请注意,前提是每个人的手机都在家庭路由器上预留了 IP 地址。

from gpiozero import PingServer, LEDBoard



from gpiozero.tools import negated



from signal import pause



status = LEDBoard(



mum=LEDBoard(red=14, green=15),



dad=LEDBoard(red=17, green=18),



alice=LEDBoard(red=21, green=22)



)



statuses = {



PingServer('192.168.1.5'): status.mum,



PingServer('192.168.1.6'): status.dad,



PingServer('192.168.1.7'): status.alice,



}



for server, leds in statuses.items():



leds.green.source = server



leds.green.source_delay = 60



leds.red.source = negated(leds.green)



pause()

或者,使用 STATUS Zero

from gpiozero import PingServer, StatusZero



from gpiozero.tools import negated



from signal import pause



status = StatusZero('mum', 'dad', 'alice')



statuses = {



PingServer('192.168.1.5'): status.mum,



PingServer('192.168.1.6'): status.dad,



PingServer('192.168.1.7'): status.alice,



}



for server, leds in statuses.items():



leds.green.source = server



leds.green.source_delay = 60



leds.red.source = negated(leds.green)



pause()

Travis构建LED指示灯

使用 LED 指示灯来显示 Travis 构建的状态。绿灯表示测试通过,红灯表示构建失败:

from travispy import TravisPy



from gpiozero import LED



from gpiozero.tools import negated



from time import sleep



from signal import pause



def build_passed(repo):



t = TravisPy()



r = t.repo(repo)



while True:



yield r.last_build_state == 'passed'



red = LED(12)



green = LED(16)



green.source = build_passed('gpiozero/gpiozero')



green.source_delay = 60 * 5 # check every 5 minutes



red.source = negated(green)



pause()

请注意,此方案需要 travispy。使用 sudo pip3 install travispy 安装。

按钮控制机器人

除了简单方案中的示例外,你还可以使用四个按钮对方向进行编程,并添加第五个按钮来依次处理它们,就像 Bee-Bot 或 Turtle 机器人一样。

from gpiozero import Button, Robot, Motor



from time import sleep



from signal import pause



robot = Robot(Motor(17, 18), Motor(22, 23))



left = Button(2)



right = Button(3)



forward = Button(4)



backward = Button(5)



go = Button(6)



instructions = []



def add_instruction(btn):



instructions.append({



left: (-1, 1),



right: (1, -1),



forward: (1, 1),



backward: (-1, -1),



}[btn])



def do_instructions():



instructions.append((0, 0))



robot.source_delay = 0.5



robot.source = instructions



sleep(robot.source_delay * len(instructions))



del instructions[:]



go.when_pressed = do_instructions



for button in (left, right, forward, backward):



button.when_pressed = add_instruction



pause()

用两个电位器控制机器人

使用两个电位器控制机器人的左右电机速度:

from gpiozero import Robot, Motor, MCP3008



from gpiozero.tools import zip_values



from signal import pause



robot = Robot(left=Motor(4, 14), right=Motor(17, 18))



left_pot = MCP3008(0)



right_pot = MCP3008(1)



robot.source = zip_values(left_pot, right_pot)



pause()

要包括反方向,可将电位器值从 0->1 缩放至 -1->1:

from gpiozero import Robot, Motor, MCP3008



from gpiozero.tools import scaled



from signal import pause



robot = Robot(left=Motor(4, 14), right=Motor(17, 18))



left_pot = MCP3008(0)



right_pot = MCP3008(1)



robot.source = zip(scaled(left_pot, -1, 1), scaled(right_pot, -1, 1))



pause()

提示

请注意,上面的示例需要 Python 3。在 Python 2 中,zip() 不支持惰性求值,因此脚本会直接挂起。

BlueDot LED

BlueDot 是一个 Python 库和一个 Android 应用程序,可让您轻松为 Raspberry Pi 项目添加蓝牙控制功能。一个使用 BlueDot 应用程序控制 LED 的简单示例:

from bluedot import BlueDot



from gpiozero import LED



bd = BlueDot()



led = LED(17)



while True:



bd.wait_for_press()



led.on()



bd.wait_for_release()



led.off()

请注意,此配方需要使用 bluedot 和相关的 Android 应用程序。有关安装说明,请参阅 BlueDot 文档

BlueDot 机器人

您可以创建一个由蓝牙控制的机器人,按下时机器人向前移动,松开时机器人停止:

from bluedot import BlueDot



from gpiozero import Robot, Motor



from signal import pause



bd = BlueDot()



robot = Robot(left=Motor(4, 14), right=Motor(17, 18))



def move(pos):



if pos.top:



robot.forward(pos.distance)



elif pos.bottom:



robot.backward(pos.distance)



elif pos.left:



robot.left(pos.distance)



elif pos.right:



robot.right(pos.distance)



bd.when_pressed = move



bd.when_moved = move



bd.when_released = robot.stop



pause()

或者更高级的例子,包括控制机器人的速度和精确方向:

from gpiozero import Robot, Motor



from bluedot import BlueDot



from signal import pause



def pos_to_values(x, y):



left = y if x > 0 else y + x



right = y if x < 0 else y - x



return (clamped(left), clamped(right))



def clamped(v):



return max(-1, min(1, v))



def drive():



while True:



if bd.is_pressed:



x, y = bd.position.x, bd.position.y



yield pos_to_values(x, y)



else:



yield (0, 0)



robot = Robot(left=Motor(4, 14), right=Motor(17, 18))



bd = BlueDot()



robot.source = drive()



pause()

控制Pi自身的LED灯

注意

译注:这个示例在 Bookworm 中不可行,因新系统很多信息都变了。为保持与译文原版内容的一致性,这里继续保留其文字。

某些型号的 Pi(特别是 A+、B+ 和 2B)可以控制电源和活动 LED。这对于测试 GPIO 功能非常有用,无需连接自己的 LED 灯(这也是因为电源和活动 LED 灯是 "已知良好" 的)。

首先,您需要禁用内置 LED 的常规触发器。这可以通过以下命令在终端完成:

echo none | sudo tee /sys/class/leds/led0/trigger



echo gpio | sudo tee /sys/class/leds/led1/trigger

现在你可以用 gpiozero 控制 LED 灯了:

from gpiozero import LED



from signal import pause



power = LED(35) # /sys/class/leds/led1



activity = LED(47) # /sys/class/leds/led0



activity.blink()



power.blink()



pause()

要将 LED 指示灯恢复原状,可以重启 Pi 或运行以下命令�:

echo mmc0 | sudo tee /sys/class/leds/led0/trigger



echo input | sudo tee /sys/class/leds/led1/trigger

提示

在 Pi Zero 上,您可以使用此配方控制活动 LED,但没有单独的电源 LED 可控(值得注意的是,活动 LED 为低电平有效,因此在构建 LED 组件时应设置 active_high=False)。

在最初的 Pi 1(型号 A 或 B)上,活动 LED 可以用 GPIO16 控制(如上所述禁用其触发器后),但电源 LED 是硬接线接通的。

在 Pi 3 上,LED 由 GPIO 扩展器控制,目前还不能通过 gpiozero 访问该扩展器。


中文翻译版以英文版相同知识授权方式共享:BSD-3-Clause。交流 Q群:498908352