Import led-driver app: pico/ and esp32/ layout
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
124
pico/src/patterns/chase.py
Normal file
124
pico/src/patterns/chase.py
Normal file
@@ -0,0 +1,124 @@
|
||||
import utime
|
||||
|
||||
|
||||
class Chase:
|
||||
def __init__(self, driver):
|
||||
self.driver = driver
|
||||
|
||||
def run(self, preset):
|
||||
"""Chase pattern: n1 LEDs of color0, n2 LEDs of color1, repeating.
|
||||
Moves by n3 on even steps, n4 on odd steps (n3/n4 can be positive or negative)"""
|
||||
colors = preset.c
|
||||
if len(colors) < 1:
|
||||
# Need at least 1 color
|
||||
return
|
||||
|
||||
# Access colors, delay, and n values from preset
|
||||
if not colors:
|
||||
return
|
||||
# If only one color provided, use it for both colors
|
||||
if len(colors) < 2:
|
||||
color0 = colors[0]
|
||||
color1 = colors[0]
|
||||
else:
|
||||
color0 = colors[0]
|
||||
color1 = colors[1]
|
||||
|
||||
color0 = self.driver.apply_brightness(color0, preset.b)
|
||||
color1 = self.driver.apply_brightness(color1, preset.b)
|
||||
|
||||
n1 = max(1, int(preset.n1)) # LEDs of color 0
|
||||
n2 = max(1, int(preset.n2)) # LEDs of color 1
|
||||
n3 = int(preset.n3) # Step movement on even steps (can be negative)
|
||||
n4 = int(preset.n4) # Step movement on odd steps (can be negative)
|
||||
|
||||
segment_length = n1 + n2
|
||||
|
||||
# Calculate position from step_count
|
||||
step_count = 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
|
||||
position = (step_count // 2) * (n3 + n4) + n3
|
||||
else:
|
||||
# Odd steps: ((step_count+1)//2) pairs of (n3+n4)
|
||||
position = ((step_count + 1) // 2) * (n3 + n4)
|
||||
|
||||
# Wrap position to keep it reasonable
|
||||
max_pos = self.driver.num_leds + segment_length
|
||||
position = position % max_pos
|
||||
if position < 0:
|
||||
position += max_pos
|
||||
|
||||
# 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):
|
||||
# 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
|
||||
|
||||
self.driver.n.write()
|
||||
|
||||
# Increment step for next beat
|
||||
self.driver.step = step_count + 1
|
||||
|
||||
# Allow tick() to advance the generator once
|
||||
yield
|
||||
return
|
||||
|
||||
# Auto mode: continuous loop
|
||||
# Use transition_duration for timing and force the first update to happen immediately
|
||||
transition_duration = max(10, int(preset.d))
|
||||
last_update = utime.ticks_ms() - transition_duration
|
||||
|
||||
while True:
|
||||
current_time = utime.ticks_ms()
|
||||
if utime.ticks_diff(current_time, last_update) >= transition_duration:
|
||||
# Calculate current position from step_count
|
||||
if step_count % 2 == 0:
|
||||
position = (step_count // 2) * (n3 + n4) + n3
|
||||
else:
|
||||
position = ((step_count + 1) // 2) * (n3 + n4)
|
||||
|
||||
# Wrap position
|
||||
max_pos = self.driver.num_leds + segment_length
|
||||
position = position % max_pos
|
||||
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):
|
||||
# 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
|
||||
|
||||
self.driver.n.write()
|
||||
|
||||
# Increment step
|
||||
step_count += 1
|
||||
self.driver.step = step_count
|
||||
last_update = current_time
|
||||
|
||||
# Yield once per tick so other logic can run
|
||||
yield
|
||||
Reference in New Issue
Block a user