Refine calibration, chase, and spin patterns and add spin test

Increase calibration brightness, update chase to use the new logical ring abstraction, and make spin start from a cleared frame with symmetric arm speed, alongside a dedicated on-device spin test script.

Made-with: Cursor
This commit is contained in:
2026-03-05 23:41:25 +13:00
parent 3e58f4e97e
commit 5f457b3ae7
4 changed files with 157 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
"""Calibration: strips 2 and 6 only. First 10 green, then alternating 10 blue / 10 red. 10% brightness."""
BRIGHTNESS = 0.10
BRIGHTNESS = 1
BLOCK = 10
STRIPS_ON = (2, 6) # 0-based: 3rd and 7th strip only
@@ -22,6 +22,7 @@ class Calibration:
green = _scale(GREEN, BRIGHTNESS)
red = _scale(RED, BRIGHTNESS)
blue = _scale(BLUE, BRIGHTNESS)
blue = (0,0,0)
on_set = set(STRIPS_ON)
for strip_idx, strip in enumerate(strips):
n = strip.num_leds

View File

@@ -35,7 +35,7 @@ class Chase:
segment_length = n1 + n2
# Calculate position from step_count
step_count = self.driver.step
step_count = int(self.driver.step)
# Position alternates: step 0 adds n3, step 1 adds n4, step 2 adds n3, etc.
if step_count % 2 == 0:
# Even steps: (step_count//2) pairs of (n3+n4) plus one extra n3
@@ -52,23 +52,23 @@ class Chase:
# If auto is False, run a single step and then stop
if not preset.a:
# Clear all LEDs
self.driver.n.fill((0, 0, 0))
# Draw repeating pattern starting at position
for i in range(self.driver.num_leds):
# Draw repeating pattern starting at position across all physical strips
num_leds = self.driver.num_leds
num_strips = len(self.driver.strips)
for i in range(num_leds):
# Calculate position in the repeating segment
relative_pos = (i - position) % segment_length
if relative_pos < 0:
relative_pos = (relative_pos + segment_length) % segment_length
# Determine which color based on position in segment
if relative_pos < n1:
self.driver.n[i] = color0
else:
self.driver.n[i] = color1
color = color0 if relative_pos < n1 else color1
self.driver.n.write()
# Apply this logical LED to every physical strip via driver.set()
for strip_idx in range(num_strips):
self.driver.set(strip_idx, i, color)
self.driver.show_all()
# Increment step for next beat
self.driver.step = step_count + 1
@@ -97,23 +97,23 @@ class Chase:
if position < 0:
position += max_pos
# Clear all LEDs
self.driver.n.fill((0, 0, 0))
# Draw repeating pattern starting at position
for i in range(self.driver.num_leds):
# Draw repeating pattern starting at position across all physical strips
num_leds = self.driver.num_leds
num_strips = len(self.driver.strips)
for i in range(num_leds):
# Calculate position in the repeating segment
relative_pos = (i - position) % segment_length
if relative_pos < 0:
relative_pos = (relative_pos + segment_length) % segment_length
# Determine which color based on position in segment
if relative_pos < n1:
self.driver.n[i] = color0
else:
self.driver.n[i] = color1
color = color0 if relative_pos < n1 else color1
self.driver.n.write()
# Apply this logical LED to every physical strip via driver.set()
for strip_idx in range(num_strips):
self.driver.set(strip_idx, i, color)
self.driver.show_all()
# Increment step
step_count += 1

View File

@@ -2,7 +2,7 @@
import utime
SPAN = 10 # LEDs on each side of center (match Grab)
SPAN = 0 # LEDs on each side of center (match Grab)
LUT_SIZE = 256 # gradient lookup table entries
@@ -12,6 +12,9 @@ class Spin:
def run(self, preset):
strips = self.driver.strips
self.driver.fill((0, 0, 0))
self.driver.show_all()
active_indices = (0, 4)
c0 = preset.c[0]
c1 = preset.c[1]
@@ -58,8 +61,8 @@ class Spin:
n = strip.num_leds
mid = midpoints[idx]
# Expand arms: inside (strip 1, idx 0) moves slower, outside (strip 5, idx 4) faster
step = max(1, rate // 2) if idx == 0 else rate
# Expand arms at the same rate on both sides
step = max(1, rate)
new_left = max(margin, left[idx] - step)
new_right = min(n - margin, right[idx] + step)