树莓派3 Reed开关控制外设:PyGame音频循环异常修复问询
问题解决:树莓派磁簧开关控制音频与继电器
问题描述
使用树莓派3,配置磁簧开关(引脚18)、香薰机(Ch1继电器,引脚26)、迪斯科球(Ch2继电器,引脚20)。需求如下:
- 磁簧开关状态为True时:停止音频播放,触发香薰机出香、迪斯科球旋转发光
- 磁簧开关状态为False时:从头开始不间断播放音频(直到开关变为True),同时关闭香薰机和迪斯科球
当前代码存在音频与sleep()同步循环的问题,无法实现连续播放。
问题分析
原代码的核心问题:
- 每次检测到开关为False时,都会重复调用
pygame.mixer.music.play(),强制音频从头重启,配合sleep(1)导致音频每1秒循环一次 sleep(1)阻塞主循环,导致开关状态的响应延迟- 未判断音频当前播放状态,重复触发播放命令造成无效操作
修改后的代码
import RPi.GPIO as GPIO import pygame from time import sleep # 初始化音频模块 pygame.mixer.init() pygame.mixer.music.load("/home/sean/Downloads/song.mp3") audio_playing = False # 跟踪音频播放状态 # GPIO配置初始化 GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(26, GPIO.OUT) GPIO.setup(20, GPIO.OUT) try: while True: switch_state = GPIO.input(18) if switch_state: # 开关触发:停止音频,启动外设 if pygame.mixer.music.get_busy(): pygame.mixer.music.stop() audio_playing = False GPIO.output(26, 1) GPIO.output(20, 1) else: # 开关未触发:关闭外设,播放音频(仅当未播放时从头启动) GPIO.output(26, 0) GPIO.output(20, 0) if not audio_playing: pygame.mixer.music.play(-1) # -1参数实现音频循环播放 audio_playing = True # 短延时降低CPU占用,同时保证状态检测灵敏度 sleep(0.1) except KeyboardInterrupt: # 中断时清理资源 pygame.mixer.music.stop() GPIO.cleanup()
关键改动说明
- 添加播放状态跟踪:用
audio_playing变量记录音频状态,避免重复触发play()导致音频频繁重启 - 设置循环播放:调用
play(-1)让音频持续循环,直到被主动停止 - 优化延时逻辑:将
sleep(1)改为sleep(0.1),既减少CPU占用,又保证开关状态检测的及时性 - 统一状态读取:单次读取开关状态后再进行分支判断,避免重复读取导致的状态不一致
- 无效操作过滤:仅当音频正在播放时才调用
stop(),减少不必要的系统调用
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

