API-引脚
从 1.1 版本开始,GPIO Zero 库大致可以分为两部分:引脚和连接到引脚的设备。大部分文档侧重于设备,因为引脚处于大多数用户不关心的底层。然而,一些用户可能希望利用替代 GPIO 实现的功能,或者(将来)使用 GPIO 扩展芯片。这就是库的引脚部分的用途。
当你构造一个设备时,你传入一个引脚规格。这被传递给引脚 Factory,它将其转换为 Pin 实现。默认工厂可以通过 Device.pin_factory 查询(和更改)。然而,所有类(甚至内部设备)都在其构造函数中接受一个 pin_factory 关键字参数,允许在每个设备的基础上覆盖工厂(允许每个设备工厂的原因在 远程 GPIO 章节中变得明显)。
这在以下流程图中说明:
默认工厂在第一个设备初始化时构造;如果无法构造默认工厂(例如,因为没有安装 GPIO 实现,或者所有实现由于某种原因无法加载),则会在构造时引发 BadPinFactory 异常。
在导入 gpiozero 之后,直到构造 gpiozero 设备之前,引脚工厂是 None,但在第一次构造时,默认引脚工厂将生效:
pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from gpiozero import Device, LED
>>> print(Device.pin_factory)
None
>>> led = LED(2)
>>> Device.pin_factory
<gpiozero.pins.rpigpio.RPiGPIOFactory object at 0xb667ae30>
>>> led.pin_factory
<gpiozero.pins.rpigpio.RPiGPIOFactory object at 0xb6323530>
如上所述,在安装了 RPi.GPIO 库的树莓派上(假设没有设置环境变量),默认引脚工厂将是 RPiGPIOFactory。
在 PC 上(没有安装引脚库且没有设置环境变量),导入将成功,但尝试创建设备将引发 BadPinFactory:
ben@magicman:~ $ python3
Python 3.6.8 (default, Aug 20 2019, 17:12:48)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from gpiozero import Device, LED
>>> print(Device.pin_factory)
None
>>> led = LED(2)
...
BadPinFactory: Unable to load any default pin factory!
更改引脚工厂
可以通过为 GPIOZERO_PIN_FACTORY 环境变量指定值来替换默认引脚工厂。例如:
pi@raspberrypi:~ $ GPIOZERO_PIN_FACTORY=native python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from gpiozero import Device
>>> Device._default_pin_factory()
<gpiozero.pins.native.NativeFactory object at 0x762c26b0>
要为会话的其余部分设置 GPIOZERO_PIN_FACTORY,你可以 export 此值:
pi@raspberrypi:~ $ export GPIOZERO_PIN_FACTORY=native
pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gpiozero
>>> Device._default_pin_factory()
<gpiozero.pins.native.NativeFactory object at 0x762c26b0>
>>> quit()
pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gpiozero
>>> Device._default_pin_factory()
<gpiozero.pins.native.NativeFactory object at 0x762c26b0>
如果你将 export 命令添加到你的 ~/.bashrc 文件中,你还将为所有未来的会话设置默认引脚工厂。
如果设置了环境变量,将使用相应的引脚工厂,否则将依次尝试使用四个 GPIO 引脚工厂中的每一个。
下表列出了以下值以及相应的 Factory 和 Pin 类。工厂按默认尝试顺序列出。
| 名称 | 工厂类 | 引脚类 |
|---|---|---|
| lgpio | gpiozero.pins.lgpio.LGPIOFactory | gpiozero.pins.lgpio.LGPIOPin |
| rpigpio | gpiozero.pins.rpigpio.RPiGPIOFactory | gpiozero.pins.rpigpio.RPiGPIOPin |
| pigpio | gpiozero.pins.pigpio.PiGPIOFactory | gpiozero.pins.pigpio.PiGPIOPin |
| native | gpiozero.pins.native.NativeFactory | gpiozero.pins.native.NativePin |
如果你需要从脚本中更改默认引脚工厂,可以将 Device.pin_factory 设置为要使用的新工厂实例:
from gpiozero.pins.native import NativeFactory
from gpiozero import Device, LED
Device.pin_factory = NativeFactory()
# 这些现在将隐式使用 NativePin 而不是 RPiGPIOPin
led1 = LED(16)
led2 = LED(17)
或使用上面提到的 pin_factory 关键字参数:
from gpiozero.pins.native import NativeFactory
from gpiozero import LED
my_factory = NativeFactory()
# 这将为 led1 使用 NativePin 而不是 RPiGPIOPin
# 但 led2 将继续使用 RPiGPIOPin
led1 = LED(16, pin_factory=my_factory)
led2 = LED(17)
某些工厂可能从其他源获取默认信息。例如,要在名为 "remote-pi" 的远程 pi 上默认使用 gpiozero.pins.pigpio.PiGPIOPin 创建引脚,你可以在运行脚本时设置 PIGPIO_ADDR 环境变量:
$ GPIOZERO_PIN_FACTORY=pigpio PIGPIO_ADDR=remote-pi python3 my_script.py
像 GPIOZERO_PIN_FACTORY 值一样,这些也可以从你的 ~/.bashrc 脚本中 export。
机敏而调皮的读者可能会注意到可以混合工厂,例如为一个引脚使用 RPiGPIOFactory,为另一个引脚使用 NativeFactory。这是不受支持的,如果这导致你的脚本崩溃、你的组件失效或你的树莓派变成真正的树莓派,你只能怪自己。
合理使用多个引脚工厂的方法在 远程 GPIO 中给出。
模拟引脚
还有一个 MockFactory,它生成完全虚假的引脚。这最初是为希望在不必将物理设备连接到 Pi 的情况下为设备编写测试的 GPIO Zero 开发人员设计的。然而,事实证明,在没有 Pi 的情况下开发 GPIO Zero 脚本时,它们也很有用。此引脚工厂永远不会默认加载;必须明确指定,通过设置环境变量或在脚本中设置引脚工厂。例如:
pi@raspberrypi:~ $ GPIOZERO_PIN_FACTORY=mock python3
或:
from gpiozero import Device, LED
from gpiozero.pins.mock import MockFactory
Device.pin_factory = MockFactory()
led = LED(2)
你可以创建设备对象并按预期检查其值变化:
pi@raspberrypi:~ $ GPIOZERO_PIN_FACTORY=mock python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from gpiozero import LED
>>> led = LED(2)
>>> led.value
0
>>> led.on()
>>> led.value
1
你甚至可以控制引脚状态变化来模拟设备行为:
>>> from gpiozero import LED, Button
# 构造连接到模拟引脚 16 和 17 的几个设备,并链接设备
>>> led = LED(17)
>>> btn = Button(16)
>>> led.source = btn
# 最初按钮未"按下",因此 LED 应该关闭
>>> led.value
0
# 将引脚驱动为低电平(这是按下按钮时在电气上会发生的情况)
>>> btn.pin.drive_low()
# LED 现在打开
>>> led.value
1
>>> btn.pin.drive_high()
# 按钮现在"释放",因此 LED 应该再次关闭
>>> led.value
0
存在几个模拟引脚的子类,用于模拟其他各种事物(支持/不支持 PWM 的引脚、连接在一起的引脚、延迟后驱动为高电平的引脚等),例如,你必须使用 MockPWMPin 才能使用需要 PWM 的设备:
pi@raspberrypi:~ $ GPIOZERO_PIN_FACTORY=mock GPIOZERO_MOCK_PIN_CLASS=mockpwmpin python3
或:
from gpiozero import Device, LED
from gpiozero.pins.mock import MockFactory, MockPWMPin
Device.pin_factory = MockFactory(pin_class=MockPWMPin)
led = LED(2)
有兴趣的用户可以阅读 GPIO Zero 测试套件 以获取更多使用示例。
基类
Factory
引脚工厂的抽象基类。
关闭引脚工厂。这应该清理工厂操作的所有资源。它通常在脚本终止时调用。
创建一个 Pin 派生类的实例,表示指定的引脚。
释放所有 reserver 保留的引脚。这通常在 close() 期间调用,用于清理在构造期间进行的保留。
释放 reserver 对引脚 names 的保留。这通常在 close() 期间调用,用于清理在构造期间进行的保留。释放当前未持有的保留将被静默忽略(以允许在失败/部分构造后进行清理)。
调用此方法表示设备保留使用指定引脚 names 的权利。这应该在设备 构造期间完成。如果保留了引脚,你必须确保通过最终调用 release_pins() 来释放保留。
返回一个 SPI 接口的实例,用于指定的 SPI port 和 device,或用于指定的引脚(clock_pin、mosi_pin、miso_pin 和 select_pin)。只能使用其中一种方案;尝试将 port 和 device 与引脚号混合将引发 SPIBadArgs。
返回工厂的当前 ticks。参考点是未定义的,因此此方法的结果只有在与此方法返回的另一个值比较时才有意义。
时间的格式也是任意的,时间是否在特定持续时间后回绕也是如此。Ticks 只应使用 ticks_diff() 方法进行比较。
返回两个 ticks() 结果之间的时间(以秒为单位)。参数的指定顺序与公式 later - earlier 中的顺序相同,但结果保证以秒为单位,并且即使在调用 ticks() 之间 ticks "回绕",结果也保证为正。
返回一个 BoardInfo 实例(或派生类),表示此工厂生成的实例将连接到的板。
Pin
表示连接到某种形式控制器(无论是 GPIO、SPI、ADC 等)的引脚的抽象基类。
派生类应该覆盖属性的 getter 和 setter,以准确表示引脚的功能。派生类必须覆盖以下方法:
_get_info()_get_function()_set_function()_get_state()
派生类可以额外覆盖以下方法(如果适用):
close()output_with_state()input_with_pull()_set_state()_get_frequency()_set_frequency()_get_pull()_set_pull()_get_bounce()_set_bounce()_get_edges()_set_edges()_get_when_changed()_set_when_changed()
清理分配给引脚的资源。调用此方法后,此 Pin 实例不能再用于查询或控制引脚的状态。
将引脚的功能设置为"输入",并为引脚指定初始上拉。默认情况下,这等同于执行:
pin.function = 'input'
pin.pull = pull
但是,派生类可以覆盖此方法,以在配置引脚为输入和设置上拉/下拉之间提供尽可能小的延迟(这对于在某些配置中避免"毛刺"很重要)。
将引脚的功能设置为"输出",并为引脚指定初始状态。默认情况下,这等同于执行:
pin.function = 'output'
pin.state = state
但是,派生类可以覆盖此方法,以在配置引脚为输出和指定初始值之间提供尽可能小的延迟(这对于在低电平有效配置中避免"毛刺"很重要)。
边缘检测当前使用的抖动检测(消除)量,以秒为单位。如果当前未使用抖动检测,则为 None。
例如,如果 edges 当前为 "rising",bounce 当前为 5/1000(5ms),则下面的波形尽管有三个上升沿,但只会触发 when_changed 两次:
TIME 0...1...2...3...4...5...6...7...8...9...10..11..12 ms
bounce elimination |===================| |==============
HIGH - - - - > ,--. ,--------------. ,--.
| | | | | |
| | | | | |
LOW ----------------' `-' `-' `-----------
: :
: :
when_changed when_changed
fires fires
如果引脚不支持边缘检测,尝试设置此属性将引发 PinEdgeDetectUnsupported。如果引脚支持边缘检测,类必须实现抖动检测,即使只是在软件中。
将触发执行分配给 when_changed 的函数或绑定方法的边缘。这可以是字符串 "both"(默认)、"rising"、"falling" 或 "none" 之一:
HIGH - - - - > ,--------------.
| |
| |
LOW --------------------' `--------------
: :
: :
Fires when_changed "both" "both"
when edges is ... "rising" "falling"
如果引脚不支持边缘检测,尝试设置此属性将引发 PinEdgeDetectUnsupported。
引脚的 PWM 实现的频率(以 Hz 为单位),如果当前未使用 PWM,则为 None。此值始终默认为 None,并且可以更改某些引脚类型以激活或停用 PWM。
如果引脚不支持 PWM,尝试将此设置为 None 以外的值时将引发 PinPWMUnsupported。
引脚的功能。此属性是一个字符串,指示引脚的当前功能或用途。通常这是字符串 "input" 或 "output"