PySimpleGUI如何处理持续用户输入?舵机控制GUI单次输入后失效问题
问题根因
- 你在「Delayed Extension Grip」「Simultaneous Extension Grip」两个预设动作的代码末尾,调用了
GPIO.cleanup(),这个函数会清空所有GPIO引脚的配置,包括你初始化好的引脚输出模式、PWM通道全部都会被重置,后续再触发舵机动作自然不会生效。 - 自定义舵机控制的逻辑存在冗余:每次触发动作时反复启停PWM,反而可能导致状态异常。
修复方案
按以下步骤修改代码即可:
- 删除两个预设动作分支末尾的
GPIO.cleanup()调用,这个操作只需要在程序退出前执行一次 - 简化自定义舵机控制的逻辑,不要每次执行完就调用PWM.stop(),保持PWM持续运行,仅修改占空比即可
- 在窗口关闭、程序退出前统一调用
GPIO.cleanup()释放资源
修改后完整代码
# -*- coding=utf-8 -*- import PySimpleGUI as psg import os import RPi.GPIO as GPIO import time servoPIN_1 = 17 # 声明舵机信号输入GPIO引脚 servoPIN_2 = 27 GPIO.setmode(GPIO.BCM) # 声明引脚编号规则 GPIO.setup(servoPIN_1, GPIO.OUT) GPIO.setup(servoPIN_2, GPIO.OUT) PWM_1 = GPIO.PWM(servoPIN_1, 50) # 创建50Hz频率的PWM通道 PWM_2 = GPIO.PWM(servoPIN_2, 50) # 初始化启动PWM,不用反复启停 PWM_1.start(0) PWM_2.start(0) psg.theme('DarkAmber') Top_Def = [[psg.Text("Concept 2: Band Pincher", size=(25,1), font=("Courier", 20))], [psg.HorizontalSeparator()]] LHS_PreDef = [ [psg.Text("Choose pre-selected routine", font=("Courier", 12))], [psg.Image('/home/pi/Desktop/Motor-Control_Script/image1.png', size=(301,232)), psg.Button('Delayed Extension Grip', font=("Courier", 10))], [psg.Image('/home/pi/Desktop/Motor-Control_Script/image2.png', size=(301,99)), psg.Button('Simultaneous Extension Grip', font=("Courier", 10))], [psg.Button('hidden', size=(6,2), button_color=(psg.theme_background_color(),psg.theme_background_color()), border_width=0)] ] RHS_CustomDef = [ [psg.Text("Create custom servo routine", font=("Courier", 12))], [psg.Image('/home/pi/Desktop/Motor-Control_Script/image3.png', size=(200,200)), psg.In(size=(20,1), enable_events=True, key="_Servo1_"), psg.Button('Actuate servo 1', size=(6,2), font=("Courier", 10))], [psg.Image('/home/pi/Desktop/Motor-Control_Script/image3.png', size=(200,200)), psg.In(size=(20,1), enable_events=True, key="_Servo2_"), psg.Button('Actuate servo 2', size=(6,2), font=("Courier", 10))], [psg.Button('Exit', size=(6,2), font=("Courier", 10))] ] Layout = [ [Top_Def,psg.Column(LHS_PreDef),psg.VSeparator(), psg.Column(RHS_CustomDef)] ] window = psg.Window('Handling solutions', Layout) while True: event, values = window.read() if event == psg.WINDOW_CLOSED or event == 'Exit': break elif event == 'Delayed Extension Grip': PWM_1.ChangeDutyCycle(9) PWM_2.ChangeDutyCycle(10) time.sleep(0.5) PWM_1.ChangeDutyCycle(6) time.sleep(1.5) PWM_2.ChangeDutyCycle(12) time.sleep(1.5) PWM_1.ChangeDutyCycle(8) PWM_2.ChangeDutyCycle(10) time.sleep(0.05) elif event == 'Simultaneous Extension Grip': PWM_1.ChangeDutyCycle(9) PWM_2.ChangeDutyCycle(10) time.sleep(0.5) PWM_1.ChangeDutyCycle(6) PWM_2.ChangeDutyCycle(11) time.sleep(1.5) PWM_1.ChangeDutyCycle(8) PWM_2.ChangeDutyCycle(10) time.sleep(0.05) elif event == 'Actuate servo 1': duty = float(values["_Servo1_"]) PWM_1.ChangeDutyCycle(duty) time.sleep(0.05) print(duty) elif event == 'Actuate servo 2': duty = float(values["_Servo2_"]) PWM_2.ChangeDutyCycle(duty) time.sleep(0.05) # 退出前统一释放资源 PWM_1.stop() PWM_2.stop() GPIO.cleanup() window.close()
额外说明
如果需要舵机到位后停止PWM避免抖动,可以在每次修改占空比、等待到位后,将占空比设为0即可,不需要调用stop方法,后续再改占空比依然可以正常响应。
内容的提问来源于stack exchange,提问作者S0yboi
相关产品推荐
相关产品推荐

