Add portal web simulator, SPI bridges, and Pico firmware updates.
Bring the five-panel hex portal online with a browser 3D/schematic preview, Pi SPI backends, and renamed multi-panel Pico UDP firmware. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
114
examples/spi_rgb_test.py
Normal file
114
examples/spi_rgb_test.py
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Full-panel red / green / blue over SPI (GPIO 10 on Pi 5)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from leds.array_config import (
|
||||
MATRIX_BRIGHTNESS,
|
||||
MATRIX_SPI_BUS,
|
||||
MATRIX_SPI_DEVICE,
|
||||
panel_layout,
|
||||
panel_pixel_count,
|
||||
)
|
||||
from leds.colors import BLUE, GREEN, OFF, RED, WHITE
|
||||
from leds.config import panel_strip_config, spi_strip_config
|
||||
from leds.matrix import LedMatrix
|
||||
|
||||
COLORS = (
|
||||
("RED", RED),
|
||||
("GREEN", GREEN),
|
||||
("BLUE", BLUE),
|
||||
("WHITE", WHITE),
|
||||
("OFF", OFF),
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="R/G/B color test on a WS2812 strip via SPI"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--panel-index",
|
||||
type=int,
|
||||
default=2,
|
||||
choices=range(5),
|
||||
metavar="N",
|
||||
help="Panel layout for width×height (default: 2 = top / Pi)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--count",
|
||||
type=int,
|
||||
default=None,
|
||||
help="LED count override (default: panel width × 9)",
|
||||
)
|
||||
parser.add_argument("--brightness", type=float, default=MATRIX_BRIGHTNESS)
|
||||
parser.add_argument(
|
||||
"--spi-bus",
|
||||
type=int,
|
||||
default=int(os.environ.get("PORTAL_SPI_BUS", MATRIX_SPI_BUS)),
|
||||
)
|
||||
parser.add_argument("--spi-device", type=int, default=MATRIX_SPI_DEVICE)
|
||||
parser.add_argument(
|
||||
"--spi-mhz",
|
||||
type=float,
|
||||
default=4.2,
|
||||
help="SPI clock in MHz (default: 4.2)",
|
||||
)
|
||||
parser.add_argument("--pause", type=float, default=1.5)
|
||||
args = parser.parse_args()
|
||||
|
||||
width, height = panel_layout(args.panel_index)
|
||||
pixels = args.count if args.count is not None else panel_pixel_count(args.panel_index)
|
||||
spi_hz = max(1, int(args.spi_mhz * 1_000_000))
|
||||
|
||||
if args.count is not None:
|
||||
if pixels % width != 0:
|
||||
parser.error(f"--count {pixels} is not a multiple of width {width}")
|
||||
height = pixels // width
|
||||
cfg = spi_strip_config(
|
||||
pixels,
|
||||
spi_bus=args.spi_bus,
|
||||
spi_device=args.spi_device,
|
||||
spi_max_speed_hz=spi_hz,
|
||||
brightness=args.brightness,
|
||||
passthrough=True,
|
||||
swap_rg=True,
|
||||
)
|
||||
else:
|
||||
cfg = panel_strip_config(
|
||||
args.panel_index,
|
||||
pixels,
|
||||
spi_max_speed_hz=spi_hz,
|
||||
brightness=args.brightness,
|
||||
passthrough=True,
|
||||
swap_rg=True,
|
||||
)
|
||||
|
||||
print(
|
||||
f"SPI RGB test: {width}×{height} ({pixels} LEDs), "
|
||||
f"bus {args.spi_bus}, {args.spi_mhz:g} MHz, passthrough RGB"
|
||||
)
|
||||
|
||||
try:
|
||||
with LedMatrix(width, height, config0=cfg) as matrix:
|
||||
for label, color in COLORS:
|
||||
print(f" {label}")
|
||||
matrix.fill(color)
|
||||
matrix.show()
|
||||
time.sleep(args.pause)
|
||||
except KeyboardInterrupt:
|
||||
print("\nStopped.")
|
||||
except OSError as exc:
|
||||
print(f"SPI error: {exc}", file=sys.stderr)
|
||||
print("Enable SPI and wire DIN → GPIO 10 (/dev/spidev0.0).", file=sys.stderr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user