Pixel Mapping
NeoPixels are numbered according to their position in the strand, starting with pixel 0. The code knows the order in which the pixels are wired, but it doesn’t automatically know where each pixel sits on the dress.
Doing a full pixel map is possible, but for a low-res flame/ember effect it's a little more than I need. Instead, I've divided the pixels into height groups. The animations will start near the hem, then move to the skirt middle, skirt top, and then dress top.
Your pixel layout will probably be different from mine. Use the pixel-identification code below to find each pixel number and create your own sections. The final code supports four different height sections of pixels: skirt bottom, skirt middle, skirt top, and dress top.
Pixel Identification Code
This is a cool mapping tool script that turns on each pixel one at a time for a few seconds, and gives you the currently-lit pixel number in the serial monitor. This way, even if your pixels are laid out in diagonals or spirals, you can still select and focus on only the pixels you want to light up.
You can access the code and necessary libraries by downloading the Project Bundle.
To do this, click on the Download Project Bundle button in the window below. It will download to your computer as a zipped folder.
# SPDX-FileCopyrightText: 2026 Erin St Blaine
# SPDX-License-Identifier: MIT
"""Light each NeoPixel individually to identify its position."""
# CircuitPython hardware modules are provided on-device, not by desktop Python.
# pylint: disable=import-error
import time
import board
import digitalio
import neopixel
NUM_PIXELS = 216
BRIGHTNESS = 0.3
# Time each pixel remains illuminated.
PIXEL_DELAY = 4.0
# Pause before starting the sequence again.
REPEAT_DELAY = 10.0
TEST_COLOR = (255, 255, 255)
EXTERNAL_POWER = digitalio.DigitalInOut(board.EXTERNAL_POWER)
EXTERNAL_POWER.direction = digitalio.Direction.OUTPUT
EXTERNAL_POWER.value = True
PIXELS = neopixel.NeoPixel(
board.EXTERNAL_NEOPIXELS,
NUM_PIXELS,
brightness=BRIGHTNESS,
auto_write=False,
pixel_order=neopixel.BGR,
)
def identify_pixels():
"""Light and print each pixel number, one at a time."""
while True:
for pixel_index in range(NUM_PIXELS):
PIXELS.fill((0, 0, 0))
PIXELS[pixel_index] = TEST_COLOR
PIXELS.show()
print("Pixel:", pixel_index)
time.sleep(PIXEL_DELAY)
PIXELS.fill((0, 0, 0))
PIXELS.show()
print("Sequence complete. Restarting soon.")
time.sleep(REPEAT_DELAY)
identify_pixels()
Upload the Code and Libraries to the RP2040 Prop-Maker Feather
After downloading the Project Bundle, plug your RP2040 Prop-Maker Feather into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the RP2040 Prop-Maker Feather's CIRCUITPY drive.
- lib folder
- code.py
Your RP2040 Prop-Maker Feather CIRCUITPY drive should look like this after copying the lib folder, and the code.py file.
Change NUM_PIXELS to match the total number of pixels in your project.
PIXEL_DELAY controls how long each pixel remains illuminated. Increase this value if the sequence moves too quickly for you to identify and record each pixel. Right now each pixel stays on for 4 seconds.
Identify the Pixel Numbers
Save the program as code.py on the CIRCUITPY drive and open the serial monitor.
The code will turn on one pixel at a time while printing its number:
Pixel: 0
Pixel: 1
Pixel: 2
Pixel: 3
Choose a dividing line for the top, middle, and bottom sections. Watch the dress as each pixel turns on, and write each pixel number into one of these groups:
-
Lower skirt
-
Middle skirt
-
Upper skirt
The sequence repeats after a short pause, so don’t worry if you miss a few pixels on the first pass.
Check Your Lists
Before returning to the main dress code, check that:
-
Every pixel number is between
0andNUM_PIXELS - 1. -
Every skirt pixel appears in one height group.
-
No skirt pixel appears in more than one height group.
-
The top pixels don’t appear in the skirt groups.
Here's what my final map list looks like:
high 0, 1, 2, 3, 4, 14, 15, 16, 17, 18, 19, 20, 21, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 161, 162, 163, 164, 165
med 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 23, 24, 25, 26, 35, 36, 37, 38, 50, 51, 52, 53, 54, 69, 70, 71, 72, 73, 91, 92, 93, 94, 108, 109, 110, 111, 112, 126, 127, 128, 136, 137, 138, 139, 140, 152, 153, 154, 155, 156, 157, 158, 159, 160
low 27, 28, 29, 30, 31, 32, 33, 34, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 129, 130, 131, 132, 133, 134, 135
I used an LLM to look over my list to make sure every number is represented and I don't have any duplicates. It found my mistakes so I could correct them and test.
Page last edited August 04, 2026
Text editor powered by tinymce.