源与值
GPIO Zero 提供了一种使用声明式编程范例将设备连接在一起的方法:将一个设备的值输入到另一个设备,例如将按钮的值输入到 LED:
from gpiozero import LED, Button
from signal import pause
led = LED(17)
button = Button(2)
led.source = button
pause()
相当于
from gpiozero import LED, Button
from time import sleep
led = LED(17)
button = Button(2)
while True:
led.value = button.value
sleep(0.01)
只不过前者是在后台线程中更新的,这样就可以同时做其他事情。
每个设备都有一个 value
属性(设备的当前值)。输入设备(如按钮)只能读取其值,但输出设备(如 LED)也可以设置其值来改变设备的状态:
>>> led = PWMLED(17)
>>> led.value # LED is initially off
0.0
>>> led.on() # LED is now on
>>> led.value
1.0
>>> led.value = 0 # LED is now off
每个设备都有一个 value
属性(持续 生成 设备当前值的生成器)。所有输出设备都有一个 source
属性,可以设置为任何 迭代器。设备将遍历所提供设备的值,以 source_delay
属性中指定的速率(默认值为 0.01 秒)为每个元素设置设备值。
最常见的用例是设置输出设备的源,使其与输入设备的值相匹配,如上面的例子。更有趣的例子是控制 LED 亮度的电位计:
from gpiozero import PWMLED, MCP3008
from signal import pause
led = PWMLED(17)
pot = MCP3008()
led.source = pot
pause()
其工作原理是,输入设备的 value
属性用于向输出设备输入值。在 v1.5 之前,source
必须直接设置为设备的 value
属性:
from gpiozero import PWMLED, MCP3008
from signal import pause
led = PWMLED(17)
pot = MCP3008()
led.source = pot.values
pause()
虽然这种方法仍受支持,但现在推荐的方法是将 source
设置为设备对象。
也可以将一个输出设备的 source
设置为另一个输出设备,使它们保持匹配。在本例中,红色 LED 被设置为与按钮匹配,绿色 LED 被设置为与红色 LED 匹配,因此当按下按钮时,两个 LED 都会亮起:
from gpiozero import LED, Button
from signal import pause
red = LED(14)
green = LED(15)
button = Button(17)
red.source = button
green.source = red
pause()
处理数值
设备的数值在传递给 source
之前也可以进行处理:
例如,编写一个生成器函数,将与 Button 值相反的值传入 LED:
from gpiozero import Button, LED
from signal import pause
def opposite(device):
for value in device.values:
yield not value
led = LED(4)
btn = Button(17)
led.source = opposite(btn)
pause()
另外,也可以使用自定义生成器从人工来源提供数值:
例如,编写一个生成器函数,随机生成 0 或 1:
from gpiozero import LED
from random import randint
from signal import pause
def rand():
while True:
yield randint(0, 1)
led = LED(17)
led.source = rand()
pause()
如果迭代器是无限的(即无限生成器),则会一直处理元素,直到 source
被更改或设置为 None
为止。
如果迭代器是有限的(例如一个列表),则会在处理完所有元素后终止(将设备值保留在最后一个元素上):
from gpiozero import LED
from signal import pause
led = LED(17)
led.source_delay = 1
led.source = [1, 0, 1, 1, 1, 0, 0, 1, 0, 1]
pause()
源工具
GPIO Zero 提供了一组现成的函数,用于处理 源/值,称为源工具。从 gpiozero.tools
中导入即可使用。
其中一些源工具是无需输入的人造源:
在此示例中,0 和 1 之间的随机值被传递给 LED,使其产生闪烁的蜡烛效果:
请注意,在上述示例中,source_delay
用于使 LED 对随机值的迭代速度稍慢一些。source_delay
可以设置为较大的数字(例如,1 表示延迟一秒),也可以设置为 0 以禁用任何延迟。
有些工具会使用单个源并处理其值:
在此示例中,只有在未按下按钮时 LED 才会点亮:
from gpiozero import Button, LED
from gpiozero.tools import negated
from signal import pause
led = LED(4)
btn = Button(17)
led.source = negated(btn)
pause()
请注意,接收一个或多个 value
参数的源工具支持传递 ValuesMixin
衍生工具或迭代器,包括设备的 values
属性。
有些工具会组合多个源的值:
在本例中,只有同时按下两个按钮,LED 才会点亮(就像一个 AND 门):
from gpiozero import Button, LED
from gpiozero.tools import all_values
from signal import pause
button_a = Button(2)
button_b = Button(3)
led = LED(17)
led.source = all_values(button_a, button_b)
pause()