0

I am trying to use tkinter to set up a gui on a raspberry pi that will have buttons for a user to control a nema 23 stepper motor. When the user holds down the button the stepper motor should move in the indicated direction until the user lets go of the button, however, currently the button will either stay held down after clicking and the motor will run for forever or if I change the while loop it will only do the specified amount of steps before needing to click the button again. How can I fix this so it will run as long as you are holding down the button?

Here is my current code:

import RPi.GPIO as GPIO
from time import sleep
import tkinter as tk

DIR = 13
STEP = 11
CW = 0
CCW = 1

GPIO.setmode(GPIO.BOARD)

GPIO.setup(DIR, GPIO.OUT)
GPIO.setup(STEP, GPIO.OUT)

GPIO.output(DIR, CW)

def start_motor(CW):

    while True:

        sleep(1.0)
        GPIO.output(DIR, CW) 

        for x in range(200):
            GPIO.output(STEP,GPIO.HIGH)
            sleep(.000005)
            GPIO.output(STEP,GPIO.LOW)
            sleep(.005)    

def start_motor(CCW):

    while True:

        sleep(1.0)
        GPIO.output(DIR, CCW) 

        for x in range(200):
            GPIO.output(STEP,GPIO.HIGH)
            sleep(.000005)
            GPIO.output(STEP,GPIO.LOW)
            sleep(.005) 

root = tk.Tk()
root.title("Motor Control")

forward_button = tk.Button(root, text="Hold to Run Forward")
forward_button.pack(pady=10)

reverse_button = tk.Button(root, text="Hold to Run Reverse")
reverse_button.pack(pady=10)

forward_button.bind("<ButtonPress>", lambda event: start_motor(CW))
reverse_button.bind("<ButtonPress>", lambda event: start_motor(CCW))

root.mainloop()

  • 1
    I think this question has already been answered here: https://stackoverflow.com/questions/34522095/gui-button-hold-down-tkinter – yeshks Apr 12 '23 at 23:16
  • Your question is a duplicate of the linked question, but your code indicates a fundamental misunderstanding of how functions work. You've defined two functions with the same name, so the first one is discarded. Any calls to `start_motor(...)` will go to the second definition. Once you call it with an argument, e.g. `start_motor(variable)`, the value of that argument is available as `CCW` to the code inside the function while it is running. So calling `start_motor(CW)` copies the value of `CW` to the function's _local variable_ `CCW`. – Pranav Hosangadi Apr 12 '23 at 23:21
  • While it should work fine the way it is now, you should change the name of the argument to something that describes what it actually specifies -- the _direction_ you want to move the stepper, so change that line to `def start_motor(direction):`. Now, inside the function, output that variable to the `DIR` pin: `GPIO.output(DIR, direction)`. – Pranav Hosangadi Apr 12 '23 at 23:23

0 Answers0