From 8902adf18c0e47051be87fcf54e9f82335214898 Mon Sep 17 00:00:00 2001 From: jimmy Date: Sat, 24 May 2025 13:09:28 +1200 Subject: [PATCH] Fix color transition --- src/patterns.py | 156 +++++++++++++++++++----------------------------- 1 file changed, 63 insertions(+), 93 deletions(-) diff --git a/src/patterns.py b/src/patterns.py index 66f7bc8..402e32d 100644 --- a/src/patterns.py +++ b/src/patterns.py @@ -28,9 +28,10 @@ class Patterns: self.selected = selected self.color1 = color1 self.color2 = color2 - self.transition_duration = 50 # Duration of color transition in milliseconds + self.transition_duration = delay * 10 # Default transition duration is 10 times the delay self.transition_step = 0 - + self.current_color = self.color1 + def sync(self): self.pattern_step=0 self.last_update = utime.ticks_ms() @@ -38,7 +39,7 @@ class Patterns: def tick(self): if self.patterns[self.selected]: self.patterns[self.selected]() - + def update_num_leds(self, pin, num_leds): self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds) self.num_leds = num_leds @@ -46,50 +47,61 @@ class Patterns: def set_delay(self, delay): self.delay = delay + # Update transition duration when delay changes for color_transition pattern + if self.selected == "color_transition": + self.transition_duration = self.delay * 10 # Or some other multiplier + def set_brightness(self, brightness): self.brightness = brightness - + def set_color1(self, color): - print(color) - self.color1 = self.apply_brightness(color) - + self.color1 = color + if self.selected == "color_transition": + self.transition_step = 0 + self.current_color = self.color1 + + def set_color2(self, color): - self.color2 = self.apply_brightness(color) - + self.color2 = color + if self.selected == "color_transition": + self.transition_step = 0 + self.current_color = self.color1 + + def apply_brightness(self, color): return tuple(int(c * self.brightness / 255) for c in color) - + def select(self, pattern): if pattern in self.patterns: self.selected = pattern + self.sync() # Reset pattern state when selecting a new pattern + if pattern == "color_transition": + self.transition_step = 0 + self.current_color = self.color1 + self.transition_duration = self.delay * 10 # Initialize transition duration return True return False - + def set(self, i, color): self.n[i] = color def write(self): self.n.write() - - def fill(self): + + def fill(self, color=None): + fill_color = color if color is not None else self.color1 for i in range(self.num_leds): - self.n[i] = self.color1 + self.n[i] = fill_color self.n.write() def off(self): - color = self.color1 - self.color1 = (0,0,0) - self.fill() - self.color1 = color - + self.fill((0, 0, 0)) + def on(self): - color = self.color1 - self.color1 = self.apply_brightness(self.color1) - self.fill() - self.color1 = color - - + self.fill(self.apply_brightness(self.color1)) + + def color_wipe_step(self): color = self.apply_brightness(self.color1) current_time = utime.ticks_ms() @@ -140,12 +152,9 @@ class Patterns: current_time = utime.ticks_ms() if utime.ticks_diff(current_time, self.last_update) >= self.delay: if self.pattern_step % 2 == 0: - for i in range(self.num_leds): - self.n[i] = self.apply_brightness(self.color1) + self.fill(self.apply_brightness(self.color1)) else: - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - self.n.write() + self.fill((0, 0, 0)) self.pattern_step = (self.pattern_step + 1) % 2 self.last_update = current_time @@ -199,80 +208,41 @@ class Patterns: def random_blink_step(self): current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: + if utime.ticks_diff(current_time, self.last_update) >= self.delay*10: color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) if self.pattern_step % 2 == 0: - for i in range(self.num_leds): - self.n[i] = self.apply_brightness(color) + self.fill(self.apply_brightness(color)) else: - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - self.n.write() + self.fill((0, 0, 0)) self.pattern_step = (self.pattern_step + 1) % 2 self.last_update = current_time + def interpolate_color(self, color_a, color_b, factor): + """Interpolates between two colors.""" + return tuple(int(a + (b - a) * factor) for a, b in zip(color_a, color_b)) + def color_transition_step(self): current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - # Calculate transition factor based on elapsed time - transition_factor = (self.pattern_step * 100) / self.transition_duration - if transition_factor > 100: - transition_factor = 100 - color = self.interpolate_color(self.color1, self.color2, transition_factor / 100) - - # Apply the interpolated color to all LEDs - for i in range(self.num_leds): - self.n[i] = self.apply_brightness(color) - self.n.write() - - self.pattern_step += self.delay - if self.pattern_step > self.transition_duration: - self.pattern_step = 0 - + # Use delay for how often to update the transition, not for the duration + if utime.ticks_diff(current_time, self.last_update) >= 1: # Update frequently for smooth transition + self.transition_step += utime.ticks_diff(current_time, self.last_update) self.last_update = current_time - def interpolate_color(self, color1, color2, factor): - return ( - int(color1[0] + (color2[0] - color1[0]) * factor), - int(color1[1] + (color2[1] - color1[1]) * factor), - int(color1[2] + (color2[2] - color1[2]) * factor) - ) - - def two_steps_forward_one_step_back_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - # Move forward 2 steps and backward 1 step - if self.direction == 1: # Moving forward - if self.scanner_position < self.num_leds - 2: - self.scanner_position += 2 # Move forward 2 steps - else: - self.direction = -1 # Change direction to backward - else: # Moving backward - if self.scanner_position > 0: - self.scanner_position -= 1 # Move backward 1 step - else: - self.direction = 1 # Change direction to forward - - # Set all LEDs to off - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - - # Set the current position to the color - self.n[self.scanner_position] = self.apply_brightness(self.color1) - - # Apply the color transition - transition_factor = (self.pattern_step * 100) / self.transition_duration - if transition_factor > 100: - transition_factor = 100 - color = self.interpolate_color(self.color1, self.color2, transition_factor / 100) - self.n[self.scanner_position] = self.apply_brightness(color) - - self.n.write() - self.pattern_step += self.delay - if self.pattern_step > self.transition_duration: - self.pattern_step = 0 + if self.transition_step >= self.transition_duration: + # Transition complete, swap colors and restart + self.color1, self.color2 = self.color2, self.color1 + self.transition_step = 0 + + # Calculate the interpolation factor (0 to 1) + factor = self.transition_step / self.transition_duration + + # Get the interpolated color and apply brightness + interpolated_color = self.interpolate_color(self.color1, self.color2, factor) + self.current_color = self.apply_brightness(interpolated_color) + + # Fill the LEDs with the current interpolated color + self.fill(self.current_color) - self.last_update = current_time if __name__ == "__main__": p = Patterns(4, 180)