Import led-driver app: pico/ and esp32/ layout
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
64
pico/src/patterns/pulse.py
Normal file
64
pico/src/patterns/pulse.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import utime
|
||||
|
||||
|
||||
class Pulse:
|
||||
def __init__(self, driver):
|
||||
self.driver = driver
|
||||
|
||||
def run(self, preset):
|
||||
self.driver.off()
|
||||
|
||||
# Get colors from preset
|
||||
colors = preset.c
|
||||
if not colors:
|
||||
colors = [(255, 255, 255)]
|
||||
|
||||
color_index = 0
|
||||
cycle_start = utime.ticks_ms()
|
||||
|
||||
# State machine based pulse using a single generator loop
|
||||
while True:
|
||||
# Read current timing parameters from preset
|
||||
attack_ms = max(0, int(preset.n1)) # Attack time in ms
|
||||
hold_ms = max(0, int(preset.n2)) # Hold time in ms
|
||||
decay_ms = max(0, int(preset.n3)) # Decay time in ms
|
||||
delay_ms = max(0, int(preset.d))
|
||||
|
||||
total_ms = attack_ms + hold_ms + decay_ms + delay_ms
|
||||
if total_ms <= 0:
|
||||
total_ms = 1
|
||||
|
||||
now = utime.ticks_ms()
|
||||
elapsed = utime.ticks_diff(now, cycle_start)
|
||||
|
||||
base_color = colors[color_index % len(colors)]
|
||||
|
||||
if elapsed < attack_ms and attack_ms > 0:
|
||||
# Attack: fade 0 -> 1
|
||||
factor = elapsed / attack_ms
|
||||
color = tuple(int(c * factor) for c in base_color)
|
||||
self.driver.fill(self.driver.apply_brightness(color, preset.b))
|
||||
elif elapsed < attack_ms + hold_ms:
|
||||
# Hold: full brightness
|
||||
self.driver.fill(self.driver.apply_brightness(base_color, preset.b))
|
||||
elif elapsed < attack_ms + hold_ms + decay_ms and decay_ms > 0:
|
||||
# Decay: fade 1 -> 0
|
||||
dec_elapsed = elapsed - attack_ms - hold_ms
|
||||
factor = max(0.0, 1.0 - (dec_elapsed / decay_ms))
|
||||
color = tuple(int(c * factor) for c in base_color)
|
||||
self.driver.fill(self.driver.apply_brightness(color, preset.b))
|
||||
elif elapsed < total_ms:
|
||||
# Delay phase: LEDs off between pulses
|
||||
self.driver.fill((0, 0, 0))
|
||||
else:
|
||||
# End of cycle, move to next color and restart timing
|
||||
color_index += 1
|
||||
cycle_start = now
|
||||
if not preset.a:
|
||||
break
|
||||
# Skip drawing this tick, start next cycle
|
||||
yield
|
||||
continue
|
||||
|
||||
# Yield once per tick
|
||||
yield
|
||||
Reference in New Issue
Block a user