7 Source/Values
gpiozero 提供了一个方法,通过某算法把设备(传感器)连接起来,然后将信息从一个设备传递到另一个设备。简单的说,gpiozero 可以把某个设备的 values 传递到其他设备。例如,Button 的 values 传递到 LED(或 values 从 Button 传递到 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)
每个设备都有 values 属性(也就是设备的当前 value,value 会不断的生成)。
Input devices (如 button) 只能读取 values,但 output devices (如 LED) 可以写入 values。
output devices 还具有 source 属性,source 可以设置成任意一种 iterator 。
values 传递的频率可以通过设置 source_delay 属性来修改,默认是 0.01s 。
(疑问:是 input 不停的发,output 设置频率接收;还是 input 设置频率发,output 不停的收)
Input devices 和 output devices 的 values 的范围要匹配。
potentiometer 控制 LED 亮度变化的示例:
from gpiozero import PWMLED, MCP3008
from signal import pause
led = PWMLED(17)
pot = MCP3008()
led.source = pot
pause()
values 可以在多个设备间传递:
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()
7.1 Processing values
values 在传递过程中,可以进行处理:
例如,Button 向 LED 传递 values 时,value 取反。
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()
有的时候可以没有 Input devices,人为生成一个输入源,如下:
例如,通过生成器随机生成 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()
如果传递的 values 是无限的,那么 value 会一直传递下去,直到 source 被修改或设置为 None 。
如果传递的 values 是有限的,那么 value 传完后就会停止,Output device 会停留在最后一个 value 的状态。
示例如下,LED 会最后一直亮下去:
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()
7.2 Source Tools
gpiozero 提供了一个工具 Source Tools,用来处理 source/values 。使用时需要导入 gpiozero.tools 。
LED 亮度随机变化示例:
from gpiozero import PWMLED
from gpiozero.tools import random_values
from signal import pause
led = PWMLED(4)
led.source = random_values()
led.source_delay = 0.1
pause()
Button 按下 LED 灭,松开亮的示例:
from gpiozero import PWMLED
from gpiozero.tools import random_values
from signal import pause
led = PWMLED(4)
led.source = random_values()
led.source_delay = 0.1
pause()
支持多个 Input device :
两个 button 都按下时,LED 亮,示例:
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()
all_values 为与的关系;any_values 为或的关系。
有的 devices 的 values 取值范围为 0 到 1,有的为 -1 到 1 (Motor, Servo 和 TonalBuzzer),可以使用 sin_values() :
from gpiozero import Motor, Servo, TonalBuzzer
from gpiozero.tools import sin_values
from signal import pause
motor = Motor(2, 3)
servo = Servo(4)
buzzer = TonalBuzzer(5)
motor.source = sin_values()
servo.source = motor
buzzer.source = motor
pause()
状态如下:
-1 到 0 | 0 到 1 | |
---|---|---|
motor | 反转,减速 | 正转,加速 |
servo | 左转 | 右转 |
buzzer | 最低 | 最高 |
7.3 Internal devices
gpiozero 提供了 internal devices,感觉像是内置函数。
8am 到 8pm lamp 亮,示例如下:
from gpiozero import Energenie, TimeOfDay
from datetime import time
from signal import pause
lamp = Energenie(1)
daytime = TimeOfDay(time(8), time(20))
lamp.source = daytime
lamp.source_delay = 60
pause()
(疑问:Energenie 东东???)
通过 DiskUsage 和 LEDBarGraph 显示磁盘使用的情况:
from gpiozero import DiskUsage, LEDBarGraph
from signal import pause
disk = DiskUsage()
graph = LEDBarGraph(2, 3, 4, 5, 6, 7, 8)
graph.source = disk
pause()
花园照明系统。晚上有人移动,led 亮,示例:
from gpiozero import LED, MotionSensor, LightSensor
from gpiozero.tools import booleanized, all_values
from signal import pause
garden = LED(2)
motion = MotionSensor(4)
light = LightSensor(5)
garden.source = all_values(booleanized(light, 0, 0.1), motion)
pause()
7.4 Composite devices
motor values 示例:
>>> from gpiozero import Robot
>>> robot = Robot(left=(14, 15), right=(17, 18))
>>> robot.value
RobotValue(left_motor=0.0, right_motor=0.0)
>>> tuple(robot.value)
(0.0, 0.0)
>>> robot.forward()
>>> tuple(robot.value)
(1.0, 1.0)
>>> robot.backward()
>>> tuple(robot.value)
(-1.0, -1.0)
>>> robot.value = (1, 1) # robot is now driven forwards
使用两个 potentiometers 来控制左右 motor 的速度:
from gpiozero import Robot, MCP3008
from gpiozero.tools import zip_values
from signal import pause
robot = Robot(left=(4, 14), right=(17, 18))
left_pot = MCP3008(0)
right_pot = MCP3008(1)
robot.source = zip_values(left_pot, right_pot)
pause()
涉及到反向, potentiometer values 从 0->1 修改为 -1->1:
from gpiozero import Robot, MCP3008
from gpiozero.tools import scaled
from signal import pause
robot = Robot(left=(4, 14), right=(17, 18))
left_pot = MCP3008(0)
right_pot = MCP3008(1)
robot.source = zip(scaled(left_pot, -1, 1), scaled(right_pot, -1, 1))
pause()