Lab 15: Moving Band
Pixel says...
The bands are going for a walk! One growing number makes every band slide along the strip.
Let's get moving!
Program file: 15-moving-band.py
What you'll learn
- How adding a growing number to every band position makes the bands slide
- How the modulo operator
%wraps a band from the end of the strip back to the start - Why this pattern needs no erasing
- How
sleep(.03)sets the speed of the animation
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
- Lab 14: Band finished, because this lab reuses its
draw_bandfunction
The program
This program draws the six bands from Lab 14, slides them one pixel, and draws them again, forever.
Power check
The bands cover all 30 pixels, so this program draws about 780 mA at every step. A USB port supplies about 500 mA. Read How Bright Can You Go? for the details. To fix it, divide every number in the six color lines by 4, for example red = (64, 0, 0). That lowers the estimate to about 195 mA.
# Lab 15: Moving Band
# Filename: 15-moving-band.py
# Version: 1.0.0
#
# The six bands of color slide along the strip.
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)
orange = (140, 60, 0)
yellow = (255, 255, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
purple = (255, 0, 255)
def draw_band(start, end, color):
# draw the band from start to end
for i in range(start, end+1):
# use the modulo to round to within the range of the strip
strip[i % NUMBER_PIXELS] = color
strip.write()
# this is designed to work on a 30-pixel strp
i=0
while True:
draw_band(0+i, 4+i, red)
draw_band(5+i, 9+i, orange)
draw_band(10+i, 14+i, yellow)
draw_band(15+i, 19+i, green)
draw_band(20+i, 24+i, blue)
draw_band(25+i, 29+i, purple)
i += 1
sleep(.03)
Run it. The six bands slide toward the far end of the strip. Each band that leaves the end appears again at the start.
How it works
The same function as Lab 14
def draw_band(start, end, color):
# draw the band from start to end
for i in range(start, end+1):
# use the modulo to round to within the range of the strip
strip[i % NUMBER_PIXELS] = color
strip.write()
This function fills the pixels from start to end with one color. See Lab 14 for the details. Each call ends with strip.write(), so the strip updates six times in every step.
Add an offset
i=0
while True:
draw_band(0+i, 4+i, red)
draw_band(5+i, 9+i, orange)
...
i += 1
sleep(.03)
The variable i is the offset (how far the pattern has moved). It starts at 0. Every band position has i added to it.
The while True: line starts a loop (code that repeats). Each time around, i += 1 adds 1 to i. So the red band covers pixels 0 to 4 at first, then 1 to 5, then 2 to 6. The whole pattern slides toward higher pixel numbers.
Wrap around with modulo
The variable i keeps growing, but the strip only has pixels 0 to 29. The % inside draw_band solves this. Try i equal to 27. The red band asks for pixels 27, 28, 29, 30, and 31. Since 30 % 30 is 0 and 31 % 30 is 1, red lands on pixels 27, 28, 29, 0, and 1. The end of the band wraps to the start.
Without %, the second step would already fail. The purple band would ask for pixel 30 when i is 1, and the strip has no pixel 30.
You can watch this in the Modulo Wrap-Around Animation MicroSim.
No erasing needed
Six bands of five pixels cover all 30 pixels at every step. Every pixel gets a new color each time, so nothing is left behind. Later labs light only a few pixels, and those need an erase step.
Speed
The sleep(.03) line pauses for 0.03 seconds after each step. One lap around a 30-pixel strip takes 30 steps. That's 0.9 seconds of pausing, plus a little time for writing to the strip.
Try it yourself
- Change
sleep(.03)tosleep(.1)for a slow crawl. Then try.005. How does the speed change? - Change
i += 1toi -= 1. Which way do the bands slide now? Python's%turns a negative number such as -1 into a pixel number at the end of the strip.
Check your understanding
- Which line makes the bands move?
- Which pixels does the red band light when
iis 27? - Why does this program need no erasing?
- How many steps make one lap of a 30-pixel strip? About how long does a lap take?
- What would go wrong if we removed
% NUMBER_PIXELS?
Lab complete!
You made a whole rainbow of blocks glide around the strip! A growing offset plus modulo is a trick you can reuse in many patterns.
What's next: In Lab 16: Comet, a bright head with a fading tail streaks along the strip.