树莓派3B+ Python GUI步进电机一键启停:启动后无法中途停止求助
解决步进电机无法中途停止的问题
你的核心问题是电机运行线程没有在步进过程中检查停止信号,导致触发停止后仍会完成全部800步。以下是具体修复方案:
问题分析
run1函数的for循环会完整执行800次步进操作,期间不会检查全局变量running1的状态,所以stop1函数修改running1后无法中断循环。run1内重复执行GPIO.setmode和GPIO.setup,这是冗余操作,可能干扰已配置的GPIO状态。
修复步骤
- 在每一步步进操作后检查
running1,如果为False立即终止循环 - 删除
run1内重复的GPIO初始化代码 - 停止时将步进引脚设为低电平,避免电机保持锁定
修改后的完整代码:
import tkinter as tk from time import sleep import RPi.GPIO as GPIO from threading import Thread DIR = 16 STEP = 20 CW = 1 CCW = 0 # 全局初始化GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(DIR, GPIO.OUT) GPIO.setup(STEP, GPIO.OUT) GPIO.output(DIR, CW) win = tk.Tk() win.title("HELLO") win.geometry("300x400") running1 = False def start1(): global running1 stop1() btn1.config(text="Stop upward", command=stop1) running1 = True info_label["text"] = "Starting..." thread1 = Thread(target=run1, daemon=True) thread1.start() def run1(): global running1 GPIO.output(DIR, CW) # 每一步都检查running1状态 for x in range(800): if not running1: break GPIO.output(STEP, GPIO.HIGH) sleep(0.0050) GPIO.output(STEP, GPIO.LOW) sleep(0.0050) # 循环结束后重置按钮状态(防止中途停止后按钮没切换) if running1: stop1() print('Cycle finished or stopped') def stop1(): global running1 running1 = False GPIO.output(STEP, GPIO.LOW) # 停止时确保步进引脚低电平 info_label["text"] = "Stopped" btn1.config(text="Start upward", command=start1) info_label = tk.Label(win, text="stepper1 ", bg="yellow") info_label.grid(row=1, column=0) # 补充布局,原代码未添加到窗口 btn1 = tk.Button(win, text="Start upward", height="5", width="10", bg="slateblue1", command=start1) btn1.grid(row=0, column=0) win.mainloop() # 程序退出时清理GPIO,避免下次运行警告 GPIO.cleanup()
额外说明
- 加入
GPIO.cleanup()在程序退出时清理GPIO资源,避免重复运行出现警告 - 补充了
info_label的布局代码,确保标签显示在窗口中 - 电机完成800步后会自动切换按钮状态为启动模式
内容的提问来源于stack exchange,提问作者BIRU
相关产品推荐
相关产品推荐

