Initial commit
This commit is contained in:
145
src/patterns_base.py
Normal file
145
src/patterns_base.py
Normal file
@@ -0,0 +1,145 @@
|
||||
from machine import Pin
|
||||
from neopixel import NeoPixel
|
||||
import utime
|
||||
|
||||
|
||||
|
||||
|
||||
# Short-key parameter mapping for convenience setters
|
||||
param_mapping = {
|
||||
"pt": "selected",
|
||||
"pa": "selected",
|
||||
"cl": "colors",
|
||||
"br": "brightness",
|
||||
"dl": "delay",
|
||||
"nl": "num_leds",
|
||||
"co": "color_order",
|
||||
"lp": "led_pin",
|
||||
"n1": "n1",
|
||||
"n2": "n2",
|
||||
"n3": "n3",
|
||||
"n4": "n4",
|
||||
"n5": "n5",
|
||||
"n6": "n6",
|
||||
"auto": "auto",
|
||||
}
|
||||
|
||||
class Patterns:
|
||||
def __init__(self, pin, num_leds, color1=(0,0,0), color2=(0,0,0), brightness=127, selected="off", delay=100):
|
||||
self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds)
|
||||
self.num_leds = num_leds
|
||||
self.pattern_step = 0
|
||||
self.last_update = utime.ticks_ms()
|
||||
self.delay = delay
|
||||
self.brightness = brightness
|
||||
self.auto = False
|
||||
self.patterns = {}
|
||||
self.selected = selected
|
||||
# Ensure colors list always starts with at least two for robust transition handling
|
||||
self.colors = [color1, color2] if color1 != color2 else [color1, (255, 255, 255)] # Fallback if initial colors are same
|
||||
if not self.colors: # Ensure at least one color exists
|
||||
self.colors = [(0, 0, 0)]
|
||||
|
||||
self.transition_duration = delay * 50 # Default transition duration
|
||||
self.hold_duration = delay * 10 # Default hold duration at each color
|
||||
self.transition_step = 0 # Current step in the transition
|
||||
self.current_color_idx = 0 # Index of the color currently being held/transitioned from
|
||||
self.current_color = self.colors[self.current_color_idx] # The actual blended color
|
||||
|
||||
self.hold_start_time = utime.ticks_ms() # Time when the current color hold started
|
||||
|
||||
# New attributes for scanner patterns
|
||||
self.scanner_direction = 1 # 1 for forward, -1 for backward
|
||||
self.scanner_tail_length = 3 # Number of trailing pixels
|
||||
|
||||
self.n1 = 0
|
||||
self.n2 = 0
|
||||
self.n3 = 0
|
||||
self.n4 = 0
|
||||
self.n5 = 0
|
||||
self.n6 = 0
|
||||
|
||||
self.generator = None
|
||||
self.select(self.selected)
|
||||
|
||||
|
||||
def tick(self):
|
||||
if self.generator is None:
|
||||
return
|
||||
try:
|
||||
next(self.generator)
|
||||
except StopIteration:
|
||||
self.generator = None
|
||||
|
||||
def select(self, pattern):
|
||||
if pattern in self.patterns:
|
||||
self.selected = pattern
|
||||
self.generator = self.patterns[pattern]()
|
||||
print(f"Selected pattern: {pattern}")
|
||||
return True
|
||||
# If pattern doesn't exist, default to "off"
|
||||
return False
|
||||
|
||||
def set_param(self, key, value):
|
||||
if key in param_mapping:
|
||||
setattr(self, param_mapping[key], value)
|
||||
return True
|
||||
print(f"Invalid parameter: {key}")
|
||||
return False
|
||||
|
||||
def update_num_leds(self, pin, num_leds):
|
||||
self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds)
|
||||
self.num_leds = num_leds
|
||||
self.pattern_step = 0
|
||||
|
||||
|
||||
def set_color(self, num, color):
|
||||
# Changed: More robust index check
|
||||
if 0 <= num < len(self.colors):
|
||||
self.colors[num] = color
|
||||
# If the changed color is part of the current or next transition,
|
||||
# restart the transition for smoother updates
|
||||
return True
|
||||
elif num == len(self.colors): # Allow setting a new color at the end
|
||||
self.colors.append(color)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def del_color(self, num):
|
||||
# Changed: More robust index check and using del for lists
|
||||
if 0 <= num < len(self.colors):
|
||||
del self.colors[num]
|
||||
return True
|
||||
return False
|
||||
|
||||
def apply_brightness(self, color, brightness_override=None):
|
||||
effective_brightness = brightness_override if brightness_override is not None else self.brightness
|
||||
return tuple(int(c * effective_brightness / 255) for c in color)
|
||||
|
||||
def fill(self, color=None):
|
||||
fill_color = color if color is not None else self.colors[0]
|
||||
for i in range(self.num_leds):
|
||||
self.n[i] = fill_color
|
||||
self.n.write()
|
||||
|
||||
def off(self):
|
||||
self.fill((0, 0, 0))
|
||||
|
||||
def on(self):
|
||||
self.fill(self.apply_brightness(self.colors[0]))
|
||||
|
||||
|
||||
|
||||
|
||||
def wheel(self, pos):
|
||||
if pos < 85:
|
||||
return (pos * 3, 255 - pos * 3, 0)
|
||||
elif pos < 170:
|
||||
pos -= 85
|
||||
return (255 - pos * 3, 0, pos * 3)
|
||||
else:
|
||||
pos -= 170
|
||||
return (0, pos * 3, 255 - pos * 3)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user