gpiozero 树莓派(Raspberry Pi)官方推荐的 Python GPIO 控制库
🧩 一、gpiozero
是什么?
gpiozero
是一个 面向对象(OOP) 的 Python 库,用于轻松控制树莓派上的 GPIO(通用输入输出)引脚。
它的设计哲学是——“简单的事情简单做,复杂的事情也能做”。
📦 安装方式:
sudo apt install python3-gpiozero
或者使用 pip:
pip install gpiozero
⚙️ 二、核心设计理念
gpiozero
的目标是隐藏底层硬件的复杂性,让你只用 Python 面向对象的思维来控制电子元件。
比如点亮一个 LED:
from gpiozero import LED
from time import sleepled = LED(17)while True:led.on()sleep(1)led.off()sleep(1)
无需自己配置引脚模式、读写电平、初始化清理等——库自动处理。
🔌 三、常用组件类(按用途分类)
🟢 输出设备
类名 | 说明 |
---|---|
LED | 控制发光二极管 |
Buzzer | 控制蜂鸣器 |
PWMLED | 控制亮度可调的 LED |
Servo / AngularServo | 控制舵机(PWM 输出) |
Motor | 控制直流电机 |
RGBLED | 控制三色 LED(RGB) |
🔴 输入设备
类名 | 说明 |
---|---|
Button | 按钮开关输入 |
MotionSensor | PIR 红外运动传感器 |
LightSensor | 光敏电阻传感器 |
DistanceSensor | 超声波测距传感器(HC-SR04) |
LineSensor | 红外循迹传感器 |
⚡ 复杂组件(复合控制)
类名 | 说明 |
---|---|
Robot | 控制左右两路电机,实现小车运动 |
PhaseEnableMotor | 控制相位+使能型电机驱动模块 |
Energenie | 控制智能插座(通过射频模块) |
🧠 四、gpiozero
的抽象层次(简化架构)
+-------------------------------------------------+
| gpiozero (高层接口) |
| 设备类 (LED, Button, Servo, Motor...) |
+-------------------------------------------------+
| RPi.GPIO / lgpio / pigpio |
| (底层驱动库,可自由选择) |
+-------------------------------------------------+
| 树莓派硬件层 |
+-------------------------------------------------+
默认使用 RPi.GPIO
,但你也可以切换到更精准的 pigpio
(支持更精细的 PWM 控制)。
🪄 五、Servo(舵机)控制详解
你的代码示例正是这个部分。我们来详细分解。
from gpiozero import Servo
from time import sleepservo = Servo(18, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000)
参数说明:
参数名 | 说明 |
---|---|
pin | 使用的 GPIO 引脚编号(BCM 编号) |
min_pulse_width | 最小脉宽(秒),对应舵机的最小角度 |
max_pulse_width | 最大脉宽(秒),对应舵机的最大角度 |
frame_width | 默认 20ms,控制信号周期 |
舵机原理:
舵机用 PWM(脉宽调制) 控制角度:
- 0.5ms → 大约 0°
- 1.5ms → 中位 90°
- 2.5ms → 最大 180°
gpiozero.Servo
会自动在这些脉宽之间插值。
控制角度:
servo.value = -1 # 最小角度(约0°)
servo.value = 0 # 中位(约90°)
servo.value = 1 # 最大角度(约180°)
这个范围是 -1 到 +1 的浮点数,线性对应舵机角度。
如果你希望直接用角度来控制,可以使用:
from gpiozero import AngularServoservo = AngularServo(18, min_angle=0, max_angle=180)
servo.angle = 90
🧯 六、资源释放与异常处理
树莓派 GPIO 必须正确释放,否则可能出现“设备忙”或“Pin already in use”错误。
你的写法是完全正确的:
finally:servo.close()
这会自动清理引脚,防止冲突。
🧩 七、进阶特性
1. 事件绑定(回调函数)
from gpiozero import Buttonbutton = Button(2)def pressed():print("Button pressed!")button.when_pressed = pressed
事件式编程无需轮询,更高效。
2. 组合逻辑设备
gpiozero
支持逻辑运算,比如两个按钮控制一个 LED:
from gpiozero import LED, Button
from signal import pauseled = LED(17)
button1 = Button(2)
button2 = Button(3)led.source = button1.values or button2.valuespause()
3. 控制远程 GPIO(通过网络)
你可以在一台树莓派上运行控制程序,操作另一台树莓派的 GPIO。
from gpiozero import LED
from gpiozero.pins.pigpio import PiGPIOFactoryfactory = PiGPIOFactory(host='192.168.1.50')
led = LED(17, pin_factory=factory)led.on()
🧾 八、调试与安全建议
- 永远使用 BCM 编号(而不是物理针脚号),保持一致性。
- 对舵机、电机等必须单独供电,避免烧坏树莓派 5V 口。
- 如果出现**“ValueError: invalid value for servo.value”**,检查脉宽设置是否超出范围。
- 可使用
servo.detach()
暂时停止信号,释放舵机力矩。
✅ 九、总结表
特性 | 功能 |
---|---|
面向对象设计 | 每个元件都是一个类 |
自动清理 | 使用 close() 或退出时自动清理 |
多层后端 | 支持 RPi.GPIO / pigpio / lgpio |
支持事件 | when_pressed , when_held 等 |
支持组合逻辑 | 可以组合输入输出 |
支持远程控制 | 可通过网络操作另一台树莓派 |
小栗子
舵机 + 按钮控制示例
🧩 一、硬件连接示意
元件 | 引脚 | 说明 |
---|---|---|
舵机信号线 | GPIO 18 | PWM 控制信号输出 |
舵机电源正极 | 5V | 建议外部供电或树莓派 5V(取决于舵机功率) |
舵机电源负极 | GND | 必须与树莓派 GND 共地 |
按钮一端 | GPIO 17 | 输入信号端 |
按钮另一端 | GND | 接地(内部上拉) |
🧠 二、代码示例
from gpiozero import Servo, Button
from time import sleep
from signal import pause# === 初始化部分 ===
# 连接舵机:GPIO 18
servo = Servo(18, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000)# 连接按钮:GPIO 17(按钮另一端接 GND)
button = Button(17, pull_up=True)# 状态变量:用于记录当前舵机角度状态
is_center = True# === 定义行为 ===
def toggle_servo():global is_centerif is_center:print("👉 转到 45°")servo.value = -0.5 # 偏转到一边(约 45°)else:print("⬅️ 回到中位")servo.value = 0 # 回中位(约 90°)is_center = not is_centersleep(0.5) # 防抖 + 稍等舵机稳定# === 事件绑定 ===
button.when_pressed = toggle_servo# 初始位置
servo.value = 0
print("系统启动完成,舵机位于中位。按下按钮切换角度。")# === 主循环(保持运行)===
try:pause() # 保持程序运行,等待事件触发
except KeyboardInterrupt:print("\n退出中...")
finally:servo.close()button.close()print("GPIO 资源已释放。")
⚙️ 三、运行逻辑说明
-
启动时,舵机回到中位(
servo.value = 0
)。 -
每次按下按钮时,会触发
toggle_servo()
。 -
is_center
变量记录当前状态:- 若在中位 → 转到 45°;
- 若在 45° → 回中位。
-
pause()
让程序持续监听按钮事件,不占用 CPU。
🧾 四、可选扩展
1️⃣ 让舵机左右来回摆动
from gpiozero import Servo
from time import sleepservo = Servo(18, min_pulse_width=0.5/1000, max_pulse_width=2.5/1000)
while True:for pos in (-1, 0, 1, 0):servo.value = possleep(0.5)
2️⃣ 使用 AngularServo
按角度控制
from gpiozero import AngularServoservo = AngularServo(18, min_angle=0, max_angle=180)
servo.angle = 90 # 中位
servo.angle = 45 # 左转 45°
🔋 五、安全与调试建议
- 如果舵机抽搐或抖动:
➜ 调整min_pulse_width
/max_pulse_width
。 - 舵机电流大时,请外接 5V 电源,并共地。
- 若按钮不响应,检查是否正确接到 GND(内部上拉需接地触发)。
- 若要增加多个按钮控制多个舵机,只需复制实例并命名不同变量。