I'm using a Raspberry Pi to run a motor off a button and some LEDs. The LEDs have to perform a flashing pattern based on certain variables, and I have them running in their own thread to allow the code to keep working (I got the idea from here, of course).
The problem is, depending on how fast the user pushes the button (a sequence requires multiple pushes to set a speed), the LED thread, which is stopped when the button is released, is sometimes called again before the last one has terminated.
This means, I think, there are two threads now, so when the command to stop the run()
action in the LED thread is sent, I believe one of the threads (or both, maybe) doesn't get the stop command, so the LED stays flashing (as the Thread calls for) after the button is released for good.
So I think what I'm looking for is a way to ensure only one instance of the LED thread runs at a time. I think the easiest way would be for the LED Thread to, as it's first step, terminate all other instances of the LED Thread that might be running. I like this because no matter which light is flashing from the Thread, it just stops, and a new thread from the most recent action calling for a flashing light takes over.
How do I do this? I've been looking at the isActive()
function, but I'm not able to conceptualize it I guess, so I don't know how to use it.
Here is the LED thread for reference. It is called by other .py
scripts using the flash_led()
function and stopped with the stop_led()
function:
## leds.py. This is imported into the scripts that run the motors and buttons
# LED control Thread (Which-LED, Desired-State On/Off/Flash, Flash-On-Duration, Flash-Off-Duration, Number-Of-Flashes)
class LEDFlash(Thread):
#Initial parameters for an LED Flash command, overwritten by led_flash()
led_pin = led_dict["red_led_1"] #from a dict earlier in the script
flash_on_duration = 1.0
flash_off_duration = 1.0
def __init__(self):
super(LEDFlash, self).__init__()
self.keep_flashing = True
def run(self):
while self.keep_flashing:
GPIO.output(self.led_pin, GPIO.HIGH)
time.sleep(self.flash_on_duration)
GPIO.output(self.led_pin, GPIO.LOW)
time.sleep(self.flash_off_duration)
def stop_flash(self):
self.keep_flashing = False
def flash_led(led, on_time, off_time): # 'flash_led.' added to make flash_thread accessible from the stop_led() function
flash_led.flash_thread = LEDFlash()
flash_led.flash_thread.led_pin = led_dict[str(led)]
flash_led.flash_thread.flash_on_duration = on_time
flash_led.flash_thread.flash_off_duration = off_time
flash_led.flash_thread.start()
def stop_led():
flash_led.flash_thread.stop_flash()