0

I need a little help if possible.

I'm trying to make a threaded function which will make my LEDs blink randomly as long as the button is pushed. when it is released it should exit the function and turn all LEDs off.

When I run the script below I get indent errors, but have no clue on where it goes wrong. All threaded function examples I find are either far more complex or not related to changing input/interaction.

Can anyone tell me where my indent goes wrong?

from threading import Thread
from gpiozero import Button, LEDBoard
import time
import random

leds = LEDBoard(yellow=16, green=19, red=20, blue=21)
button = Button(12)

def ledrandom(self):
    while True:
        x = random.randint(0,3)  
        y = random.randint(0,3)  
        if (x != y): 
            leds[x].on()  
            leds[y].on()
            time.sleep(.1) 
            leds[x].off() 
            leds[y].off()

def pushed():
    print("pushed")
    t = Thread(target=ledrandom) # Create thread
    t.start() # Start thread

def released():
    print("released")
    leds.off() 

while True:
    button.when_pressed = pushed
    button.when_released = released
2
  • There is nothing wrong with the indenting as presented. Perhaps your local copy has a mixture of tabs and spaces?
    – joan
    Aug 14, 2018 at 15:12
  • you are right Joan, the indents itself was a local editor issue (tab/spaces got mixed up),
    – nixx
    Aug 15, 2018 at 10:24

2 Answers 2

0

should give you a line number of where it is having an indent error. The issue with your threading is that you dont have a way to stop the thread. For a simple case like this, could use a global variable like so...

This way you signal the running thread to stop, which will let it turn off the LED's and return from its function. The way you had it, you will keep launching threads that can never finish.

For a more advanced way of handling threads, look into the Queue module, this allows you to send massages back and forth between threads.

from threading import Thread
from gpiozero import Button, LEDBoard
import time
import random

leds = LEDBoard(yellow=16, green=19, red=20, blue=21)
button = Button(12)
shouldRun=False  #global variable to let the thread know when it should stop

def ledrandom():
    global shouldRun
     while shouldRun :
        x = random.randint(0,3)  
        y = random.randint(0,3)  
        if (x != y): 
            leds[x].on()  
            leds[y].on()
            time.sleep(.1) 
            leds[x].off() 
            leds[y].off()
     leds.off() #turn them off now that shouldRun is False
def pushed():
    global shouldRun
    print("pushed")
    shouldRun=True
    t = Thread(target=ledrandom) # Create thread
    t.start() # Start thread

def released():
    global shouldRun
    print("released")
    shouldRun=False

while True:
    button.when_pressed = pushed
    button.when_released = released
2
  • Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py", line 754, in run self.__target(*self.__args, self.__kwargs) **TypeError: ledrandom() takes exactly 1 argument (0 given) thanks for thinking along Chad, somehow the error above turns up when I use your code. I assume this is because the shouldRun variable doesn't reach the ledrandom function? but have no idea why not?
    – nixx
    Aug 15, 2018 at 10:31
  • ya, the 'self' shouldn't have been there, I didn't notice it when I copied your original code. I edited my answer to reflect that. Glad you got it working
    – Chad G
    Aug 15, 2018 at 15:33
0

Ok, I found a working solution as shown below. the self argument in the ledrandom function got it all confused. this works perfectly now

from threading import Thread
from gpiozero import Button, LEDBoard
import time
import random

leds = LEDBoard(yellow=16, green=19, red=20, blue=21)
button = Button(12)
ShouldRun=False  #global variable to let the thread know when it should stop

def ledrandom():
    print ("leds on")
    global ShouldRun
    while ShouldRun:
        x = random.randint(0,3)  
        y = random.randint(0,3)  
        if (x != y): 
            leds[x].on()  
            leds[y].on()
            time.sleep(.0) 
            leds[x].off() 
            leds[y].off()
    leds.off()      #turn them off now that ShouldRun is False
    print ("leds off")

def pushed():
    global ShouldRun
    ShouldRun=True
    print("pushed")
    t = Thread(target=ledrandom) # Create thread
    t.start() # Start thread

def released():
    global ShouldRun
    ShouldRun=False
    print("released")

while True:
    button.when_pressed = pushed
    button.when_released = released

Not the answer you're looking for? Browse other questions tagged or ask your own question.