You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Python开发:按下GPIO按钮时如何立即退出运行循环?

问题根源

你当前代码按键响应延迟的核心原因是使用了阻塞式的sleep(3):程序执行到sleep语句时会完全暂停当前线程的逻辑运行,必须等3秒等待结束后才会走到按键状态判断的代码段,自然无法做到按键按下即时响应。
gpiozero库的Button组件本身自带硬件中断式的事件监听能力,不需要在循环里轮询按键状态,配合非阻塞等待逻辑即可实现毫秒级的按键响应,立刻打断当前运行的循环流程。

可直接运行的修改版代码
import pygame
from gpiozero import Button, Motor
from time import sleep

# 硬件初始化,添加50ms消抖避免机械按键误触发
btn1 = Button(20, bounce_time=0.05)
btn2 = Button(21, bounce_time=0.05)
motor = Motor(4, 14)
pygame.init()

# 全局状态标记,记录触发的按键,None为无按键按下状态
pressed_btn = None

def trigger_btn1():
    global pressed_btn
    pressed_btn = 1

def trigger_btn2():
    global pressed_btn
    pressed_btn = 2

# 绑定按键按下回调,gpiozero会自动启动后台线程监听引脚电平变化,无需手动轮询
btn1.when_pressed = trigger_btn1
btn2.when_pressed = trigger_btn2

def wait_with_interrupt(duration):
    """替代原生sleep的非阻塞等待函数,检测到按键触发立刻终止等待"""
    global pressed_btn
    time_passed = 0
    check_step = 0.05  # 每50ms检测一次按键状态,最高延迟50ms人无感知
    while time_passed < duration:
        if pressed_btn is not None:
            return
        sleep(check_step)
        time_passed += check_step

# 主逻辑循环
while True:
    pressed_btn = None
    # 默认运行循环,检测到按键立刻跳出
    while pressed_btn is None:
        motor.stop()
        pygame.mixer.music.load('sounds/sound1.mp3')
        pygame.mixer.music.play()
        wait_with_interrupt(3)
        if pressed_btn is not None:
            break

        motor.forward()
        wait_with_interrupt(3)
        if pressed_btn is not None:
            break

    # 按键触发后的分支逻辑
    pygame.mixer.music.stop()
    motor.stop()
    print(f'button {pressed_btn} pressed')
    if pressed_btn == 1:
        pygame.mixer.music.load('sounds/sound2.mp3')
    else:
        pygame.mixer.music.load('sounds/sound3.mp3')
    pygame.mixer.music.play()
    wait_with_interrupt(3)
    motor.forward()
    wait_with_interrupt(3)
关键改动说明
  • 用gpiozero自带的when_pressed事件回调实现按键监听,该机制基于硬件中断实现,运行在独立后台线程,不会被主线程的sleep阻塞,按键按下时会立刻修改状态标记
  • 替换所有长阻塞的原生sleep(3)为分段短等待实现的非阻塞等待函数,每50ms检测一次按键状态,响应延迟控制在人无法感知的50ms以内,同时CPU占用几乎可以忽略
  • 给按键添加了50ms的硬件消抖配置,避免机械按键接触抖动导致的重复触发问题
  • 移除了原代码中未使用的RPi.GPIO导入,减少不必要的资源占用

内容的提问来源于stack exchange,提问作者joaomcs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:03:33