import utime class SegmentChase: def __init__(self, driver): self.driver = driver def run(self, preset): """Independent moving segments (distinct from classic two-color chase). n1: segment size (LEDs per segment) n2: step size (phase increment each frame) n3: per-segment phase offset n4: gap spacing inside segment (0 = solid segment) """ colors = preset.c if preset.c else [(255, 0, 0), (0, 0, 255)] seg = max(1, int(preset.n1) if int(preset.n1) > 0 else 4) phase_step = max(1, int(preset.n2) if int(preset.n2) > 0 else 1) seg_offset = max(0, int(preset.n3)) gap = max(0, int(preset.n4)) phase = self.driver.step % 256 last = utime.ticks_ms() while True: d = max(1, int(preset.d)) now = utime.ticks_ms() if utime.ticks_diff(now, last) >= d: for i in range(self.driver.num_leds): seg_idx = i // seg in_seg = i % seg local_phase = (phase + seg_idx * seg_offset) % seg lit_idx = (in_seg + local_phase) % seg if gap > 0 and lit_idx >= max(1, seg - gap): self.driver.n[i] = (0, 0, 0) else: color_idx = seg_idx % len(colors) self.driver.n[i] = self.driver.apply_brightness(colors[color_idx], preset.b) self.driver.n.write() phase = (phase + phase_step) % seg self.driver.step = phase last = utime.ticks_add(last, d) if not preset.a: yield return yield