GPIO 编程(Python)
把电脑变成能碰硬件的机器。搞懂 BCM 编号和 3.3V 电平,用 gpiozero 几行 Python 就能点灯、读按键、做呼吸灯。
把电脑变成能碰硬件的机器。搞懂 BCM 编号和 3.3V 电平,用 gpiozero 几行 Python 就能点灯、读按键、做呼吸灯。
LED、Button 等设备类,无需手动设方向。LED(17)、Button(2)、PWMLED(18) 等,把复杂的底层操作封装成直观的对象方法。它底层可切换多种 pin factory(RPi.GPIO / lgpio / pigpio),Pi 5 用 lgpio。是本教程主力。接线前必须看懂引脚图。牢记电源脚和地脚的位置,别把信号接到电源上。下图标注 BCM 编号:
① GPIO 是 3.3V,绝不接 5V 信号到 GPIO;② LED 必须串限流电阻;③ 所有设备共地(GND 连通)才能正常工作。接线前断电,用 pinout 命令确认引脚位置,避免把 5V 或信号接错到相邻脚。
硬件连接:LED 长脚(正极)→ 220Ω 电阻 → GPIO17(物理 11 脚);LED 短脚(负极)→ GND(物理 9 脚)。代码惊人地简单:
# blink.py — 让 LED 闪烁 from gpiozero import LED from time import sleep led = LED(17) # BCM 17,即物理第 11 脚 while True: led.on() # 点亮(输出高电平 3.3V) sleep(1) # 亮 1 秒 led.off() # 熄灭 sleep(1)
# 运行脚本(gpiozero 已预装,直接跑) python3 blink.py # LED 开始 1 秒一次地闪烁,Ctrl+C 停止 # 更简洁的写法:内置 blink 方法自动循环
# blink2.py — 用内置 blink,无需手写循环 from gpiozero import LED from signal import pause led = LED(17) led.blink(on_time=0.5, off_time=0.5) # 后台自动闪 pause() # 阻塞主线程,让后台闪烁持续(否则脚本立即退出)
硬件连接:按键一端 → GPIO2(物理 3 脚),另一端 → GND。gpiozero 的 Button 默认启用内部上拉电阻——未按时读高电平,按下时接通 GND 变低电平。
# button.py — 按键控制 LED from gpiozero import LED, Button from signal import pause led = LED(17) button = Button(2) # 默认内部上拉,按下=接地=触发 # 方式一:轮询查询按键状态 # while True: # if button.is_pressed: # led.on() # else: # led.off() # 方式二:事件回调(推荐,不占 CPU) button.when_pressed = led.on # 按下时点灯 button.when_released = led.off # 松开时熄灭 print("按下按键点亮 LED,Ctrl+C 退出") pause() # 等待事件(回调在后台线程触发)
机械按键按下瞬间会因触点弹跳产生多次抖动信号。传统上要写延时消抖逻辑。gpiozero 的 Button 内置了 bounce_time 参数(如 Button(2, bounce_time=0.05)),自动过滤 50ms 内的抖动。事件回调(when_pressed)比轮询更省 CPU,是推荐做法。
普通 LED 只能全亮全灭。用 PWM 快速开关并调节占空比,就能实现亮度渐变。gpiozero 用 PWMLED,value 取 0.0~1.0 表示亮度。
# breathe.py — LED 呼吸灯 from gpiozero import PWMLED from time import sleep led = PWMLED(17) # 支持 PWM 的 LED 对象 while True: # 渐亮:亮度从 0 到 1 for i in range(0, 101): led.value = i / 100.0 # value ∈ [0.0, 1.0] sleep(0.01) # 渐暗 for i in range(100, -1, -1): led.value = i / 100.0 sleep(0.01)
# breathe2.py — gpiozero 内置 pulse 一行搞定呼吸效果 from gpiozero import PWMLED from signal import pause led = PWMLED(17) led.pulse(fade_in_time=1, fade_out_time=1) # 自动呼吸 pause()
了解底层库有助理解原理和排障。同样点灯,RPi.GPIO 需要更多样板代码:
# 用 RPi.GPIO 底层库点灯(仅 Pi 4 及以前;Pi 5 请用 lgpio) import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) # 用 BCM 编号 GPIO.setup(17, GPIO.OUT) # 手动设为输出 try: while True: GPIO.output(17, GPIO.HIGH) # 高电平 time.sleep(1) GPIO.output(17, GPIO.LOW) # 低电平 time.sleep(1) except KeyboardInterrupt: GPIO.cleanup() # 必须手动清理引脚状态
| 特性 | gpiozero(推荐) | RPi.GPIO | lgpio |
|---|---|---|---|
| 抽象层次 | 高(对象化) | 低 | 低 |
| 代码量 | 极少 | 多(样板代码) | 中 |
| Pi 5 支持 | 是(自动适配) | 否 | 是 |
| 事件/消抖 | 内置 | 需手写 | 需手写 |
| 适用 | 绝大多数场景 | 老项目/精细控制 | Pi 5 底层 |
不写代码也能查 GPIO 状态:pinout 显示完整引脚图和板子信息;gpioinfo(lgpio 工具)列出所有 GPIO 当前状态;raspi-gpio get 读取实时电平。接线没反应时先用这些命令确认引脚是否被占用、方向是否正确。
GPIO 让树莓派能碰硬件。引脚有 BCM(芯片编号,如 GPIO17)和 BOARD(物理位置)两套编号,本教程统一用 BCM。三条铁律:GPIO 是 3.3V(绝不接 5V)、LED 必须串限流电阻(220~330Ω)、所有设备共地。gpiozero 是官方推荐的高层库(系统预装、支持 Pi 5):LED(17) 点灯、Button(2) 读按键(内置上拉和消抖,用 when_pressed 事件回调最省 CPU)、PWMLED(17) 通过占空比调亮度做呼吸灯。底层库 RPi.GPIO 代码繁琐且不支持 Pi 5,Pi 5 底层用 lgpio——但优先永远选 gpiozero,它自动适配底层。调试用 pinout 看引脚图。下一章我们连接真实传感器,学习 I2C/SPI/1-Wire 三大总线。