Lab 21: Twinkle Colors
Pixel says...
Twinkle, twinkle, little pixel! We'll make a star pop up anywhere on the strip, in any
color, and then vanish.
Program file: 21-twinkle-colors.py
What you'll learn
- How to pick a random pixel and a random color
- How to write a function with two parameters,
delayandcolor - How to pull one random item out of a tuple
- How the length of each
sleepshapes the feel of a pattern
What you'll need
- Your base kit: a Pico, a breadboard, and the 30-pixel LED strip, wired as shown in the Kit User's Guide
- The
config.pyfile saved on the Pico (see Getting Code onto the Kit) - Thonny open and connected to your Pico
The program
This program lights one random pixel in a random color for a tenth of a second. Then it turns the pixel off and waits a second before the next twinkle.
# Lab 21: Twinkle Colors
# Filename: 21-twinkle-colors.py
# Version: 1.0.0
#
# A random pixel twinkles in a random color and then goes dark.
from machine import Pin
from neopixel import NeoPixel
from utime import sleep, ticks_ms
from urandom import randint
import config
# hardware settings from config.py
NEOPIXEL_PIN = config.NEOPIXEL_PIN
NUMBER_PIXELS = config.NUMBER_PIXELS
strip = NeoPixel(Pin(NEOPIXEL_PIN), NUMBER_PIXELS)
red = (255, 0, 0)
red_med = (32, 0, 0)
red_light = (8, 0, 0)
off = (0, 0, 0)
orange = (140, 60, 0)
yellow = (255, 255, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
cyan = (0, 255, 255)
indigo = (75, 0, 130)
violet = (138, 43, 226)
white = (128, 128, 128)
colors = (red, orange, yellow, green, blue, cyan, indigo, violet)
color_count = len(colors)
levels = [255, 128, 64, 32, 16, 8, 4, 2, 1]
level_count = len(levels)
def twinkle(delay, color):
random_index = randint(0, NUMBER_PIXELS-1);
# turn on
strip[random_index] = color
strip.write();
sleep(delay);
# turn off
strip[random_index] = (0,0,0)
strip.write();
while True:
twinkle(.1, colors[randint(0, color_count-1)])
sleep(1)
Run it. A single pixel flashes somewhere on the strip and vanishes. About one second later, another pixel flashes in a new color.
How it works
The twinkle function
def twinkle(delay, color):
random_index = randint(0, NUMBER_PIXELS-1);
# turn on
strip[random_index] = color
strip.write();
sleep(delay);
# turn off
strip[random_index] = (0,0,0)
strip.write();
A function is a named block of code you can run again and again. This one has two parameters (named slots for values you hand to the function): delay and color.
The steps go in this order:
- Pick a random pixel number from 0 to 29. The top number is
NUMBER_PIXELS-1because the pixels start at 0. - Give that pixel the
color, and write it to the strip. - Wait for
delayseconds. - Set the pixel to
(0,0,0), which is off, and write again.
There are two strip.write() calls. The first shows the twinkle. The second hides it.
Some lines end with a semicolon (;). Python allows this but does not need it. Your code works the same without the semicolons.
A random color from the tuple
colors = (red, orange, yellow, green, blue, cyan, indigo, violet)
color_count = len(colors)
The colors tuple holds eight colors. A tuple is an ordered group of values inside parentheses. The len() function counts them, so color_count is 8.
while True:
twinkle(.1, colors[randint(0, color_count-1)])
sleep(1)
Read the color part from the inside out. The call randint(0, color_count-1) gives a random position from 0 to 7. Then colors[...] looks up the color at that position. That color goes into twinkle as color.
Timing
Each twinkle stays on for .1 seconds, which is a tenth of a second. Then the program waits sleep(1) for one more second. So you see about one twinkle every 1.1 seconds. Only one pixel is lit at any moment.
The program defines a few more names, such as levels and red_med, that it does not use. They are safe to ignore. Chapter 12 builds a busier twinkle with several pixels at once.
Try it yourself
- Change
sleep(1)tosleep(.2). How often does a twinkle happen now? Then try changing.1intwinkle(.1, ...)to.5. - Make the gap between twinkles random. Replace the
while True:block with this one. The/symbol divides and gives a decimal answer, so the gap is 0.1 to 2.0 seconds.
while True:
twinkle(.1, colors[randint(0, color_count-1)])
sleep(randint(1, 20) / 10)
Want the stars to fade out smoothly instead of switching off? Lab 24: Fading Stars shows how.
Check your understanding
- Why is the top number
NUMBER_PIXELS-1and notNUMBER_PIXELS? - What does
colors[randint(0, color_count-1)]give you? - About how much time passes from one twinkle to the next?
- Why does
twinklecallstrip.write()two times? - How many pixels are lit at the same time?
Lab complete!
You made a night sky out of random numbers! Picking both the place and the color by chance is a trick you'll use again.
What's next: In Lab 22: Random Walk, a dim pixel wanders left and right, one random step at a time.