Update STRIP_CONFIG

This commit is contained in:
2026-02-28 08:58:55 +13:00
parent 0c73d56ab5
commit b45823c479

View File

@@ -1,106 +1,99 @@
# """
# Pico: receive led-driver JSON from UART (one message per line). Runs Presets + patterns.
# UART RX on D7 (GPIO1). Non-blocking so presets.tick() runs every loop.
# """
# from settings import Settings
# from machine import UART, Pin
# import utime
# from presets import Presets
# from utils import convert_and_reorder_colors
# import json
# # UART (Pico XIAO: D7 = GPIO1)
# UART_RX_PIN = 1
# UART_BAUD = 115200
# UART_ID = 0
# settings = Settings()
# print(settings)
# presets = Presets(settings["led_pin"], settings["num_leds"])
# presets.load()
# presets.b = settings.get("brightness", 255)
# startup_preset = settings.get("startup_preset")
# if startup_preset:
# presets.select(startup_preset)
# print("Selected startup preset:", startup_preset)
# last_brightness_save = 0
# # Non-blocking UART
# uart = UART(UART_ID, baudrate=UART_BAUD, rx=Pin(UART_RX_PIN), rxbuf=512, timeout=0)
# uart_buf = bytearray()
# print("UART RX on pin %s, %s baud (one JSON object per line)" % (UART_RX_PIN, UART_BAUD))
# def process_message(data):
# """Handle one JSON message (led-driver protocol: v, b, presets, select, default, save)."""
# if data.get("v") != "1":
# return
# global last_brightness_save
# if "b" in data:
# try:
# presets.b = max(0, min(255, int(data["b"])))
# settings["brightness"] = presets.b
# now = utime.ticks_ms()
# if utime.ticks_diff(now, last_brightness_save) >= 500:
# settings.save()
# last_brightness_save = now
# except (TypeError, ValueError):
# pass
# if "presets" in data:
# for id, preset_data in data["presets"].items():
# if "c" in preset_data:
# preset_data["c"] = convert_and_reorder_colors(preset_data["c"], settings)
# presets.edit(id, preset_data)
# print("Edited preset", id, preset_data.get("name", ""))
# if settings.get("name") in data.get("select", {}):
# select_list = data["select"][settings.get("name")]
# if select_list:
# preset_name = select_list[0]
# step = select_list[1] if len(select_list) > 1 else None
# presets.select(preset_name, step=step)
# if "default" in data:
# settings["startup_preset"] = data["default"]
# print("Set startup preset to", data["default"])
# settings.save()
# if "save" in data:
# presets.save()
# while True:
# presets.tick()
# n = uart.any()
# if n:
# data_in = uart.read(n)
# if data_in:
# for b in data_in:
# if b in (0x0A, 0x0D): # LF or CR
# if uart_buf:
# try:
# msg = uart_buf.decode("utf-8").strip()
# if msg:
# data = json.loads(msg)
# process_message(data)
# except (ValueError, UnicodeError):
# pass
# uart_buf = bytearray()
# else:
# if len(uart_buf) < 1024:
# uart_buf.append(b)
# utime.sleep_ms(1)
from neopixel import NeoPixel
from machine import Pin
import sys
# So "from ws2812 import WS2812B" finds pico/lib when run from device / or test/
if "lib" not in sys.path:
sys.path.insert(0, "lib")
if "../lib" not in sys.path:
sys.path.insert(0, "../lib")
from ws2812 import WS2812B
import time
# --- Rainbow pattern (outside ws2812): pregen double buffer, show via head offset ---
def hue_to_rgb(hue):
"""Hue 0..360 -> (r, g, b). Simple HSV with S=V=1."""
h = hue % 360
x = 1 - abs((h / 60) % 2 - 1)
if h < 60:
r, g, b = 1, x, 0
elif h < 120:
r, g, b = x, 1, 0
elif h < 180:
r, g, b = 0, 1, x
elif h < 240:
r, g, b = 0, x, 1
elif h < 300:
r, g, b = x, 0, 1
else:
r, g, b = 1, 0, x
return (int(r * 255), int(g * 255), int(b * 255))
def make_rainbow_double(num_leds, brightness=1.0):
"""Build 2 full rainbow cycles (2*num_leds pixels, GRB). Returns (double_buf, strip_len).
head must be in 0..strip_len-1 so DMA reads double_buf[head:head+strip_len] with no copy."""
n = 2 * num_leds
double_buf = bytearray(n * 3)
for i in range(n):
hue = (i / n) * 360 * 2
r, g, b = hue_to_rgb(hue)
g = int(g * brightness) & 0xFF
r = int(r * brightness) & 0xFF
b = int(b * brightness) & 0xFF
o = i * 3
double_buf[o] = g
double_buf[o + 1] = r
double_buf[o + 2] = b
strip_len = num_leds * 3
return (double_buf, strip_len)
def show_rainbow(strip, double_buf, strip_len, head):
"""DMA reads directly from double_buf at head; no copy. head in 0..strip_len-1."""
strip.show(double_buf, head)
# --- Strips + rainbow buffers per strip ---
# Each strip can have a different length; buffers and phase are per-strip.
# Strip config must match pico/src/main.py pins.
STRIP_CONFIG = (
(7, 291),
(3, 290),
(6, 283),
(28, 278),
(29, 275),
(4, 270),
(0, 283),
(2, 290),
)
strips = []
sm = 0
pins = ((2,270), (3,271), (4,272), (0,273), (7,274), (6,275), (29,276), (28,277))
for pin, num_leds in pins:
for pin, num_leds in STRIP_CONFIG:
print(pin, num_leds)
np = WS2812B(num_leds, pin, sm, 0.1)
ws = WS2812B(num_leds, pin, sm, brightness=0.2) # 1.0 so fill() is visible
strips.append(ws)
sm += 1
np.fill((8, 0, 0))
np.show()
# Cumulative LED count before each strip; total ring size
cumulative_leds = [0]
for ws in strips[:-1]:
cumulative_leds.append(cumulative_leds[-1] + ws.num_leds)
total_ring_leds = cumulative_leds[-1] + strips[-1].num_leds
bytes_per_cycle = total_ring_leds * 3
# One rainbow double buffer per strip (length = 2 * num_leds for that strip)
now = time.ticks_ms()
rainbow_data = [make_rainbow_double(ws.num_leds, ws.brightness) for ws in strips]
# Global phase in bytes; each strip: head = (phase + cumulative_leds[i]*3) % strip_len[i]
print(time.ticks_diff(time.ticks_ms(), now), "ms")
rainbow_head = 0
step = 3
while True:
now = time.ticks_ms()
for i, (strip, (double_buf, strip_len)) in enumerate(zip(strips, rainbow_data)):
head = (rainbow_head + cumulative_leds[i] * 3) % strip_len
show_rainbow(strip, double_buf, strip_len, head)
rainbow_head = (rainbow_head + step) % bytes_per_cycle
#print(time.ticks_diff(time.ticks_ms(), now), "ms")
time.sleep_ms(10)