Okay, we've learned how to make our blink script without relying on time.sleep(), but if we only use one LED, then it hardly makes any difference to us really. Let's add some more LEDs into the mix so we can see the the major advantage of ditching the time.sleep() calls.

This script is made to run on a Feather M4 Express, Feather nRF52840, or Feather Bluefruit Sense. With minimal tweaking, it could be adjusted to work with the Metro M4 or ItsyBitsy M4 devices.

All of the pins and other information we need to manage the blinking schedule is packed into a list of dictionaries. This makes it easy for us to iterate over them and check each one, taking action as needed to turn LEDs ON or OFF.

"""
This example script shows how to blink multiple LEDs at different
rates simultaneously without each affecting the others.
"""

import time
import board
import digitalio

BLINK_LIST = [
    {
        "ON": 0.25,
        "OFF": 0.25,
        "PREV_TIME": -1,
        "PIN": board.D5,
    },
    {
        "ON": 0.5,
        "OFF": 0.5,
        "PREV_TIME": -1,
        "PIN": board.D6,
    },
    {
        "ON": 1.0,
        "OFF": 1.0,
        "PREV_TIME": -1,
        "PIN": board.D9,
    },
    {
        "ON": 2.0,
        "OFF": 2.0,
        "PREV_TIME": -1,
        "PIN": board.D10,
    }
]

for led in BLINK_LIST:
    led["PIN"] = digitalio.DigitalInOut(led["PIN"])
    led["PIN"].direction = digitalio.Direction.OUTPUT

while True:
    # Store the current time to refer to later.
    now = time.monotonic()

    for led in BLINK_LIST:
        if led["PIN"].value is False:
            if now >= led["PREV_TIME"] + led["OFF"]:
                led["PREV_TIME"] = now
                led["PIN"].value = True
        if led["PIN"].value is True:
            if now >= led["PREV_TIME"] + led["ON"]:
                led["PREV_TIME"] = now
                led["PIN"].value = False

Circuit Playground Bluefruit

In this script, we pack all of the blinking rules into a dictionary that we can iterate over to carry out the correct blink actions at the correct times and on the correct LEDs. 

You can add more LEDs into the mix by adding new entries into the dictionary.

"""
Blinking multiple LEDs at different rates.

Circuit Playground Neopixels.
"""
import time
from adafruit_circuitplayground import cp

BLINK_MAP = {
    "RED": {
        "ON": 0.25,
        "OFF": 0.25,
        "PREV_TIME": -1,
        "INDEX": 1,
        "COLOR": (255, 0, 0)
    },
    "GREEN": {
        "ON": 0.5,
        "OFF": 0.5,
        "PREV_TIME": -1,
        "INDEX": 3,
        "COLOR": (0, 255, 0)
    },
    "BLUE": {
        "ON": 1.0,
        "OFF": 1.0,
        "PREV_TIME": -1,
        "INDEX": 6,
        "COLOR": (0, 0, 255)
    },
    "YELLOW": {
        "ON": 2.0,
        "OFF": 2.0,
        "PREV_TIME": -1,
        "INDEX": 8,
        "COLOR": (255, 255, 0)
    }
}

cp.pixels.brightness = 0.02

while True:
    # Store the current time to refer to later.
    now = time.monotonic()

    for color in BLINK_MAP.keys(): # pylint: disable=consider-iterating-dictionary

        # Is LED currently OFF?
        if cp.pixels[BLINK_MAP[color]["INDEX"]] == (0, 0, 0):
            # Is it time to turn ON?
            if now >= BLINK_MAP[color]["PREV_TIME"] + BLINK_MAP[color]["OFF"]:
                cp.pixels[BLINK_MAP[color]["INDEX"]] = BLINK_MAP[color]["COLOR"]
                BLINK_MAP[color]["PREV_TIME"] = now
        else:  # LED is ON:
            # Is it time to turn OFF?
            if now >= BLINK_MAP[color]["PREV_TIME"] + BLINK_MAP[color]["ON"]:
                cp.pixels[BLINK_MAP[color]["INDEX"]] = (0, 0, 0)
                BLINK_MAP[color]["PREV_TIME"] = now

If you want to do more advanced animations with NeoPixels, there is a library made especially for that check out this NeoPixel LED Animation Guide to learn all about it. 

This guide was first published on Oct 08, 2020. It was last updated on Oct 08, 2020.

This page (Multiple LEDs) was last updated on Oct 23, 2021.

Text editor powered by tinymce.