品味树莓派:GPIO Zero库使用入门

目的

树莓派有很多GPIO口可供用户使用,官方同时也提供了一些方式来操作这些IO口,其中目前主要推荐的是基于Python的GPIO Zero库,本文将简单介绍该库的基础使用方法。

基础说明

GPIO Zero库是树莓派官方目前推荐的用于操作树莓派上GPIO口的Python库,该库最早是在RPi.GPIO库之上开发而来的,现在默认情况下也有许多功能是基于RPi.GPIO库实现的,不过用户可以自行设置其它库用在底层。
GPIO Zero库将常用的功能进行封装(LED、Button、Motor……),使一般用户和软件开发者更加容易实现需要用到GPIO口的功能,而不需要像RPi.GPIO库一样去了解GPIO口的输入输出、上下拉电阻等底层硬件相关的参数。
GPIO Zero库官方文档:https://gpiozero.readthedocs.io/en/stable/

可以看到官方文档的基础说明里都是具体的应用
可以看到官方文档的基础说明里都是具体的LED、Button、Motor等应用

带图形界面的Raspbian系统默认就安装了GPIO Zero库,Raspbian Lite上可以使下面命令来安装该库:

sudo apt update
sudo apt install python3-gpiozero

其它树莓派上的系统可以使下面命令来安装该库:

sudo pip3 install gpiozero

使用过程中需要的树莓派GPIO口定义可以参考下图:
在这里插入图片描述

入门使用

GPIO Zero库中具体实现的功能还是比较多的,这里挑选一部分介绍演示。

LED

控制LED是嵌入式入门实验,GPIO Zero库可以使用LED类来控制LED,首先按下图连接LED:
在这里插入图片描述
上图中左侧为实物连接,右侧为原理图,电路中的电阻是用来限制电流大小的。
可以使用下面代码来控制LED亮灭交替闪烁:

from gpiozero import LED # 引入LED类
from time import sleep

red = LED(17) # 声明LED对象red,该对象连接至树莓派GPIO17引脚

while True: # 使下面程序持续循环运行
    red.on() # 点亮LED
    sleep(1) # 延时1秒
    red.off() # 熄灭LED
    sleep(1) # 延时1秒

或者用下面代码也能实现一样的效果:

from gpiozero import LED # 引入LED类
from signal import pause

red = LED(17) # 声明LED对象red,该对象连接至树莓派GPIO17引脚

red.blink() # 使LED反复亮灭

pause() # 暂停当前脚本的进程
        #(使脚本不会结束,这样red.blink()就会一直运行,不会因为脚本结束而被释放)

在这里插入图片描述
上面是简单的演示,每隔一秒分别开关了LED,同时打印了其状态。

LED类更多说明如下:

  • class gpiozero.LED(pin, *, active_high=True, initial_value=False, pin_factory=None)
    LED构造函数,输入参数如下:
    pin: GPIO口编号(填入数字或字符串均可);
    active_high: LED是否在GPIO口电平为High时点亮,默认True表示GPIO口输出高电平时点亮LED;
    initial_value: 初始值,默认False表示初始不点亮LED;
    pin_factory: 一般不用到,以后会单独进行讲解,下同;
  • blink(on_time=1, off_time=1, n=None, background=True)
    控制LED闪烁,输入参数如下:
    on_time: 一次闪烁中LED点亮持续时间,单位秒;
    off_time: 一次闪烁中LED熄灭持续时间,单位秒;
    n: 闪烁次数,默认None表示LED将持续闪烁;
    background: 默认True表示该动作将新开一个线程运行,函数会立即返回。如果设置为False,函数将阻塞在次直到闪烁完成才返回;
  • off() 熄灭LED;
  • on() 点亮LED;
  • toggle() 翻转LED状态;
  • is_lit 以布尔值方式表示LED是否点亮状态;
  • pin 以字符串形式表示LED连接的pin编号;
  • value 以数值形式表示LED是否点亮状态;

PWMLED

上面的LED只是单纯的点亮或熄灭,GPIO Zero库中还可以使用PWM来调节KED亮度,或是实现呼吸灯功能,比如下面代码:

from gpiozero import PWMLED # 引入PWMLED类
from time import sleep
from signal import pause

led = PWMLED(17) # 声明PWMLED对象led,该对象连接至树莓派GPIO17引脚

led.value = 1 # 以100%亮度点亮LED(这里用了特别的方式,以后会单独进行讲解)
sleep(2) # 延时2秒
led.value = 0.5 # 以50%亮度点亮LED
sleep(2) # 延时2秒
led.value = 0 # 熄灭LED
sleep(2) # 延时2秒

led.pulse() # 使LED以呼吸灯方式闪烁

pause()

PWMLED类更多说明如下:

  • class gpiozero.PWMLED(pin, *, active_high=True, initial_value=0, frequency=100, pin_factory=None)
    LED构造函数,输入参数如下:
    pin: GPIO口编号(填入数字或字符串均可);
    active_high: LED是否在GPIO口电平为High时点亮,默认True表示GPIO口输出高电平时点亮LED;
    initial_value: 初始值,可选0和1之间的值,0表示熄灭,1表示完全点亮;
    frequency: PWM频率,默认值100表示100Hz;
  • blink(on_time=1, off_time=1, fade_in_time=0, fade_out_time=0, n=None, background=True)
    控制LED闪烁,输入参数如下:
    on_time: 一次闪烁中LED完全点亮持续时间,单位秒;
    off_time: 一次闪烁中LED完全熄灭持续时间,单位秒;
    fade_in_time: 一次闪烁中LED从熄灭到点亮的过程时间,单位秒;
    fade_out_time: 一次闪烁中LED从点亮到熄灭的过程时间,单位秒;
    n: 闪烁次数,默认None表示LED将持续闪烁;
    background: 默认True表示该动作将新开一个线程运行,函数会立即返回。如果设置为False,函数将阻塞在次直到闪烁完成才返回;
  • off() 熄灭LED;
  • on() 点亮LED;
  • pulse(fade_in_time=1, fade_out_time=1, n=None, background=True)
    控制LED闪烁,输入参数如下:
    fade_in_time: 一次闪烁中LED从熄灭到点亮的过程时间,单位秒;
    **fade_out_time:**一次闪烁中LED从点亮到熄灭的过程时间,单位秒;
    n: 闪烁次数,默认None表示LED将持续闪烁;
    background: 默认True表示该动作将新开一个线程运行,函数会立即返回。如果设置为False,函数将阻塞在次直到闪烁完成才返回;
  • toggle() 翻转LED状态至 1 - value
  • is_lit 以布尔值方式表示LED是否点亮状态;
  • pin 以字符串形式表示LED连接的pin编号;
  • value 返回当前LED的PWM占空比值;

Button

外接物理按键是一个非常常用的功能,GPIO Zero库中直接封装了一个Button类,这个类的使用非常方便,首先按照下图方式连接设备:
在这里插入图片描述
按上图连接电路,等下再在程序里启用GPIO2的内部上拉电阻,这样的话按钮在未被按下时GPIO2上为高电平,当按钮被按下后会变为低电平。
使用下面代码可以简单进行测试:

from gpiozero import Button # 引入Button类

button = Button(2) # 声明Button对象button,该对象连接至树莓派GPIO2引脚

button.wait_for_press() # 等待按钮被按下
print(button.is_pressed) # 当按钮被按下时触发该行

button.wait_for_release() # 等待按钮被松开
print(button.is_pressed) # 当按钮被松开时触发该行

在这里插入图片描述
上面是个简单的演示,实际操作中不太会用wait_for_press()和wait_for_release(),更多的会用事件与回调函数形式来处理按钮按下松开时的动作:

from gpiozero import Button # 引入Button类
from signal import pause

def btn_held(): # 回调函数
    print('held:{} - {}'.format(button.is_pressed, button.is_held))
    print('{} - {}'.format(button.pressed_time, button.held_time))
    
def btn_pressed(): # 回调函数
    print('pressed:{} - {}'.format(button.is_pressed, button.is_held))
    print('{} - {}'.format(button.pressed_time, button.held_time))

def btn_released(): # 回调函数
    print('released:{} - {}'.format(button.is_pressed, button.is_held))
    print('{} - {}'.format(button.pressed_time, button.held_time))

button = Button(2) # 声明Button对象button,该对象连接至树莓派GPIO2引脚

button.when_held = btn_held # 注册按钮长按事件回调函数
button.when_pressed = btn_pressed # 注册按钮按下事件回调函数
button.when_released = btn_released # 注册按钮松开事件回调函数

pause()

在这里插入图片描述
上面演示了基础的回调函数功能,事实上按钮事件的回调函数在触发时还可以传入Button对象,这在多个按钮绑定同一个回调函数的时候挺好用,可以知道具体是哪个按钮触发了该动作:

from gpiozero import Button # 引入Button类
from signal import pause

def btn_callback(btn): # 回调函数
    print(btn.pin) # 打印触发该函数的Button对象连接的GPIO编号

button = Button(2) # 声明Button对象button,该对象连接至树莓派GPIO2引脚

button.when_pressed = btn_callback # 注册按钮按下事件回调函数

pause()

在这里插入图片描述

Button类更多说明如下:

  • class gpiozero.Button(pin, *, pull_up=True, active_state=None, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None)
    Button构造函数,输入参数如下:
    pin: GPIO口编号(填入数字或字符串均可);
    pull_up: 内部上下拉电阻设置,True启用内部上拉,False启用内部下来,None不启用上下拉;
    active_state: 如果为True,则IO外部为高时软件显示该IO口为高,如果为False,则IO外部为高时软件显示该IO口为低。当pull_up不为None时该值将自动设置;
    bounce_time: 软件消抖时间,None则为不启用软件消抖;
    hold_time: 按下按钮后直到触发when_held的时间,单位秒;
    hold_repeat: 如果为True,则只要按钮持续被按下when_held会每隔hold_time时间持续被触发,如果为False,则when_held只会触发一次;
  • wait_for_press(timeout=None) 等待按钮被按下,timeout为超时时间,单位秒;
  • wait_for_release(timeout=None) 等待按钮被释放,timeout为超时时间,单位秒;
  • pressed_time 从按钮被按下开始持续经过的时间;
  • held_time 从when_held触发开始按钮被持续按下的时间;
  • is_held 如果该值为True,则说明按钮至少被按下hold_time秒;
  • is_pressed 如果按钮被按下该值为True,否则为False;
  • pin 以字符串形式表示LED连接的pin编号;
  • value 如果按钮被按下该值为1,否则为0;
  • when_held 当按钮被按下hold_time后触发的回调函数,填写None则禁用该事件;
  • when_pressed 当按钮被按下时触发的回调函数,填写None则禁用该事件;
  • when_released 当按钮被松开时触发的回调函数,填写None则禁用该事件;

更多入门例程

GPIO Zero库文档中提供了非常多的常用的元器件、传感器、执行器等的例程,比如人体红外传感器、超声波测距传感器、电机等等。更多内容可以参考官方文档:
https://gpiozero.readthedocs.io/en/stable/recipes.html
注:GPIO Zero官方例程中有很多内容是基于特定某个电路或电路模块而来的,请根据自己的实际情况进行阅读。

类基础说明

GPIO Zero库中各个类的关系如下图(点击看大图):
在这里插入图片描述
上图中深蓝色的是实体类、浅蓝色的是抽象类、紫色的是mixin类。越靠近右边的越具体、越接近用户,比如LED、Button等。
从上图可以看到LED和Buzzer都是基于DigitalOutputDevice类的(如果你去看源码的话就会发现LED类几乎就只是DigitalOutputDevice类换了个名称而已),该类用于控制GPIO口数字输出,如果你想单独控制GPIO口用作数字输出就可以直接用该类,参考下面例子:
在这里插入图片描述
同样的如果你想单独控制GPIO口用作数字输入就可以使用上图中DigitalInputDevice类。其它情况同理,可以在上图中找到合适的类使用。相关的类说明可以从参考官方文档中以 API - 开头的相关章节中查询:
在这里插入图片描述
当然对于Python而言库写的好的话用help方法也很方便:
在这里插入图片描述

注意事项

GPIO Zero库中的对象在被释放时受控的GPIO口会恢复到系统启动后的初始状态。除系统自动释放外你也可以使用close()方法手动进行释放。

总结

GPIO Zero库使用起来还是比较简单的,特别适合没有硬件基础的用户使用,更多内容可以参考下面链接:
https://github.com/gpiozero/gpiozero

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值