Add multi-panel Pico UDP firmware and Python LED control.

Pico panels get static IPs on 10.1.1.10–14 with per-panel LED counts, Makefile deploy targets, and Python examples for animations, sync tests, and direct Pi SPI control.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-28 22:46:08 +12:00
parent d8323bb9a3
commit d5cab2efdf
52 changed files with 4677 additions and 1 deletions

69
examples/setup_pi5_leds.py Executable file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/env python3
"""Print or install Pi 5 ws2812-pio overlay lines for two strips."""
from __future__ import annotations
import argparse
import sys
from pathlib import Path
CONFIG = Path("/boot/firmware/config.txt")
MARKER = "# portal ws2812 strips"
def overlay_lines(count0: int, count1: int, gpio0: int, gpio1: int) -> list[str]:
return [
MARKER,
f"dtoverlay=ws2812-pio,gpio={gpio0},num_leds={count0}",
f"dtoverlay=ws2812-pio,gpio={gpio1},num_leds={count1}",
]
def main() -> int:
parser = argparse.ArgumentParser(
description="Configure Pi 5 ws2812-pio overlays for two LED strips"
)
parser.add_argument("-n", type=int, nargs=2, default=[10, 10], metavar=("STRIP0", "STRIP1"))
parser.add_argument("--gpio0", type=int, default=18, help="strip 0 data pin (default 18)")
parser.add_argument("--gpio1", type=int, default=13, help="strip 1 data pin (default 13)")
parser.add_argument(
"--install",
action="store_true",
help="append overlay lines to /boot/firmware/config.txt (requires sudo)",
)
args = parser.parse_args()
lines = overlay_lines(args.n[0], args.n[1], args.gpio0, args.gpio1)
print("Add these lines to /boot/firmware/config.txt under [all], then reboot:\n")
for line in lines:
print(line)
print(
f"\nWiring: strip 0 DIN → GPIO {args.gpio0}, strip 1 DIN → GPIO {args.gpio1}, "
"GND → Pi GND, 5V from external supply for long strips."
)
print("\nAfter reboot you should see /dev/leds0 and /dev/leds1.")
if not args.install:
return 0
if not CONFIG.exists():
print(f"Error: {CONFIG} not found", file=sys.stderr)
return 1
text = CONFIG.read_text()
if MARKER in text:
print("\nOverlay lines already present in config.txt.")
return 0
with CONFIG.open("a") as f:
f.write("\n")
for line in lines:
f.write(line + "\n")
print(f"\nAppended to {CONFIG}. Reboot to apply.")
return 0
if __name__ == "__main__":
raise SystemExit(main())