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

PySimpleGUI如何处理持续用户输入?舵机控制GUI单次输入后失效问题

问题根因

  1. 你在「Delayed Extension Grip」「Simultaneous Extension Grip」两个预设动作的代码末尾,调用了GPIO.cleanup(),这个函数会清空所有GPIO引脚的配置,包括你初始化好的引脚输出模式、PWM通道全部都会被重置,后续再触发舵机动作自然不会生效。
  2. 自定义舵机控制的逻辑存在冗余:每次触发动作时反复启停PWM,反而可能导致状态异常。

修复方案

按以下步骤修改代码即可:

  1. 删除两个预设动作分支末尾的GPIO.cleanup()调用,这个操作只需要在程序退出前执行一次
  2. 简化自定义舵机控制的逻辑,不要每次执行完就调用PWM.stop(),保持PWM持续运行,仅修改占空比即可
  3. 在窗口关闭、程序退出前统一调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 13:09:00