CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-luma--led-matrix

A Python library to drive MAX7219 LED matrices, WS2812 NeoPixels, and APA102 DotStar LEDs on Raspberry Pi

Pending
Overview
Eval results
Files

unicornhathd.mddocs/

Unicorn HAT HD

Specialized driver for Pimoroni's Unicorn HAT HD, a 16x16 RGB LED matrix (256 LEDs total) that connects via SPI interface. This device provides high-resolution RGB display capabilities for Raspberry Pi projects.

Capabilities

Device Initialization

Creates a Unicorn HAT HD device instance with configurable rotation.

class unicornhathd:
    def __init__(
        self,
        serial_interface=None,
        rotate=0,
        **kwargs
    ):
        """
        Initialize Unicorn HAT HD device.
        
        Parameters:
        - serial_interface: Serial SPI interface object (optional, defaults to None)
        - rotate: Rotation angle (0, 1, 2, 3 for 0°, 90°, 180°, 270°)
        - **kwargs: Additional parameters passed to parent device class
        """

Display Control

Controls the RGB LED matrix output with brightness and power management features.

def display(self, image):
    """
    Display a 32-bit RGBA PIL image on the 16x16 LED matrix.
    Alpha channel controls individual pixel brightness.
    
    Parameters:
    - image: PIL Image object in mode 'RGBA' (32-bit color with alpha)
             Must be 16x16 pixels to match hardware dimensions
    """

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.
    Brings LEDs back to normal brightness after hide().
    """

def hide(self):
    """
    Set contrast to zero (all LEDs appear off).
    LEDs are turned off but device remains active for quick restore.
    """

Usage Examples

Basic Setup

from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd
from luma.core.render import canvas

# Create SPI interface 
serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial)

# Draw simple pattern
with canvas(device) as draw:
    draw.rectangle((0, 0, 15, 15), outline="white")
    draw.point((8, 8), fill="red")

Rainbow Pattern

import colorsys
from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd
from luma.core.render import canvas

serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial)

# Create rainbow gradient
with canvas(device) as draw:
    for x in range(16):
        for y in range(16):
            # Calculate hue based on position
            hue = (x + y) / 32.0
            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)

Animated Plasma Effect

import time
import math
from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd
from luma.core.render import canvas

serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial)

# Plasma animation
for step in range(1000):
    with canvas(device) as draw:
        for x in range(16):
            for y in range(16):
                # Plasma calculation
                v = math.sin((x + step) * 0.2) * 0.5
                v += math.sin((y + step) * 0.15) * 0.5
                v += math.sin((x + y + step) * 0.1) * 0.5
                v += math.sin(math.sqrt((x - 8) ** 2 + (y - 8) ** 2) + step * 0.3) * 0.5
                
                # Convert to color
                hue = (v + 4) / 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((x, y), fill=color)
    
    time.sleep(0.05)

Image Display with Brightness Control

from PIL import Image
from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd

serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial)

# Load and resize image to 16x16
image = Image.open("photo.jpg")
image = image.resize((16, 16), Image.LANCZOS)
image = image.convert("RGBA")

# Display with varying brightness
for brightness in range(0, 256, 5):
    device.contrast(brightness)
    device.display(image)
    time.sleep(0.1)

Rotated Display

from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd
from luma.core.render import canvas

# Create device rotated 90 degrees
serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial, rotate=1)

# Draw text that will appear rotated
with canvas(device) as draw:
    draw.text((2, 5), "HI", fill="green")

Scrolling Text

import time
from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd
from luma.core.render import canvas
from luma.core.virtual import viewport
from luma.core.legacy import text
from luma.core.legacy.font import proportional, CP437_FONT

serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial)

# Create scrolling text
virtual = viewport(device, width=200, height=16)
text(virtual, (0, 0), "Scrolling message on Unicorn HAT HD!", 
     fill="white", font=proportional(CP437_FONT))

# Scroll the text
for offset in range(200 - 16):
    virtual.set_position((offset, 0))
    time.sleep(0.1)

Power Management

import time
from luma.core.interface.serial import spi, noop
from luma.led_matrix.device import unicornhathd
from luma.core.render import canvas

serial = spi(port=0, device=0, gpio=noop())
device = unicornhathd(serial_interface=serial)

# Draw pattern
with canvas(device) as draw:
    draw.ellipse((4, 4, 12, 12), fill="blue")

# Flash on and off
for _ in range(10):
    device.hide()   # Turn off
    time.sleep(0.5)
    device.show()   # Turn on
    time.sleep(0.5)

Hardware Specifications

  • Resolution: 16×16 RGB LEDs (256 total)
  • Color Depth: 24-bit RGB (16.7 million colors)
  • Brightness Control: 8-bit per pixel via alpha channel
  • Interface: SPI communication
  • Dimensions: 62mm × 62mm HAT form factor
  • Power: 5V via GPIO header (external supply recommended for full brightness)
  • Current Draw: Up to 2A at full white brightness

Hardware Requirements

  • Platform: Raspberry Pi with 40-pin GPIO header
  • Interface: Hardware SPI (faster performance than bitbang)
  • Connections:
    • SPI MOSI (GPIO 10)
    • SPI SCLK (GPIO 11)
    • SPI CE0 (GPIO 8)
    • 5V power supply
    • Ground connection
  • Power Supply: External 5V power supply recommended for full brightness operation

Performance Characteristics

  • Refresh Rate: High refresh rate via SPI interface
  • Update Speed: Can handle real-time animations and video
  • Memory Usage: Efficient buffering for 16×16 pixel array
  • Heat Generation: Minimal heat at moderate brightness levels

Error Handling

The device may raise the following exceptions:

  • luma.core.error.DeviceDisplayModeError: Invalid image dimensions (must be 16×16) or unsupported mode
  • RuntimeError: SPI interface initialization failures or communication errors
  • AssertionError: Invalid parameter values (brightness out of range, invalid rotation)
  • OSError: Hardware access issues or permissions problems

Compatibility Notes

  • HAT Compatibility: Designed specifically for Raspberry Pi HAT interface
  • Pin Usage: Uses SPI pins, may conflict with other SPI devices
  • Power Requirements: May require external power supply for full brightness
  • Case Compatibility: Standard HAT form factor fits most Pi cases with cutouts

Install with Tessl CLI

npx tessl i tessl/pypi-luma--led-matrix

docs

apa102.md

constants.md

index.md

max7219.md

neopixel.md

sevensegment.md

unicornhathd.md

tile.json