From 748ad4b507edff090fcfecdf6f9cd388976d88d2 Mon Sep 17 00:00:00 2001 From: jimmy Date: Thu, 18 Sep 2025 20:35:21 +1200 Subject: [PATCH] Add n3 step rate functionality to patterns --- src/main.py | 46 +++++++++++++++++++++++++--------------------- src/patterns.py | 17 +++++++++++------ 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/main.py b/src/main.py index 5ef2f56..84a9d36 100644 --- a/src/main.py +++ b/src/main.py @@ -18,6 +18,10 @@ def main(): settings = Settings() print(settings) + if settings.get("color_order", "rgb") == "rbg": + color_order = (1, 5, 3) + else: + color_order = (1, 3, 5) patterns = Patterns(settings["led_pin"], settings["num_leds"], selected="off") sta_if = network.WLAN(network.STA_IF) @@ -42,28 +46,28 @@ def main(): last_msg = msg if last_msg: - try: - data = json.loads(last_msg) - defaults = data.get("d", {}) - bar = data.get(settings.get("name"), {}) + # try: + data = json.loads(last_msg) + defaults = data.get("d", {}) + bar = data.get(settings.get("name"), {}) - patterns.brightness = bar.get("brightness", defaults.get("brightness", patterns.brightness)) - patterns.delay = bar.get("delay", defaults.get("delay", patterns.delay)) - colors = bar.get("colors", defaults.get("colors", patterns.colors)) - patterns.colors = [tuple(int(color[i:i+2], 16) for i in settings.color_order) for color in colors] - patterns.n1 = bar.get("n1", defaults.get("n1", patterns.n1)) - patterns.n2 = bar.get("n2", defaults.get("n2", patterns.n2)) - patterns.step = bar.get("pattern_step", defaults.get("step", patterns.step)) - - selected_pattern = bar.get("pattern", defaults.get("pattern", "off")) - if selected_pattern in patterns.patterns: - # Run the selected pattern ONCE in response to this message. Do not auto-tick elsewhere. - patterns.patterns[selected_pattern]() - else: - print(f"Pattern {selected_pattern} not found") - except Exception as ex: - print(f"Failed to load espnow data {last_msg}: {ex}") - continue + patterns.brightness = bar.get("brightness", defaults.get("brightness", patterns.brightness)) + patterns.delay = bar.get("delay", defaults.get("delay", patterns.delay)) + patterns.colors = bar.get("colors", defaults.get("colors", patterns.colors)) + patterns.n1 = bar.get("n1", defaults.get("n1", patterns.n1)) + patterns.n2 = bar.get("n2", defaults.get("n2", patterns.n2)) + patterns.n3 = bar.get("n3", defaults.get("n3", patterns.n3)) + patterns.step = bar.get("pattern_step", defaults.get("step", patterns.step)) + + selected_pattern = bar.get("pattern", defaults.get("pattern", "off")) + if selected_pattern in patterns.patterns: + # Run the selected pattern ONCE in response to this message. Do not auto-tick elsewhere. + patterns.patterns[selected_pattern]() + else: + print(f"Pattern {selected_pattern} not found") + # except Exception as ex: + # print(f"Failed to load espnow data {last_msg}: {ex}") + # continue main() diff --git a/src/patterns.py b/src/patterns.py index 0129573..3d26a90 100644 --- a/src/patterns.py +++ b/src/patterns.py @@ -12,6 +12,7 @@ class Patterns(PatternBase): # Inherit from PatternBase self.off_width = 2 # Default off width (so total segment is 3, matching original behavior) self.n1 = 0 # Default start of fill range self.n2 = self.num_leds - 1 # Default end of fill range + self.n3 = 1 # Default step factor self.oneshot = False # New: One-shot flag for patterns like fill_range self.patterns = { "flicker": self.flicker, @@ -28,15 +29,17 @@ class Patterns(PatternBase): # Inherit from PatternBase def flicker(self): current_time = utime.ticks_ms() base_color = self.colors[0] - # Increase the range for flicker_brightness_offset - # Changed from self.brightness // 4 to self.brightness // 2 (or even self.brightness for max intensity) + # Use fixed minimum brightness of 10, flicker between 10 and full brightness + # Use n3 as step rate multiplier to control how fast patterns step + min_brightness = 10 + step_rate = max(1, int(self.n3)) flicker_brightness_offset = random.randint(-int(self.brightness // 1.5), int(self.brightness // 1.5)) - flicker_brightness = max(0, min(255, self.brightness + flicker_brightness_offset)) + flicker_brightness = max(min_brightness, min(255, self.brightness + flicker_brightness_offset)) flicker_color = self.apply_brightness(base_color, brightness_override=flicker_brightness) self.fill(flicker_color) self.last_update = current_time - return max(1, int(self.delay // 5)) + return max(1, int(self.delay // (5 * step_rate))) def fill_range(self): """ @@ -61,6 +64,7 @@ class Patterns(PatternBase): # Inherit from PatternBase 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)) @@ -74,7 +78,7 @@ class Patterns(PatternBase): # Inherit from PatternBase else: self.n[i] = (0, 0, 0) self.n.write() - self.pattern_step = (self.pattern_step + 1) % segment_length + self.pattern_step = (self.pattern_step + step_rate) % segment_length self.last_update = current_time return self.delay @@ -166,11 +170,12 @@ class Patterns(PatternBase): # Inherit from PatternBase pos -= 170 return (0, pos * 3, 255 - pos * 3) + step_rate = max(1, int(self.n3)) for i in range(self.num_leds): rc_index = (i * 256 // max(1, self.num_leds)) + self.pattern_step self.n[i] = self.apply_brightness(wheel(rc_index & 255)) self.n.write() - self.pattern_step = (self.pattern_step + 1) % 256 + self.pattern_step = (self.pattern_step + step_rate) % 256 return max(1, int(self.delay // 5)) def specto(self):