Refactor n_chase pattern for bidirectional movement
- Updated n_chase to support bidirectional movement with n3 and n4 parameters - n3 controls forward steps per direction change - n4 controls backward steps per direction change - Pattern alternates between moving forward n3 steps and backward n4 steps - Each direction repeats for the specified number of steps before switching - Added test/9.py with n1=20, n2=20, n3=20, n4=-5 parameters - Updated to run as a thread-based pattern similar to other patterns
This commit is contained in:
133
src/patterns.py
133
src/patterns.py
@@ -295,48 +295,7 @@ class Patterns(PatternBase): # Inherit from PatternBase
|
||||
self.run = False
|
||||
self.running = False
|
||||
|
||||
def n_chase(self):
|
||||
"""Chase pattern - n1 LEDs on, n2 LEDs off, moving forward"""
|
||||
self.run = True
|
||||
|
||||
# n1 = on width, n2 = off width
|
||||
on_width = max(1, int(self.n1))
|
||||
off_width = max(0, int(self.n2))
|
||||
segment_length = on_width + off_width
|
||||
|
||||
if segment_length == 0:
|
||||
segment_length = 1
|
||||
|
||||
# Calculate timing from delay
|
||||
step_delay = max(10, int(self.delay)) # At least 10ms
|
||||
|
||||
step = 0
|
||||
last_update = utime.ticks_ms()
|
||||
color = self.apply_brightness(self.colors[0])
|
||||
|
||||
while self.run:
|
||||
self.wdt.feed()
|
||||
current_time = utime.ticks_ms()
|
||||
|
||||
# Move forward every step_delay ms
|
||||
if utime.ticks_diff(current_time, last_update) >= step_delay:
|
||||
# Clear all LEDs
|
||||
self.n.fill((0, 0, 0))
|
||||
|
||||
# Draw the chase pattern - repeating segments across all LEDs
|
||||
for i in range(self.num_leds):
|
||||
pos_in_segment = (i + step) % segment_length
|
||||
if pos_in_segment < on_width:
|
||||
self.n[i] = color
|
||||
|
||||
self.n.write()
|
||||
step = (step + 1) % segment_length
|
||||
last_update = current_time
|
||||
|
||||
utime.sleep_ms(1)
|
||||
|
||||
self.run = False
|
||||
self.running = False
|
||||
|
||||
|
||||
# def flicker(self):
|
||||
# current_time = utime.ticks_ms()
|
||||
@@ -372,34 +331,74 @@ class Patterns(PatternBase): # Inherit from PatternBase
|
||||
# self.last_update = current_time
|
||||
# return self.delay
|
||||
|
||||
# def n_chase(self):
|
||||
# """
|
||||
# A theater chase pattern using n1 for on-width and n2 for off-width.
|
||||
# """
|
||||
# current_time = utime.ticks_ms()
|
||||
# step_rate = max(1, int(self.n3))
|
||||
# segment_length = self.n1 + self.n2
|
||||
# if segment_length == 0: # Avoid division by zero
|
||||
# self.fill((0,0,0))
|
||||
# self.n.write()
|
||||
# self.last_update = current_time
|
||||
# return self.delay
|
||||
def n_chase(self):
|
||||
"""Chase pattern - n1 LEDs on, n2 LEDs off, bidirectional movement"""
|
||||
self.run = True
|
||||
|
||||
# # Use controller's step for synchronization, but scale it for chasing
|
||||
# chase_step = (self.step * step_rate) % self.num_leds
|
||||
# n1 = on width, n2 = off width
|
||||
on_width = max(1, int(self.n1))
|
||||
off_width = max(0, int(self.n2))
|
||||
segment_length = on_width + off_width
|
||||
|
||||
if segment_length == 0:
|
||||
segment_length = 1
|
||||
|
||||
# n3 = forward steps per move, n4 = backward steps per move
|
||||
forward_steps = max(1, abs(int(self.n3)))
|
||||
backward_steps = max(1, abs(int(self.n4)))
|
||||
|
||||
# Calculate timing from delay
|
||||
step_delay = max(10, int(self.delay)) # At least 10ms
|
||||
|
||||
position = 0 # Current position of the chase head
|
||||
phase = "forward" # "forward" or "backward"
|
||||
steps_remaining = forward_steps
|
||||
total_steps = 0 # Track total steps for wrapping
|
||||
|
||||
last_update = utime.ticks_ms()
|
||||
color = self.apply_brightness(self.colors[0])
|
||||
|
||||
while self.run:
|
||||
self.wdt.feed()
|
||||
current_time = utime.ticks_ms()
|
||||
|
||||
# for i in range(self.num_leds):
|
||||
# # Calculate position relative to the chase head
|
||||
# pos_from_head = (i - chase_step) % self.num_leds
|
||||
# if pos_from_head < self.n1:
|
||||
# self.n[i] = self.apply_brightness(self.colors[0])
|
||||
# else:
|
||||
# self.n[i] = (0, 0, 0)
|
||||
# self.n.write()
|
||||
# Check if it's time to move
|
||||
if utime.ticks_diff(current_time, last_update) >= step_delay:
|
||||
# Move position based on current phase
|
||||
if phase == "forward":
|
||||
total_steps = (total_steps + 1) % (self.num_leds * segment_length)
|
||||
position = total_steps % segment_length
|
||||
steps_remaining -= 1
|
||||
if steps_remaining == 0:
|
||||
phase = "backward"
|
||||
steps_remaining = backward_steps
|
||||
else: # backward
|
||||
total_steps = (total_steps - 1) % (self.num_leds * segment_length)
|
||||
position = total_steps % segment_length
|
||||
steps_remaining -= 1
|
||||
if steps_remaining == 0:
|
||||
phase = "forward"
|
||||
steps_remaining = forward_steps
|
||||
|
||||
# Clear all LEDs
|
||||
self.n.fill((0, 0, 0))
|
||||
|
||||
# Draw the chase pattern - repeating segments across all LEDs
|
||||
# Position determines where to start drawing on the strip
|
||||
for i in range(self.num_leds):
|
||||
# Create repeating pattern of on_width on, off_width off
|
||||
pos_in_segment = ((i + position) % segment_length)
|
||||
if pos_in_segment < on_width:
|
||||
self.n[i] = color
|
||||
|
||||
self.n.write()
|
||||
last_update = current_time
|
||||
|
||||
utime.sleep_ms(1)
|
||||
|
||||
# # Don't update internal step - use controller's step for sync
|
||||
# self.last_update = current_time
|
||||
# return self.delay
|
||||
self.run = False
|
||||
self.running = False
|
||||
|
||||
|
||||
# def alternating(self):
|
||||
# # Use n1 as ON width and n2 as OFF width
|
||||
|
||||
Reference in New Issue
Block a user