1

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?

Arash Hatami
  • 5,297
  • 5
  • 39
  • 59
Zarkov
  • 11
  • 3
  • One idea: when you turn on a LED, put that LED in a list with a timestamp. when it's time to turn off a LED, search that list if you find one that has been on for over 500ms. if you do, turn it off and remove from list. if not, grab a random LED from that list and turn that off. – 576i Feb 02 '16 at 08:16
  • I think you will need to use multithreading. In [this question](http://stackoverflow.com/questions/7168508/background-function-in-python) the basics are explained very well. – SebasSBM Feb 02 '16 at 08:20

1 Answers1

1

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)
Marijn van Vliet
  • 5,239
  • 2
  • 33
  • 45
  • Thanks @Rodin, that looks like a really neat solution. I'll give it a try this afternoon, I'm not that fluent in Python yet but I think I understand most of what you're doing (except maybe for the delay function at the end). – Zarkov Feb 02 '16 at 12:15
  • the `delay` function I've taken from your code example. `time.time()` gives the current time in seconds (needs to be converted to milliseconds)... wait, there's an error there... we should multiply by 1000 not divide! – Marijn van Vliet Feb 02 '16 at 12:54