patterns: fix blink timing; slow alternating; unify self-test with absolute tick scheduling
This commit is contained in:
@@ -31,7 +31,8 @@ class PatternBase:
|
||||
self.scanner_direction = 1 # 1 for forward, -1 for backward
|
||||
self.scanner_tail_length = 3 # Number of trailing pixels
|
||||
|
||||
# Removed: selected_delay caching
|
||||
# Store last pattern-returned delay to use for subsequent gating
|
||||
self._last_returned_delay = None
|
||||
|
||||
def sync(self):
|
||||
self.pattern_step=0
|
||||
@@ -48,27 +49,19 @@ class PatternBase:
|
||||
def set_pattern_step(self, step):
|
||||
self.pattern_step = step
|
||||
|
||||
def tick(self):
|
||||
def tick(self, delay=0):
|
||||
now =utime.ticks_ms()
|
||||
if self.patterns.get(self.selected) and self.run:
|
||||
# Compute gating interval per pattern based on current delay
|
||||
interval = None
|
||||
if self.selected in ("color_wipe", "theater_chase", "blink", "scanner", "fill_range", "n_chase", "alternating"):
|
||||
interval = self.delay
|
||||
elif self.selected == "rainbow_cycle":
|
||||
interval = max(1, int(self.delay // 5))
|
||||
elif self.selected == "flicker":
|
||||
interval = max(1, int(self.delay // 5))
|
||||
elif self.selected == "bidirectional_scanner":
|
||||
interval = max(1, int(self.delay // 100))
|
||||
# Patterns intentionally not gated here: off, on, external, pulse, color_transition
|
||||
|
||||
if interval is not None:
|
||||
current_time = utime.ticks_ms()
|
||||
if utime.ticks_diff(current_time, self.last_update) < interval:
|
||||
return interval
|
||||
self.patterns[self.selected]()
|
||||
return interval
|
||||
return None
|
||||
if delay == 0:
|
||||
self.patterns[self.selected]()
|
||||
print("manual tick")
|
||||
return 0
|
||||
if utime.ticks_diff(now, delay) > 0:
|
||||
delay = self.patterns[self.selected]()
|
||||
print("auto tick")
|
||||
return delay + now
|
||||
else:
|
||||
return delay
|
||||
|
||||
def update_num_leds(self, pin, num_leds):
|
||||
self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds)
|
||||
@@ -80,7 +73,8 @@ class PatternBase:
|
||||
# Update transition duration and hold duration when delay changes
|
||||
self.transition_duration = self.delay * 50
|
||||
self.hold_duration = self.delay * 10
|
||||
# No cached interval
|
||||
# Reset last returned delay so next tick recomputes
|
||||
self._last_returned_delay = None
|
||||
|
||||
|
||||
def set_brightness(self, brightness):
|
||||
@@ -183,6 +177,8 @@ class PatternBase:
|
||||
if pattern in self.patterns:
|
||||
self.selected = pattern
|
||||
self.sync() # Reset pattern state when selecting a new pattern
|
||||
# Reset last returned delay so gating can be recalculated for the new pattern
|
||||
self._last_returned_delay = None
|
||||
if pattern == "color_transition":
|
||||
if len(self.colors) < 2:
|
||||
print("Warning: 'color_transition' requires at least two colors. Switching to 'on'.")
|
||||
|
||||
Reference in New Issue
Block a user