Add Pico presets engine, patterns, and tests.
Wire the Pico to UART-driven preset selection, add pattern modules and presets data, remove old p2p/settings code, and update tests and LED driver. Made-with: Cursor
This commit is contained in:
@@ -28,13 +28,13 @@ def hue_to_rgb(hue):
|
||||
return (int(r * 255), int(g * 255), int(b * 255))
|
||||
|
||||
|
||||
def make_rainbow_ring(total_leds, brightness=1.0):
|
||||
"""Build one rainbow over the whole ring: 2 full hue cycles over total_leds (GRB).
|
||||
Returns (double_buf, ring_len_bytes). All strips sample from this so phase is continuous."""
|
||||
n = 2 * total_leds
|
||||
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 % total_leds) / total_leds) * 360 * 2
|
||||
hue = (i / n) * 360 * 2
|
||||
r, g, b = hue_to_rgb(hue)
|
||||
g = int(g * brightness) & 0xFF
|
||||
r = int(r * brightness) & 0xFF
|
||||
@@ -43,48 +43,27 @@ def make_rainbow_ring(total_leds, brightness=1.0):
|
||||
double_buf[o] = g
|
||||
double_buf[o + 1] = r
|
||||
double_buf[o + 2] = b
|
||||
ring_len_bytes = total_leds * 3
|
||||
return (double_buf, ring_len_bytes)
|
||||
strip_len = num_leds * 3
|
||||
return (double_buf, strip_len)
|
||||
|
||||
|
||||
def make_strip_rainbow(num_leds, cumulative_leds, total_ring_leds, brightness=1.0):
|
||||
"""Per-strip double buffer: pixel j has hue at global position (cumulative_leds + j) % total_ring_leds.
|
||||
Use same head for all strips: head = rainbow_head % (2*num_leds*3)."""
|
||||
n = 2 * num_leds
|
||||
buf = bytearray(n * 3)
|
||||
for j in range(n):
|
||||
global_pos = (cumulative_leds + j) % total_ring_leds
|
||||
hue = (global_pos / total_ring_leds) * 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 = j * 3
|
||||
buf[o] = g
|
||||
buf[o + 1] = r
|
||||
buf[o + 2] = b
|
||||
strip_len_bytes = num_leds * 3
|
||||
return (buf, strip_len_bytes)
|
||||
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)
|
||||
|
||||
|
||||
def show_rainbow_segment(strip, buf, strip_len_bytes, head):
|
||||
"""DMA reads strip's segment from buf at head."""
|
||||
strip.show(buf, head)
|
||||
|
||||
|
||||
# --- Strips + one global ring rainbow (all strips in phase) ---
|
||||
# Each strip can have a different length; one rainbow spans total_ring_leds so hue is continuous.
|
||||
|
||||
# (pin, num_leds) per strip — lengths differ per segment
|
||||
# --- 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 = (
|
||||
(2, 291),
|
||||
(7, 291),
|
||||
(3, 290),
|
||||
(4, 283),
|
||||
(7, 278),
|
||||
(0, 275),
|
||||
(6, 283),
|
||||
(28, 278),
|
||||
(29, 283),
|
||||
(6, 290),
|
||||
(29, 275),
|
||||
(4, 278),
|
||||
(0, 283),
|
||||
(2, 290),
|
||||
)
|
||||
|
||||
strips = []
|
||||
@@ -102,24 +81,19 @@ for ws in strips[:-1]:
|
||||
total_ring_leds = cumulative_leds[-1] + strips[-1].num_leds
|
||||
bytes_per_cycle = total_ring_leds * 3
|
||||
|
||||
# Per-strip rainbow buffers: each strip's segment of the ring (same phase, no shared-buffer DMA)
|
||||
# One rainbow double buffer per strip (length = 2 * num_leds for that strip)
|
||||
now = time.ticks_ms()
|
||||
rainbow_data = [
|
||||
make_strip_rainbow(ws.num_leds, cumulative_leds[i], total_ring_leds, ws.brightness)
|
||||
for i, ws in enumerate(strips)
|
||||
]
|
||||
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, (buf, strip_len_bytes)) in enumerate(zip(strips, rainbow_data)):
|
||||
# Same head for all: each strip's buffer is already offset by cumulative_leds[i]
|
||||
double_len_bytes = 2 * strip.num_leds * 3
|
||||
head = rainbow_head % double_len_bytes
|
||||
show_rainbow_segment(strip, buf, strip_len_bytes, head)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user