Zarkov
Zarkov

Reputation: 11

Python: Turning on random LEDs and delay turning off

I have 100 adresseable LED:s connected to a RPi and would like to have them blink at random.

My initial thought was to create a randomized list at startup containing the 100 numbers and then turn them on one after another in a loop. After a certain amount of time I would like to turn them off again.

RGBlist = [100 random numbers 0-99]
for i in RGBlist:
    turnOnLED(i)

How do I start a second loop to run concurrently with the first one?

delay(X ms)
for i in RGBlist:
    turnOffLED(i)

I don't want all 100 LEDs to turn on before turning them off again one at a time, I'd like LED(x) to turn on, then LED(y), LED(z), LED(x) turn off, LED(u) turn on, LED(y) turn off and so on. Even better if they can be turned off after being lit for an arbitrary time of 100-500 ms.

Do I need to enter the deep, dark caves of multiprocessing and threading for this?

Upvotes: 1

Views: 2531

Answers (1)

Marijn van Vliet
Marijn van Vliet

Reputation: 5409

I don't think you have to resort to multithreading. You can make an action plan first and then execute it. For example:

import random
import time

RGBlist = [random.randint(0, 100) for _ in range(100)]
delay = 1000  # in milliseconds

# Make a todo list. 
# Columns are: time, led, on/off

# First add the entries to turn all leds on
todo = [(delay * i, led, True) for i, led in enumerate(RGBlist)]

# Now add the entries to turn them all off at random intervals
todo += [(delay * i + random.randint(100, 500), led, False)
         for i, led in enumerate(RGBlist)]

# Sort the list by the first column: time
todo.sort(key=lambda x: x[0])

# Iterate over the list and perform the actions in sequence
for action_time, led, on in todo:
    # Wait until it is time to perform the action
    delay(action_time - time.time() * 1000)  # In milliseconds

    # Perform the action
    if on:
        turnOnLed(led)
    else:
        turnOffLed(led)

Upvotes: 1

Related Questions