The CircuitPython LED Animation library includes pixel mapping helpers to make it super simple to treat a single LED strip as a grid. This is handy when you are using an LED matrix that is essentially one strip in series, or if you have a series of strips arranged in a grid. This section will go over the basics of the pixel mapping feature of the library and show you how to use it with animations.
LED Matrices
Many LED matrices look like a matrix at first glance, but they're actually a strip of pixels arranged as a grid. The NeoPixel FeatherWing is a set of NeoPixels made up of 32 pixels that are arranged in an 8x4 pixel grid. It's arranged left to right, beginning in the upper left corner near the "NeoPixel FeatherWing" silk print, and ending in the bottom right near the DOUT pin, with each row beginning on the left and ending on the right.
If you want to see the pixel arrangement, try animating a comet with the initial pixel object. It will follow the pixel "strip". But what if you want to treat it as a matrix to display animations across it horizontally or vertically? PixelMap
has helpers to do exactly that.
PixelMap
The PixelMap
helper enables you to treat a strip or strips of LEDs as a grid for animation purposes. It also works great with LED matrices that are actually a strip of LEDs arranged in a matrix, such as the NeoPixel FeatherWing. The example on this page uses the NeoPixel FeatherWing, but should be quick to adapt to any grid or matrix.
First, you'll need to import the helper
module. You'll also import the other required libraries, a number of animations and colors for some of them, and AnimationSequence
.
import board import neopixel from adafruit_led_animation.animation.comet import Comet from adafruit_led_animation.animation.rainbowcomet import RainbowComet from adafruit_led_animation.animation.rainbowchase import RainbowChase from adafruit_led_animation.animation.chase import Chase from adafruit_led_animation.animation.rainbow import Rainbow from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation import helper from adafruit_led_animation.color import PURPLE, JADE, AMBER
Next you create the initial pixel object. This is identical to the pixel object used in all the previous examples - it sets up the pixels for use by the code.
If you're using some other NeoPixel form factor, update pixel_pin
and pixel_num
to match your NeoPixel setup. However, be aware that this example is designed for 32 pixels in a 8x4 matrix, and will require other changes to run properly if using a different setup.
pixel_pin = board.D6 pixel_num = 32 pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False)
Next you're going to create two new pixel objects using the PixelMap
and horizontal_strip_gridmap
helpers. One will be to create grid on which to animate vertically, and the other to animate horizontally.
PixelMap has two grid options for creating a grid: vertical_lines
and horizontal_lines
. The first generates a pixel map of vertical lines on a strip arranged in a grid, and the second generates a pixel map of horizontal lines on a strip arranged in a grid. Both of these helpers have four required arguments.
-
pixel_object
: The initial pixel object, e.g.pixels
. -
width
: The width of the grid, e.g.8
. -
height
: The height of the grid, e.g.4
. -
gridmap
: A function to map x and y coordinates to the grid, e.g.horizontal_strip_gridmap
orvertical_strip_gridmap
.
As the NeoPixel FeatherWing is arranged horizontally, you'll be using the horizontal_strip_gridmap
helper. It has one required argument and one optional argument.
Required:
-
width
: The grid width in pixels, e.g.8
.
Optional:
-
alternating
: Whether or not the lines in the grid are running alternating directions in a zigzag. Defaults toTrue
.
The NeoPixel FeatherWing lines do not run in alternating directions.
pixel_wing_vertical = helper.PixelMap.vertical_lines( pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False) ) pixel_wing_horizontal = helper.PixelMap.horizontal_lines( pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False) )
Now that you've created these pixel objects, you can use them with the animations, the same way you used the initial pixel object.
To create a purple comet that is the width of the grid and animates top to bottom, you would create a comet animation as follows:
comet_h = Comet( pixel_wing_horizontal, speed=0.1, color=PURPLE, tail_length=3, bounce=True )
To create an amber comet that is the height of the grid and animates left to right, you would create a comet as follows:
comet_v = Comet(pixel_wing_vertical, speed=0.1, color=AMBER, tail_length=6, bounce=True)
To create a jade chase animation that animates from top to bottom:
chase_h = Chase(pixel_wing_horizontal, speed=0.1, size=3, spacing=6, color=JADE)
To create a rainbow chase animation that animates from left to right:
rainbow_chase_v = RainbowChase( pixel_wing_vertical, speed=0.1, size=3, spacing=2, wheel_step=8 )
To create a rainbow comet that animates across the grid from left to right:
rainbow_comet_v = RainbowComet( pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True )
To create a rainbow that cycles across the grid vertically:
rainbow_v = Rainbow(pixel_wing_vertical, speed=0.1, period=2)
And finally, to create a rainbow chase that animates from top to bottom:
rainbow_chase_h = RainbowChase(pixel_wing_horizontal, speed=0.1, size=3, spacing=3)
Then you would display these animations the same way you did previously.
animations = AnimationSequence( rainbow_v, comet_h, rainbow_comet_v, chase_h, rainbow_chase_v, comet_v, rainbow_chase_h, advance_interval=5, ) while True: animations.animate()
The same follows for any other animation. Some animations do not make sense to use with these helpers like blink, colorcycle, sparkle and pulse, as they use all the LEDs and the arrangement is irrelevant.
Now you can create animations that display horizontally and vertically across a grid!
Full Example Code
This example displays five different animations horizontally and vertically across a grid.
# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries # SPDX-License-Identifier: MIT """ This example shows usage of the PixelMap helper to easily treat a single strip as a horizontal or vertical grid for animation purposes. For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using a different form of NeoPixels. Note that if you are using a number of pixels other than 32, you will need to alter the PixelMap values as well for this example to work. This example does not work on SAMD21 (M0) boards. """ import board import neopixel from adafruit_led_animation.animation.comet import Comet from adafruit_led_animation.animation.rainbowcomet import RainbowComet from adafruit_led_animation.animation.rainbowchase import RainbowChase from adafruit_led_animation.animation.chase import Chase from adafruit_led_animation.animation.rainbow import Rainbow from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation import helper from adafruit_led_animation.color import PURPLE, JADE, AMBER # Update to match the pin connected to your NeoPixels pixel_pin = board.D6 # Update to match the number of NeoPixels you have connected pixel_num = 32 pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.5, auto_write=False) pixel_wing_vertical = helper.PixelMap.vertical_lines( pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False) ) pixel_wing_horizontal = helper.PixelMap.horizontal_lines( pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False) ) comet_h = Comet( pixel_wing_horizontal, speed=0.1, color=PURPLE, tail_length=3, bounce=True ) comet_v = Comet(pixel_wing_vertical, speed=0.1, color=AMBER, tail_length=6, bounce=True) chase_h = Chase(pixel_wing_horizontal, speed=0.1, size=3, spacing=6, color=JADE) rainbow_chase_v = RainbowChase( pixel_wing_vertical, speed=0.1, size=3, spacing=2, step=8 ) rainbow_comet_v = RainbowComet( pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True ) rainbow_v = Rainbow(pixel_wing_vertical, speed=0.1, period=2) rainbow_chase_h = RainbowChase(pixel_wing_horizontal, speed=0.1, size=3, spacing=3) animations = AnimationSequence( rainbow_v, comet_h, rainbow_comet_v, chase_h, rainbow_chase_v, comet_v, rainbow_chase_h, advance_interval=5, ) while True: animations.animate()
Page last edited January 22, 2025
Text editor powered by tinymce.