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
Greenonline
  • 2,969
  • 5
  • 27
  • 38
nixx
  • 3
  • 1
  • 3

2 Answers2

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
Chad G
  • 1,063
  • 1
  • 7
  • 14
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
nixx
  • 3
  • 1
  • 3