Rainbowchase, comet and rainbowcomet!

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.

Most animations will run individually on the SAMD21 (M0) microcontroller boards, but some combinations of animations, the most complex animations, and complex pixel mapping will not. Check out the FAQ for details. If you're interested in running all the animations, many animations together, or a complex pixel map, consider using at least a SAMD51 (M4) microcontroller.

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 left 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.

Download: file
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.

Download: file
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 or vertical_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 to True.

The NeoPixel FeatherWing lines do not run in alternating directions.

Download: file
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:

Download: file
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:

Download: file
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:

Download: file
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:

Download: file
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:

Download: file
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:

Download: file
rainbow_v = Rainbow(pixel_wing_vertical, speed=0.1, period=2)

And finally, to create a rainbow chase that animates from top to bottom:

Download: file
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.

Download: file
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.

"""
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()

This guide was first published on May 27, 2020. It was last updated on May 27, 2020.

This page (Pixel Mapping) was last updated on Nov 06, 2020.