A Python library to drive MAX7219 LED matrices, WS2812 NeoPixels, and APA102 DotStar LEDs on Raspberry Pi
—
RGB LED strip and matrix driver supporting WS281x chips (WS2812, WS2812B, WS2811, etc.) with DMA interface for smooth animations and full-color control. NeoPixels are individually addressable RGB LEDs that can display millions of colors.
Creates a NeoPixel device instance with configurable dimensions, rotation, and pixel mapping for various LED arrangements.
class neopixel:
def __init__(
self,
dma_interface=None,
width=8,
height=4,
cascaded=None,
rotate=0,
mapping=None
):
"""
Initialize NeoPixel (WS281x) RGB LED device.
Parameters:
- dma_interface: WS2812 DMA interface (optional, auto-detected if not specified)
- width: Number of pixels horizontally (default: 8)
- height: Number of pixels vertically (default: 4)
- cascaded: Total number of pixels in strip (overrides width/height if specified)
- rotate: Rotation angle (0, 1, 2, 3 for 0°, 90°, 180°, 270°)
- mapping: Array of pixel-to-physical offset mappings for non-standard layouts
"""
# ws2812 is an alias for neopixel
ws2812 = neopixelControls the RGB LED output including color display, brightness adjustment, and cleanup operations.
def display(self, image):
"""
Display a 24-bit RGB PIL image on the NeoPixel LEDs.
Parameters:
- image: PIL Image object in mode 'RGB' (24-bit color)
"""
def contrast(self, value):
"""
Set LED intensity/brightness for all pixels.
Parameters:
- value: Brightness level (0-255, where 0 is off and 255 is full brightness)
"""
def show(self):
"""
Restore contrast to previous level.
Used after hide() to bring LEDs back to normal brightness.
"""
def hide(self):
"""
Set contrast to zero (simulated off state).
LEDs appear off but device remains active.
"""
def cleanup(self):
"""
Reset device and free hardware resources.
Should be called when finished using the device.
"""from luma.led_matrix.device import neopixel
from luma.core.render import canvas
# Create 30-pixel LED strip
device = neopixel(cascaded=30)
# Set individual pixel colors
with canvas(device) as draw:
draw.point((0, 0), fill="red")
draw.point((1, 0), fill="green")
draw.point((2, 0), fill="blue")
draw.point((3, 0), fill=(255, 128, 0)) # Orangefrom luma.led_matrix.device import neopixel
from luma.core.render import canvas
# Create 8x8 NeoPixel matrix
device = neopixel(width=8, height=8)
# Draw colorful patterns
with canvas(device) as draw:
# Rainbow diagonal
for i in range(8):
hue = i / 8.0
import colorsys
rgb = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
color = tuple(int(c * 255) for c in rgb)
draw.point((i, i), fill=color)from luma.led_matrix.device import neopixel, UNICORN_HAT
from luma.core.render import canvas
# Create 8x8 matrix with Unicorn HAT snake-like mapping
device = neopixel(width=8, height=8, mapping=UNICORN_HAT)
# Draw normally - mapping handles physical layout
with canvas(device) as draw:
draw.rectangle((0, 0, 7, 7), outline="white")import time
import math
from luma.led_matrix.device import neopixel
from luma.core.render import canvas
device = neopixel(width=8, height=4)
# Brightness control
device.contrast(128) # 50% brightness
# Animated rainbow wave
for step in range(100):
with canvas(device) as draw:
for x in range(device.width):
for y in range(device.height):
hue = (x + y + step * 0.1) % 1.0
import colorsys
rgb = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
color = tuple(int(c * 255) for c in rgb)
draw.point((x, y), fill=color)
time.sleep(0.05)
# Cleanup when done
device.cleanup()from luma.led_matrix.device import neopixel
# Custom mapping for non-standard LED arrangements
# Maps logical positions to physical LED indices
custom_mapping = [
15, 14, 13, 12, # Top row (right to left)
8, 9, 10, 11, # Second row (left to right)
7, 6, 5, 4, # Third row (right to left)
0, 1, 2, 3 # Bottom row (left to right)
]
device = neopixel(width=4, height=4, mapping=custom_mapping)UNICORN_HAT: list[int]Translation mapping for 8x8 Unicorn HAT converting snake-like physical layout to scan-like logical layout. This 64-element list maps logical pixel positions to physical LED indices.
UNICORN_HAT = [
7, 6, 5, 4, 3, 2, 1, 0,
8, 9, 10, 11, 12, 13, 14, 15,
23, 22, 21, 20, 19, 18, 17, 16,
24, 25, 26, 27, 28, 29, 30, 31,
39, 38, 37, 36, 35, 34, 33, 32,
40, 41, 42, 43, 44, 45, 46, 47,
55, 54, 53, 52, 51, 50, 49, 48,
56, 57, 58, 59, 60, 61, 62, 63
]The device may raise the following exceptions:
RuntimeError: WS281x initialization failures, DMA setup issues, or hardware communication errorsluma.core.error.DeviceDisplayModeError: Invalid display dimensions or unsupported image modeAssertionError: Invalid parameter values (brightness out of range, invalid dimensions)OverflowError: Too many pixels specified for available memory/hardware limitsInstall with Tessl CLI
npx tessl i tessl/pypi-luma--led-matrix