品味树莓派:GPIO Zero库进阶使用

2023-10-27

目的

GPIO Zero库在传统的GPIO使用基础上还提供了很多的进阶功能,本文将对其中的一些内容进行摘录说明。

进阶功能

Source/Values模式

GPIO Zero库提供了一种Source/Values的使用模式,有点类似于某些些上位机界面开发时用的
Binding,为的是降低代码的耦合度,减少程序员的工作量。
举个例子,如果你要通过Button来控制LED,当Button按下时点亮LED,按钮松开时熄灭LED。传统情况下你的代码大概是下面这个样子的:

from gpiozero import Button, LED
from signal import pause

led = LED(17)
button = Button(2)

button.when_pressed = lambda : led.on()
button.when_released = lambda : led.off()

pause()

通过GPIO Zero库的Source/Values模式,你的代码就可以是下面那样的了:

from gpiozero import Button, LED
from signal import pause

led = LED(17)
button = Button(2)

led.source = button # 关联button和led,当button活动时(被按下时)led活动(点亮)

pause()

可以看到用上Source/Values模式后大大简化了代码,不需要用代码检测数据源变化再做出响应,这一切都会在底层自动完成。这个例子中Button的状态是Values,实际使用中我们可以用各种东西当作Values,比如下面例子:
在这里插入图片描述
上图中通过CPU温度来调节LED亮度。
默认情况下CPUTemperature类将0 ~ 100摄氏度映射成0 ~ 1的值,实际使用时可以手动调整温度区间,比如使用 temp = CPUTemperature(min_temp=40, max_temp=90) 会将40 ~ 90摄氏度映射成0 ~ 1的值。

前面例子中数据都是来自库中类的对象,其实我们也可以用自己的可迭代数据作为Values:

from gpiozero import LED
from signal import pause

data = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]

led = LED(17)
led.source_delay = 1 # 设置数据驱动刷新速度为1秒一次(默认为0.01秒)
led.source = data

pause()

下面例子是使用迭代器作为Values:

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()

上面例子都是一个值来驱动一个对象,我们也可以用多个值来驱动多个对象:

from gpiozero import LED, Button
from gpiozero.tools import all_values, any_values
from signal import pause

led1 = LED(2)
led2 = LED(4)
btn1 = Button(20)
btn2 = Button(21)

led1.source = all_values(btn1, btn2) # 两个按钮都按下时点亮led1
led2.source = any_values(btn1, btn2) # 任意按钮都按下时点亮led2

pause()

更多内容可以参考:https://gpiozero.readthedocs.io/en/stable/source_values.html

Device Source Tools

这一章节的内容是用来配合上一章节Source/Values使用的,上一章节说了Source/Values关系绑定前可以做各种处理,GPIO Zero库中提供了很多工具用来方便的做出这些处理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
GPIO Zero库中提供的工具蛮多,每一个都写了例程,可以参考下面连链接:
https://gpiozero.readthedocs.io/en/stable/api_tools.html

高级设备类库

GPIO Zero库对于IO口的管理控制上有很多方便的功能,这章节就介绍下其中的 LEDBoardButtonBoard 两项功能。
在前面文章介绍LED、PWMLED、Button的时候都是单个的进行声明、控制与应答的,在GPIO Zero库中我们除了单个控制外还可以整组的控制,主要由下面两个类实现相关功能:

  • class gpiozero.LEDBoard(*pins, pwm=False, active_high=True, initial_value=False, pin_factory=None, **named_pins)
  • class gpiozero.ButtonBoard(*pins, pull_up=True, active_state=None, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None, **named_pins)

观察上面的构造函数会发现它们和LED、PWMLED、Button的构造函数是很像的,如果你去查看类库可以发现不光是构造函数,其它的属性和方法等两者也是非常相似的,实际上两者的具体操作使用是差不多的。下面进行简单的演示:

from gpiozero import LEDBoard
from time import sleep

leds = LEDBoard(2, 3, 4, 17) # GPIO2 3 4 17上分别接了LED

def printandsleep():
    print('{} {} {} {}'.format(leds[0].value, leds[1].value, leds[2].value, leds[3].value))
    sleep(2)

leds.on() # 点亮所有LED
printandsleep()

leds.off() # 熄灭所有LED
printandsleep()

leds.on(0) # 点亮第一个LED(GPIO2),同leds[0].on()
printandsleep()

leds[-1].on() # 点亮最后一个LED(GPIO17),同leds.on(-1),这里也等同于leds.on(3)
printandsleep()

leds.on(1, 2) # 点亮第2、3个LED(GPIO3、GPIO4)
printandsleep()

for led in leds[2:]:  # 选择第3、4个LED(GPIO4、GPIO17)
    led.off()
printandsleep()

for led in leds[::2]: #从0开始步进为2选择LED,这里相当于第0、2个
    led.toggle() # 翻转LED
printandsleep()

在这里插入图片描述
上面是基础的LED操作,下面再演示下PWMLED和Button的操作:

from gpiozero import LEDBoard, ButtonBoard
from time import sleep
from signal import pause

leds = LEDBoard(pwm=True, led0=2, led1=3) # GPIO2 3上分别接了LED, 相当于leds = LEDBoard(2, 3, pwm=true)

leds.led0.pulse() # 使led0以呼吸灯方式闪烁
leds.led1.value = 0.5 # 以50%占空比点亮led1
print('{} {}'.format(leds.led0.value, leds.led1.value))
sleep(3)

btns = ButtonBoard(17, 27) # GPIO17 27上分别接了Button
leds.source = btns.values # 该行将led0与第一个button绑定(GPIO17)、将led1与第二个button绑定(GPIO27)
pause()

上面代码中先接了两个LED,用PWM方式进行了控制,然后声明了两个Button,将LED和Button以上面的Source/Values方式进行绑定,分别按下按钮,LED分别会有响应。

这个章节可以说的内容其实挺多,但是其中很多东西都是基于具体的某个电路或成品的电路模块来设计的,这里就不进一步展开了,更多内容可以参考下面链接:
https://gpiozero.readthedocs.io/en/stable/recipes_advanced.html
https://gpiozero.readthedocs.io/en/stable/api_boards.html

异常

GPIO Zero库中设计了对相关操作异常的反馈,可以使用 try...except... 语句进行捕获处理:
在这里插入图片描述
GPIO Zero库定义了哪些异常可以参考下面链接:
https://gpiozero.readthedocs.io/en/stable/api_exc.html

Internal Devices

GPIO Zero库中提供了几个Internal Devices,用于获取树莓派的一些信息,下面分别列举进行简单说明:

  • TimeOfDay
    class gpiozero.TimeOfDay(start_time, end_time, *, utc=True, pin_factory=None)
    用来标示一天中某一时间段处于活动状态,start_time和end_time分别表示设备激活起始与结束时间,utc True表示使用UTC时间、False表示使用本地时间。
    TimeOfDay对象有value属性,其值为True表示处于start_time和end_time时间之间。

  • PingServer
    class gpiozero.PingServer(host, *, pin_factory=None)
    ping host,如果能ping通则其value属性为True。

  • CPUTemperature
    class gpiozero.CPUTemperature(sensor_file='/sys/class/thermal/thermal_zone0/temp', *, min_temp=0.0, max_temp=100.0, threshold=80.0, pin_factory=None)
    获取CPU温度、对温度进行数值映射、设置报警阈值。

  • LoadAverage
    class gpiozero.LoadAverage(load_average_file='/proc/loadavg', *, min_load_average=0.0, max_load_average=1.0, threshold=0.8, minutes=5, pin_factory=None)
    设置将CPU平均负载映射为某一只区间,同时设置阈值,value值高于阈值时以活动表示。

  • DiskUsage
    class gpiozero.DiskUsage(filesystem='/', *, threshold=90.0, pin_factory=None)
    设置阈值,当磁盘空间使用率超过该值时以活动表示。

下面是简单的测试例子:

from gpiozero import TimeOfDay, PingServer, CPUTemperature, LoadAverage, DiskUsage
from datetime import time

am = TimeOfDay(time(10), time(11), utc=False)
pm = TimeOfDay(time(20), time(21), utc=False)
print('TimeOfDay 10~11h: {}'.format(am.value))
print('TimeOfDay 20~21h: {}'.format(pm.value))

google = PingServer('google.com')
baudu = PingServer('baidu.com')
print('Ping google: {}'.format(google.value))
print('Ping baudu: {}'.format(baudu.value))

temp = CPUTemperature()
print('CPU temperature: {}C'.format(temp.temperature))
print('CPU temperature value: {}'.format(temp.value))

la = LoadAverage()
print('LoadAverage {}'.format(la.is_active))
print('LoadAverage {}'.format(la.value))

disk = DiskUsage()
print('DiskUsage {}'.format(disk.is_active))
print('DiskUsage {}'.format(disk.value))

在这里插入图片描述
这一节介绍的很多内容其实就算不依赖GPIO Zero库提供的这些工具我们也有别的方法可以获取,不过使用上面的工具最大的好处是直接可以在Source/Values模式中作为Values使用。更多详细说明可以参考下面链接:
https://gpiozero.readthedocs.io/en/stable/api_internal.html

Pin Factory

GPIO Zero库对很多GPIO相关功能进行了封装,但它自己并不实现GPIO口底层的操作,而是借由一些现有的库来实现,Pin Factory就是用来连接上层和底层库的。
在这里插入图片描述
默认情况下大部分GPIO Zero库功能都是由RPi.GPIO库来实现的,你也可以通过Pin Factory来更改所使用的库,更改的方式很多,比如在终端中通过命令更改:

# 修改默认库为native
export GPIOZERO_PIN_FACTORY=native

你也可以在python代码中更改:

from gpiozero.pins.native import NativeFactory
from gpiozero import Device, LED

Device.pin_factory = NativeFactory() # 使用native库

led1 = LED(16) # 这里的LED就用了native库

或者也可以用下面方式设置:

from gpiozero.pins.native import NativeFactory
from gpiozero import LED

my_factory = NativeFactory()

led1 = LED(16, pin_factory=my_factory) # 这里的LED就用了native库

下面是目前可选用的库:

Name Factory class Pin class
rpigpio gpiozero.pins.rpigpio.RPiGPIOFactory gpiozero.pins.rpigpio.RPiGPIOPin
rpio gpiozero.pins.rpio.RPIOFactory gpiozero.pins.rpio.RPIOPin
pigpio gpiozero.pins.pigpio.PiGPIOFactory gpiozero.pins.pigpio.PiGPIOPin
native gpiozero.pins.native.NativeFactory gpiozero.pins.native.NativePin

除上面外其实还有一个库 Mock - gpiozero.pins.mock.MockFactory 这个库是个虚拟的库,主要用于没有树莓派的时候开发测试使用。

Pin Factory这个功能主要是为了提供更多可能和个性化选择,另外在远程控制GPIO的时候也需要用到这个功能。 更详细说明可以参考下面链接:
https://gpiozero.readthedocs.io/en/stable/api_pins.html

总结

上文介绍的GPIO Zero库的一些特性更加贴近用户和上位机软件开发者,确实的可以带来很多便利性。GPIO Zero库进阶使用功能非常多,本文无法一一进行介绍,更多内容可以参考下面官方文档:
https://gpiozero.readthedocs.io/en/stable/index.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

品味树莓派:GPIO Zero库进阶使用 的相关文章

随机推荐

  • Obsidian利用插件Remotely-save实现超低成本全平台云笔记

    Obsidian作为一个笔记软件 是目前最满足我需求的了 本地存储文件 Markdown格式作为基础 双链支持 以及好用的搜索等功能 基本实现了我对一款文字笔记软件的要求 但是Obsidian的收费价格确实不低 虽然软件本身的所有功能基本免
  • Visual Unit 简明教程

    载自 http www vckbase com index php wv 1270 VU1 0 简介 Visual Unit 简称VU 是新一代单元测试工具 功能强大 使用简单 完全可视化 不需编写测试代码 VU的测试结果使程序行为一目了然
  • UNIX系统被删文件的恢复策略

    与DOS Windows不同 UNIX文件被删除后很难恢复 这是由UNIX独特 的文件系统结构决定的 UNIX文件目录不像DOS Windows那样 文 件即使被删除之后仍保存有完整的文件名 文件长度 始簇号 即 文件占有的第一个磁盘块号
  • TTF、TOF、WOFF 和 WOFF2 的相关概念

    前言 在上一篇文章中 我引入了 TTF 格式的字体文件来解决各平台字体表现不统一的问题 但其实那不是最优解决方案 因为字体文件不止有 TTF 格式 常见的字体格式还有 OTF WOFF 和 WOFF2 等 今天 我来总结一下最常见字体格式的
  • Bootstarp学习教程(14) 其他相关组件(2)

    页面标题 简单的h1样式 可以适当地分出空间且分开页面中的章节 像其它组件一样 它可以使用h1的默认small元素 div class page header h1 Example page header h1 div
  • 【Web前端】彼岸の花——网上花店(网页制作)

    本篇博客我们来做一个好看又简单的前端案例 彼岸的花网页界面 这里是代码和网页素材 需要的自取 提取码 7777 https pan baidu com s 1PH0TCuLpapPlJnczDcGkig pwd 7777 at 166988
  • 面经获取

    分享下面文字和图片到朋友圈或者QQ空间 所有人可见 不能是小号 时间保留一天 或者发一个大于100人的群聊保留2分钟以上也行 但你如果发群里可能会被踢 提醒你一下 时间到了截图即可 面经整理不易 大家不要作弊啊 如果有父母啥的不能看 那么你
  • linux ssh出现Unable to negotiate with 192.168.1.1 port 22: no matching cipher found. Their offer......

    问题描述 linux ssh出现Unable to negotiate with 192 168 1 1 port 22 no matching cipher found Their offer aes128 cbc des cbc 解决办
  • VS2019安装配置QT插件(qt-vsaddin)

    1 介绍 Windows的Qt开发 一般采用Visual Studio安装Qt插件的方法开发Qt程序 毕竟VS开发工具还是比QtCreator开发工具强大 好用的多 本教程采用VS2019安装配置Qt插件 qt vsaddin msvc20
  • SpringMVC 从入门到精通系列 03 —— 常用注解

    文章目录 1 RequestParam 注解 2 RequestBody 注解 3 PathVariable 注解 4 RequestHeader 注解 了解 5 CookieValue 注解 了解 6 ModelAttribute 注解
  • Vuex常见面试题

    1 vuex是什么 怎么使用 哪种功能场景使用它 Vuex 是一个专为 Vue js 应用程序开发的状态管理插件 公共数据库 当项目遇到以下两种场景时 1 多个组件依赖于同一状态时 2 来自不同组件的行为需要变更同一状态 解决的问题 多个视
  • Python北理工_turtle绘画

    模块1 turtle库的使用 海龟绘图法 turtle setup 调整绘图窗体在电脑屏幕中的布局 空间坐标系 角度坐标系 代码示例 import turtle turtle left 45 turtle fd 150 turtle rig
  • C++11中std::condition_variable的使用

  • Java中如何创建一个枚举Enum类

    从jdk5出现了枚举类后 定义一些字典值可以使用枚举类型 枚举常用的方法是 values 对枚举中的常量值进行遍历 valueof String name 根据名称获取枚举类中定义的常量值 要求字符串跟枚举的常量名必须一致 获取枚举类中的常
  • Node创建应用

    github地址 https github com lily1010 Node learn tree master test 一 使用node的意义 使用 Node js 时 我们不仅仅 在实现一个JS应用 同时还实现了整个 HTTP 服务
  • 国际版阿里云/腾讯云免费:阿里云产品-弹性核算简介(依据官网转载)

    阿里云产品 弹性核算简介 依据官网转载 云服务器ECS Elastic Compute Service 是阿里云供给的功能杰出 安稳牢靠 弹性扩展的IaaS Infrastructure as a Service 等级云核算服务 实例 等同
  • Java复习-16-多态性

    多态性 在Java中对于多态性有两种实现的模式 方法的多态性 方法的重载 同一个方法名称可以根据传入的参数类型和个数的不同 进行不同的处理 方法的覆写 同一个方法可能根据使用子类的不同 由不同的实现 对象的多态性 父子实例之间的转换处理 有
  • 机器学习类比赛中经常用到的一些函数和知识点

    文章目录 豆瓣 清华源命令 pip升级命令 画图plot汉字显示不出 python控制台打印结果省略的问题 enumerate pandas描述数据基本分布情况 isin 判断值是否存在 某两个特征之间的关联性 np corrcoef fo
  • GLib学习

    Gstreamer 基础 学习博客 一 glib glib介绍 1 1 类型介绍 glib的类型定义在gtypes h文件中 关键定义如下 1 1 1 不规则类型 gboolean gpointer gconstpointer gchar
  • 品味树莓派:GPIO Zero库进阶使用

    文章目录 目的 进阶功能 Source Values模式 Device Source Tools 高级设备类库 异常 Internal Devices Pin Factory 总结 目的 GPIO Zero库在传统的GPIO使用基础上还提供