树莓派从零开始玩转GPIO:用Python驱动LED的三种实战模式

张开发
2026/4/18 0:35:12 15 分钟阅读

分享文章

树莓派从零开始玩转GPIO:用Python驱动LED的三种实战模式
1. 树莓派GPIO与LED控制基础第一次拿到树莓派时我最想尝试的就是用代码控制硬件。GPIO通用输入输出接口就像树莓派的手脚而LED是最简单的输出设备。记得当时连好电路后看到自己写的Python代码成功点亮LED那一刻那种成就感至今难忘。树莓派的GPIO引脚有40个排列成两排。新手最常困惑的是引脚编号方式主要有两种物理编号按实际位置1-40编号BCM编号按芯片寄存器地址命名GPIO2、GPIO3等我建议直接用BCM编号因为RPi.GPIO库默认采用这种方式。比如GPIO17对应物理引脚11这个对应关系可以运行pinout命令查看。硬件连接时LED长脚正极接GPIO引脚短脚负极接GND中间最好串联一个220Ω电阻保护电路。2. 基础点亮你的第一个LED程序先安装必备库sudo apt-get update sudo apt-get install python3-rpi.gpio基础点亮代码保存为led_basic.pyimport RPi.GPIO as GPIO import time LED_PIN 17 # 修改为你实际使用的GPIO引脚 GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT) try: while True: GPIO.output(LED_PIN, GPIO.HIGH) # 点亮 time.sleep(1) GPIO.output(LED_PIN, GPIO.LOW) # 熄灭 time.sleep(1) except KeyboardInterrupt: GPIO.cleanup()运行时会遇到两个常见问题权限不足用sudo python3 led_basic.py运行引脚复用警告在setup前加GPIO.setwarnings(False)我第一次测试时LED不亮后来发现是正负极接反了。建议用万用表测试线路通断这是硬件调试的基本功。3. 进阶玩法一PWM实现呼吸灯效果PWM脉冲宽度调制通过快速开关模拟电压变化。树莓派的硬件PWM只有两个引脚GPIO12/13但软件PWM所有引脚都支持。呼吸灯完整代码保存为led_pwm.pyfrom time import sleep import RPi.GPIO as GPIO LED_PIN 18 # 硬件PWM引脚 FREQ 100 # PWM频率(Hz) GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT) pwm GPIO.PWM(LED_PIN, FREQ) pwm.start(0) try: while True: # 渐亮 for duty in range(0, 101, 5): pwm.ChangeDutyCycle(duty) sleep(0.05) # 渐暗 for duty in range(100, -1, -5): pwm.ChangeDutyCycle(duty) sleep(0.05) except KeyboardInterrupt: pwm.stop() GPIO.cleanup()关键参数调试经验频率低于50Hz肉眼可见闪烁频率100-200Hz呼吸效果最平滑占空比步长5%的渐变最自然我曾用这个效果做了个魔戒道具通过光敏电阻自动触发呼吸效果在创客市集上吸引了不少目光。4. 进阶玩法二按键控制LED开关给电路增加一个轻触开关连接方式开关一脚接GPIO如GPIO23另一脚接GNDGPIO设置内部上拉电阻按键控制代码保存为led_button.pyimport RPi.GPIO as GPIO LED_PIN 17 BUTTON_PIN 23 GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_downGPIO.PUD_UP) led_state False def toggle_led(channel): global led_state led_state not led_state GPIO.output(LED_PIN, led_state) GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callbacktoggle_led, bouncetime200) try: while True: pass except KeyboardInterrupt: GPIO.cleanup()调试时发现三个典型问题按键抖动添加bouncetime参数单位ms长按误触发在回调函数中增加时间判断多按键冲突用队列管理事件我的智能家居项目就用这个方案做物理开关比纯手机控制可靠多了。5. 进阶玩法三中断实现事件驱动闪烁GPIO中断可以立即响应引脚变化适合实时性要求高的场景。树莓派支持四种触发方式RISING上升沿FALLING下降沿BOTH双边沿HIGH/LOW电平变化中断控制LED闪烁保存为led_interrupt.pyimport RPi.GPIO as GPIO import time LED_PIN 17 INTERRUPT_PIN 24 blink_enabled False def interrupt_callback(channel): global blink_enabled blink_enabled not blink_enabled GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT) GPIO.setup(INTERRUPT_PIN, GPIO.IN, pull_up_downGPIO.PUD_UP) GPIO.add_event_detect(INTERRUPT_PIN, GPIO.FALLING, callbackinterrupt_callback, bouncetime200) try: while True: if blink_enabled: GPIO.output(LED_PIN, GPIO.HIGH) time.sleep(0.2) GPIO.output(LED_PIN, GPIO.LOW) time.sleep(0.2) except KeyboardInterrupt: GPIO.cleanup()实际项目中我用来做设备状态指示正常工作时慢闪1Hz出现警告时快闪5Hz严重错误时常亮中断响应延迟通常在微秒级比轮询方式高效得多。曾经用这个特性做了个反应速度测试器测量玩家按键响应时间。6. 综合实战智能光控小夜灯结合光敏电阻和PWM实现自动调光夜灯。电路需要光敏电阻与10kΩ电阻分压ADC芯片如MCP3008读取模拟值LED灯带作为照明核心代码逻辑保存为night_light.pyimport RPi.GPIO as GPIO import time import spidev # 初始化SPI接口 spi spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz 1000000 LED_PIN 18 GPIO.setmode(GPIO.BCM) GPIO.setup(LED_PIN, GPIO.OUT) pwm GPIO.PWM(LED_PIN, 200) pwm.start(0) def read_light(channel0): adc spi.xfer2([1, (8 channel) 4, 0]) return ((adc[1] 3) 8) adc[2] try: while True: light_level read_light() brightness 100 - min(100, light_level / 10) pwm.ChangeDutyCycle(brightness) time.sleep(0.1) finally: spi.close() pwm.stop() GPIO.cleanup()这个项目我放在卧室使用光敏阈值通过实验确定白天自然光ADC值800 → LED关闭夜晚开大灯ADC值300-800 → 50%亮度仅小夜灯ADC值300 → 100%亮度调试时发现PWM频率要高于100Hz否则手机拍摄会有频闪现象。后来还增加了人体感应模块实现人来自动亮灯的功能。

更多文章