官网地址:http://gpiozero.readthedocs.io/en/stable/recipes.html
环境:UbuntuMeta-16.04
树莓派:3代B型
2、基本方法(Basic Recipes)
下面演示了GPIO Zero库的一些功能,注意的是这些方法都是在python3下编写的,在python2下可能有用也可能没有用!
2.1 导入GPIO Zero
使用GPIO Zero库有两种方式
2.1.1 单独导入GPIO Zero库的某个类
导入 GPIO Zero 的 Button :
from gpiozero import Button
现在 Button 就可以直接在脚本中使用:
button = Button(2) #2为Button的引脚
2.1.2 完整导入GPIO Zero库
或者,导入整个GPIO Zero库:
import gpiozero
在这种情况下,GPIO Zero中对项目的所有引用都必须加上前缀(gpiozero):
button = gpiozero.Button(2) #2为Button的引脚
2.2. Pin 编号
该库使用Broadcom(BCM)引脚编号作为GPIO引脚,而不是物理(BOARD)编号。 与RPi.GPIO库不同,这是不可配置的。
2.3 开关一个LED
不断的打开和关闭LED灯
from gpiozero import LED
from time import sleep
red = LED(17) #led的正极接GPIO17
while True:
red.on() #开灯
sleep(1)
red.off() #关灯
sleep(1)
或者也可以两一种写法:
from gpiozero import LED
from signal import pause
red = LED(17) #led的正极接GPIO17
2.4 改变LED的亮度
任何常规LED都可以使用PWM(脉冲宽度调制)设置其亮度值。 在GPIO Zero中,可以使用PWMLED来实现,PWMLED的值从0到1:
from gpiozero import PWMLED
from time import sleep
led = PWMLED(17)
while True:
led.value = 0 # 灭
sleep(1)
led.value = 0.5 # 半亮
sleep(1)
led.value = 1 # 全亮
sleep(1)
类似于连续闪烁,PWMLED可以脉冲(连续淡入和淡出),以下实现呼吸灯的效果:
from gpiozero import PWMLED
from signal import pause
led = PWMLED(17)
led.pulse() #呼吸灯的效果
pause()
2.5 加入一个按钮
按钮的连接如下图
检查是否按下了按钮:
from gpiozero import Button
button = Button(2)
while True:
if button.is_pressed:
print("按钮已经按下")
else:
print("按钮没有被按下")
一直等待按钮被按下:
from gpiozero import Button
button = Button(2)
button.wait_for_press() #等待按钮被按下
print("按钮已经按下")
每次按下按钮的时候运行一个方法:
from gpiozero import Button
from signal import pause
def say_hello():
print("Hello!")
button = Button(2)
button.when_pressed = say_hello #当被按下时执行 say_hello 方法,注意不能写为say_hello()
同样的,按钮被释放时也可以执行一个方法:
from gpiozero import Button
from signal import pause
def say_hello():
print("Hello!")
def say_goodbye():
print("Goodbye!")
button = Button(2)
button.when_pressed = say_hello #当被按下时执行 say_hello 方法
2.6 使用一个按钮控制led灯
按下按钮时打开LED:
from gpiozero import LED, Button
from signal import pause
led = LED(17) #定义一个led灯
button = Button(2) #定义一个button
button.when_pressed = led.on #开灯
button.when_released = led.off #关灯
pause()
或者:
from gpiozero import LED, Button
from signal import pause
led = LED(17) #定义一个led灯
2.7 按钮控制摄像头
当按下按钮时触发 PiCamera 拍照,使用 when_pressed = camera.capture 的写法是无效,因为capture()方法需要输出参数。
但是,这可以使用不需要参数的自定义函数来实现:
from gpiozero import Button
from picamera import PiCamera
from datetime import datetime
from signal import pause
button = Button(2)
camera = PiCamera()
def capture():
ctime = datetime.now().isoformat()
camera.capture('/home/pi/%s.jpg' % ctime) #保存图片
button.when_pressed = capture
pause()
另外可以使用一个按钮来启动和停止相机预览,另一个按钮用来拍照:
from gpiozero import Button
from picamera import PiCamera
from datetime import datetime
from signal import pause
left_button = Button(2)
right_button = Button(3)
camera = PiCamera()
def capture():
ctime = datetime.now().isoformat()
camera.capture('/home/pi/%s.jpg' % ctime)
left_button.when_pressed = camera.start_preview
left_button.when_released = camera.stop_preview
right_button.when_pressed = capture
pause()
2.8 实现按钮关机
Button类还提供了在按钮按住一段给定时间后运行函数的功能。
下面的示例是,当按钮按住2秒时,将关闭树莓派:
from gpiozero import Button
from subprocess import check_call
from signal import pause
def shutdown():
check_call(['sudo', 'poweroff']) #运行shell
shutdown_btn = Button(17, hold_time=2) #定义按钮,以及持续时间
shutdown_btn.when_held = shutdown
pause()
2.9 LEDBoard(灯组)
可以使用LEDBoard访问LED组合灯:
from gpiozero import LEDBoard
from time import sleep
from signal import pause
leds = LEDBoard(5, 6, 13, 19, 26) #定义一组led灯,该组由引脚分别为5, 6, 13, 19, 26的5个led组成
leds.on() #全亮
sleep(1)
leds.off() #全灭
sleep(1)
leds.value = (1, 0, 1, 0, 1) #1,3,5亮,2,4灭
sleep(1)
leds.blink() #全部闪烁
pause()
使用带有pwm = True的LEDBoard,可以控制每个LED的亮度:
from gpiozero import LEDBoard
from signal import pause
leds = LEDBoard(5, 6, 13, 19, 26, pwm=True)
leds.value = (0.2, 0.4, 0.6, 0.8, 1.0) #单独设置每个led的亮度
pause()
在高级LEDBoard方法中,可以看到更多LEDBoard示例。
2.10 LEDBarGraph(柱状图)
可以使用LEDBarGraph将LED组合为柱状图:
from gpiozero import LEDBarGraph
from time import sleep
graph = LEDBarGraph(5, 6, 13, 19, 26, pwm=False) #定义一组led柱状灯,该组由引脚分别为5, 6, 13, 19, 26的5个led组成,不设置每个灯的亮度
#以下值,类似于电量100%显示
graph.value = 1/10 # (0.5, 0, 0, 0, 0)
sleep(1)
graph.value = 3/10 # (1, 0.5, 0, 0, 0)
sleep(1)
graph.value = -3/10 # (0, 0, 0, 0.5, 1)
sleep(1)
graph.value = 9/10 # (1, 1, 1, 1, 0.5)
sleep(1)
graph.value = 95/100 # (1, 1, 1, 1, 0.75)
sleep(1)
可以看到上面的值都是四舍五入的,当pwm = False(默认值)时,LED要么是打开要么是关闭。
但是,使用带有pwm = True的LEDBarGraph可以使用LED亮度获得更精确的值:
from gpiozero import LEDBarGraph
from time import sleep
graph = LEDBarGraph(5, 6, 13, 19, 26, pwm=True) #定义一组led柱状灯,该组由引脚分别为5, 6, 13, 19, 26的5个led组成,设置每个灯的亮度
graph.value = 1/10 # (0.5, 0, 0, 0, 0)
sleep(1)
graph.value = 3/10 # (1, 0.5, 0, 0, 0)
sleep(1)
graph.value = -3/10 # (0, 0, 0, 0.5, 1)
sleep(1)
graph.value = 9/10 # (1, 1, 1, 1, 0.5)
sleep(1)
graph.value = 95/100 # (1, 1, 1, 1, 0.75)
sleep(1)
2.11 Traffic Lights(交通灯)
一个交通灯系统。
使用像Pi-Stop这样的TrafficLights套件:
from gpiozero import TrafficLights
from time import sleep
lights = TrafficLights(2, 3, 4) #一组交通灯
lights.green.on() #绿灯亮
while True:
sleep(10)
lights.green.off() #绿灯灭
lights.amber.on() #黄灯亮
sleep(1)
lights.amber.off() #黄灯灭
lights.red.on() #红灯亮
sleep(10)
lights.amber.on() #黄灯亮
sleep(1)
lights.green.on() #绿灯亮
lights.amber.off() #黄灯灭
lights.red.off() #红灯灭
另外;
from gpiozero import TrafficLights
from time import sleep
from signal import pause
lights = TrafficLights(2, 3, 4)
def traffic_light_sequence():
while True:
yield (0, 0, 1) # green
sleep(10)
yield (0, 1, 0) # amber
sleep(1)
yield (1, 0, 0) # red
sleep(10)
yield (1, 1, 0) # red+amber
sleep(1)
lights.source = traffic_light_sequence()
pause()
使用LED组合:
from gpiozero import LED
from time import sleep
red = LED(2)
amber = LED(3)
green = LED(4)
green.on()
amber.off()
red.off()
while True:
sleep(10)
green.off()
amber.on()
sleep(1)
amber.off()
red.on()
sleep(10)
amber.on()
sleep(1)
green.on()
amber.off()
red.off()
2.12. Push button stop motion:
每按一次按钮,使用相机模块拍摄一张照片:
from gpiozero import Button
from picamera import PiCamera
button = Button(2)
camera = PiCamera()
camera.start_preview()
frame = 1
while True:
button.wait_for_press()
camera.capture('/home/pi/frame%03d.jpg' % frame)
frame += 1
有关完整资源,请参阅 Push Button Stop Motion 。
2.13. Reaction Game(反应游戏):
当你看到灯亮起时,第一个按下按钮的人就赢了!
from gpiozero import Button, LED
from time import sleep
import random #导入随机库
led = LED(17)
player_1 = Button(2)
player_2 = Button(3)
time = random.uniform(5, 10) #随机产生5到10之间的数
sleep(time)
led.on() #灯亮
while True:
if player_1.is_pressed:
print("Player 1 wins!")
break
if player_2.is_pressed:
print("Player 2 wins!")
break
led.off() #灯灭
有关完整资源,请参阅 Quick Reaction Game。
2.14. GPIO Music Box(GPIO音乐盒):
每一个按钮会发出不一样的声音!
from gpiozero import Button
import pygame.mixer
from pygame.mixer import Sound
from signal import pause
pygame.mixer.init()
button_sounds = {
Button(2): Sound("samples/drum_tom_mid_hard.wav"),
Button(3): Sound("samples/drum_cymbal_open.wav"),
}
for button, sound in button_sounds.items():
button.when_pressed = sound.play
pause()
有关完整资源,请参阅 GPIO Music Box。
2.15. All on when pressed(全部打开时按下):
按下按钮时,蜂鸣器和所有指示灯亮起。
FishDish:
from gpiozero import FishDish
from signal import pause
fish = FishDish()
fish.button.when_pressed = fish.on
fish.button.when_released = fish.off
pause()
Ryanteck TrafficHat:
from gpiozero import TrafficHat
from signal import pause
th = TrafficHat()
th.button.when_pressed = th.on
th.button.when_released = th.off
pause()
使用LED,蜂鸣器和按钮组合:
from gpiozero import LED, Buzzer, Button
from signal import pause
button = Button(2)
buzzer = Buzzer(3)
red = LED(4)
amber = LED(5)
green = LED(6)
things = [red, amber, green, buzzer]
def things_on():
for thing in things:
thing.on()
def things_off():
for thing in things:
thing.off()
button.when_pressed = things_on
button.when_released = things_off
pause()
2.16. Full color LED(全彩LED):
使用RGBLED产生色彩:
from gpiozero import RGBLED
from time import sleep
led = RGBLED(red=9, green=10, blue=11)
led.red = 1 # full red
sleep(1)
led.red = 0.5 # half red
sleep(1)
led.color = (0, 1, 0) # full green
sleep(1)
led.color = (1, 0, 1) # magenta
sleep(1)
led.color = (1, 1, 0) # yellow
sleep(1)
led.color = (0, 1, 1) # cyan
sleep(1)
led.color = (1, 1, 1) # white
sleep(1)
led.color = (0, 0, 0) # off
sleep(1)
# slowly increase intensity of blue
for n in range(100):
led.blue = n/100
sleep(0.1)
2.17. Motion sensor(运动传感器):
运动传感器检测到运动时点亮LED:
from gpiozero import MotionSensor, LED
from signal import pause
pir = MotionSensor(4)
led = LED(16)
pir.when_motion = led.on
pir.when_no_motion = led.off
pause()
2.18. Light sensor(光敏传感器):
需要有个光敏传感器,可以检测有光和黑暗:
from gpiozero import LightSensor
sensor = LightSensor(18)
while True:
sensor.wait_for_light()
print("It's light! :)")
sensor.wait_for_dark()
print("It's dark :(")
当光线改变时执行一个函数:
from gpiozero import LightSensor, LED
from signal import pause
sensor = LightSensor(18)
led = LED(16)
sensor.when_dark = led.on
sensor.when_light = led.off
pause()
或者根据检测到的光线强弱改变PWMLED的亮度:
from gpiozero import LightSensor, PWMLED
from signal import pause
sensor = LightSensor(18)
led = PWMLED(16)
led.source = sensor.values
pause()
2.19. Distance sensor(距离传感器):
注意:在上图中,可以省略从传感器通向面包板的导线; 只需将传感器直接插入边缘的面包板中。
让DistanceSensor可以检测到最近的物体的距离:
from gpiozero import DistanceSensor
from time import sleep
sensor = DistanceSensor(23, 24)
while True:
print('Distance to nearest object is', sensor.distance, 'm')
sleep(1)
当某物接近传感器时执行一个函数:
from gpiozero import DistanceSensor, LED
from signal import pause
sensor = DistanceSensor(23, 24, max_distance=1, threshold_distance=0.2)
led = LED(16)
sensor.when_in_range = led.on
sensor.when_out_of_range = led.off
pause()
2.20. Motors(电机):
向前和向后旋转电机:
from gpiozero import Motor
from time import sleep
motor = Motor(forward=4, backward=14)
while True:
motor.forward()
sleep(5)
motor.backward()
sleep(5)
2.21. Robot(机器人)
让机器人在一个大致正方形的区域中四处走动:
from gpiozero import Robot
from time import sleep
robot = Robot(left=(4, 14), right=(17, 18))
for i in range(4):
robot.forward()
sleep(10)
robot.right()
sleep(1)
制作一个带有距离传感器的机器人,当侧得距离小于20厘米时,机器人就会转弯:
from gpiozero import Robot, DistanceSensor
from signal import pause
sensor = DistanceSensor(23, 24, max_distance=1, threshold_distance=0.2)
robot = Robot(left=(4, 14), right=(17, 18))
sensor.when_in_range = robot.backward
sensor.when_out_of_range = robot.stop
pause()
2.22. Button controlled robot(使用按钮控制机器人)
使用四个按钮作为机器人的前进/后退/左/右控制键:
from gpiozero import Robot, Button
from signal import pause
robot = Robot(left=(4, 14), right=(17, 18))
left = Button(26)
right = Button(16)
fw = Button(21)
bw = Button(20)
fw.when_pressed = robot.forward
fw.when_released = robot.stop
left.when_pressed = robot.left
left.when_released = robot.stop
right.when_pressed = robot.right
right.when_released = robot.stop
bw.when_pressed = robot.backward
bw.when_released = robot.stop
pause()
2.23. Keyboard controlled robot(使用键盘控制机器人)
使用上/下/左/右键来控制机器人:
import curses
from gpiozero import Robot
robot = Robot(left=(4, 14), right=(17, 18))
actions = {
curses.KEY_UP: robot.forward,
curses.KEY_DOWN: robot.backward,
curses.KEY_LEFT: robot.left,
curses.KEY_RIGHT: robot.right,
}
def main(window):
next_key = None
while True:
curses.halfdelay(1)
if next_key is None:
key = window.getch()
else:
key = next_key
next_key = None
if key != -1:
# KEY DOWN
curses.halfdelay(3)
action = actions.get(key)
if action is not None:
action()
next_key = key
while next_key == key:
next_key = window.getch()
# KEY UP
robot.stop()
curses.wrapper(main)
注意:此方法使用的是标准curses模块。 此模需要在Python的终端中运行才能正常工作,因此此方法在IDLE等环境中不起作用。
如果你更喜欢在IDLE下工作的版本,则以下方法应该足够:
from gpiozero import Robot
from evdev import InputDevice, list_devices, ecodes
robot = Robot(left=(4, 14), right=(17, 18))
# Get the list of available input devices
devices = [InputDevice(device) for device in list_devices()]
# Filter out everything that's not a keyboard. Keyboards are defined as any
# device which has keys, and which specifically has keys 1..31 (roughly Esc,
# the numeric keys, the first row of QWERTY plus a few more) and which does
# *not* have key 0 (reserved)
must_have = {i for i in range(1, 32)}
must_not_have = {0}
devices = [
dev
for dev in devices
for keys in (set(dev.capabilities().get(ecodes.EV_KEY, [])),)
if must_have.issubset(keys)
and must_not_have.isdisjoint(keys)
]
# Pick the first keyboard
keyboard = devices[0]
keypress_actions = {
ecodes.KEY_UP: robot.forward,
ecodes.KEY_DOWN: robot.backward,
ecodes.KEY_LEFT: robot.left,
ecodes.KEY_RIGHT: robot.right,
}
for event in keyboard.read_loop():
if event.type == ecodes.EV_KEY and event.code in keypress_actions:
if event.value == 1: # key down
keypress_actions[event.code]()
if event.value == 0: # key up
robot.stop()
注意:此方法使用第三方evdev模块。 首先使用sudo pip3 install evdev安装此库。 请注意,evdev仅适用于本地输入设备; 这个方法不适用于SSH。
2.24. Motion sensor robot(运动传感器机器人)
检测到运动时让机器人向前行驶:
from gpiozero import Robot, MotionSensor
from signal import pause
robot = Robot(left=(4, 14), right=(17, 18))
pir = MotionSensor(5)
pir.when_motion = robot.forward
pir.when_no_motion = robot.stop
pause()
或者:
from gpiozero import Robot, MotionSensor
from signal import pause
robot = Robot(left=(4, 14), right=(17, 18))
pir = MotionSensor(5)
robot.source = zip(pir.values, pir.values)
pause()
2.25. Potentiometer(电位器)
连续打印连接到MCP3008模数转换器的电位计值(0到1之间的值):
from gpiozero import MCP3008
pot = MCP3008(channel=0)
while True:
print(pot.value)
使用PWM在LED条形图上显示电位计的值,以表示状态不会“填满”LED:
from gpiozero import LEDBarGraph, MCP3008
from signal import pause
graph = LEDBarGraph(5, 6, 13, 19, 26, pwm=True)
pot = MCP3008(channel=0)
graph.source = pot.values
pause()
2.26. Measure temperature with an ADC(使用ADC测量温度)
将TMP36温度传感器连接到MCP3008模数转换器的第一个引脚:
from gpiozero import MCP3008
from time import sleep
def convert_temp(gen):
for value in gen:
yield (value * 3.3 - 0.5) * 100
adc = MCP3008(channel=0)
for temp in convert_temp(adc.values):
print('The temperature is', temp, 'C')
sleep(1)
2.27. Full color LED controlled by 3 potentiometers(由3个电位器控制全彩LED)
连接三个电位器(红色,绿色和蓝色)并使用它们的每个值来产生LED的颜色:
from gpiozero import RGBLED, MCP3008
led = RGBLED(red=2, green=3, blue=4)
red_pot = MCP3008(channel=0)
green_pot = MCP3008(channel=1)
blue_pot = MCP3008(channel=2)
while True:
led.red = red_pot.value
led.green = green_pot.value
led.blue = blue_pot.value
或者,以下示例产生相同的效果,但使用的是source属性而不是while循环:
from gpiozero import RGBLED, MCP3008
from signal import pause
led = RGBLED(2, 3, 4)
red_pot = MCP3008(0)
green_pot = MCP3008(1)
blue_pot = MCP3008(2)
led.source = zip(red_pot.values, green_pot.values, blue_pot.values)
pause()
注意:上面的示例需要Python 3的环境。在Python 2中,zip()不支持延迟评估,因此脚本将挂起。
2.28. Timed heat lamp(定时加热灯)
如果你有宠物(例如乌龟)需要每天开启一定时间的加热灯,您可以使用Energenie Pi-mote远程控制灯,TimeOfDay类来控制时间:
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.values
lamp.source_delay = 60
pause()
2.29. Internet connection status indicator(Internet连接状态指示灯)
你可以使用一对绿色和红色LED展示你的互联网连接是否正常工作。 只需使用PingServer类来确定是否ping通google.com。 如果成功,绿色LED点亮,如果不成功,红色LED点亮:
from gpiozero import LED, PingServer
from gpiozero.tools import negated
from signal import pause
green = LED(17)
red = LED(18)
google = PingServer('google.com')
green.source = google.values
green.source_delay = 60
red.source = negated(green.values)
pause()
2.30. CPU Temperature Bar Graph(CPU温度条形图)
你可以使用内置的CPUTemperature类读取Raspberry Pi自己的CPU温度,并在LED的“条形图”上显示:、
from gpiozero import LEDBarGraph, CPUTemperature
from signal import pause
cpu = CPUTemperature(min_temp=50, max_temp=90)
leds = LEDBarGraph(2, 3, 4, 5, 6, 7, 8, pwm=True)
leds.source = cpu.values
pause()
2.31. More recipes(更多方法)
继续: