Files
python-editor/workspace/code/pattern_chase_demo.py

84 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Knight Riderstyle bouncing scanner — self-contained (stdlib + simulated hardware only)."""
import time
from machine import Pin
import neopixel
# --- helpers
def _clamp(channel: int) -> int:
return max(0, min(255, int(channel)))
def _bounce_head_index(led_count: int, frame: int) -> int:
if led_count <= 1:
return 0
span = led_count - 1
cycle = span * 2
if cycle <= 0:
return 0
t = frame % cycle
return t if t <= span else 2 * span - t
def _bounce_phase_tail_direction(led_count: int, frame: int) -> int:
if led_count <= 1:
return -1
span = led_count - 1
cycle = span * 2
if cycle <= 0:
return -1
t = frame % cycle
if t <= span:
return -1
return 1
def knight_rider_scanner_frame(
led_count: int,
frame: int,
head_color=(220, 0, 28),
tail_len: int = 8,
falloff_gamma: float = 2.6,
):
if led_count <= 0:
return []
out = [(0, 0, 0) for _ in range(led_count)]
tl = max(1, tail_len)
head = _bounce_head_index(led_count, frame)
direc = _bounce_phase_tail_direction(led_count, frame)
gamma = max(1.05, falloff_gamma)
for rk in reversed(range(tl)):
idx = head + direc * rk
if idx < 0 or idx >= led_count:
continue
w = max(0.0, float(tl - rk) / float(tl))
strength = w**gamma
out[idx] = tuple(_clamp(int(head_color[ch] * strength)) for ch in range(3))
return out
# --- demo
NUM_LEDS = 16
np = neopixel.NeoPixel(Pin(4), NUM_LEDS)
for frame in range(200):
frame_colors = knight_rider_scanner_frame(
len(np),
frame,
head_color=(220, 0, 36),
tail_len=10,
falloff_gamma=2.85,
)
for i, color in enumerate(frame_colors):
np[i] = color
np.write()
time.sleep(0.05)
np.fill((0, 0, 0))
np.write()