diff --git a/src/patterns.py b/src/patterns.py index 2e4bbec..219f0d4 100644 --- a/src/patterns.py +++ b/src/patterns.py @@ -26,15 +26,17 @@ class Patterns: self.patterns = { "off": self.off, "on" : self.on, - "color_wipe": self.color_wipe_step, - "rainbow_cycle": self.rainbow_cycle_step, - "theater_chase": self.theater_chase_step, - "blink": self.blink_step, - "color_transition": self.color_transition_step, # Added new pattern - "flicker": self.flicker_step, - "scanner": self.scanner_step, # New: Single direction scanner - "bidirectional_scanner": self.bidirectional_scanner_step, # New: Bidirectional scanner - "strip_cycle": self.strip_cycle_step, # New: Cycle through strips + "color_wipe": self.color_wipe, + "rainbow_cycle": self.rainbow_cycle, + "rainbow_spiral": self.rainbow_spiral, # Rainbow cycle per strip + "rainbow_strips": self.rainbow_strips, # New: Single color per strip, rainbow between strips + "theater_chase": self.theater_chase, + "blink": self.blink, + "color_transition": self.color_transition, # Added new pattern + "flicker": self.flicker, + "scanner": self.scanner, # New: Single direction scanner + "bidirectional_scanner": self.bidirectional_scanner, # New: Bidirectional scanner + "strip_cycle": self.strip_cycle, # New: Cycle through strips "external": None } self.selected = selected @@ -229,7 +231,7 @@ class Patterns: def on(self): self.fill(self.apply_brightness(self.colors[0])) - def color_wipe_step(self): + def color_wipe(self): color = self.apply_brightness(self.colors[0]) current_time = utime.ticks_ms() if utime.ticks_diff(current_time, self.last_update) >= self.delay: @@ -246,7 +248,7 @@ class Patterns: self.pattern_step = 0 self.last_update = current_time - def rainbow_cycle_step(self): + def rainbow_cycle(self): current_time = utime.ticks_ms() if utime.ticks_diff(current_time, self.last_update) >= self.delay/5: def wheel(pos): @@ -267,7 +269,7 @@ class Patterns: self.pattern_step = (self.pattern_step + 1) % 256 self.last_update = current_time - def theater_chase_step(self): + def theater_chase(self): current_time = utime.ticks_ms() if utime.ticks_diff(current_time, self.last_update) >= self.delay: total_leds = sum(len(strip) for strip in self.strips) @@ -280,7 +282,7 @@ class Patterns: self.pattern_step = (self.pattern_step + 1) % 3 self.last_update = current_time - def blink_step(self): + def blink(self): current_time = utime.ticks_ms() if utime.ticks_diff(current_time, self.last_update) >= self.delay: if self.pattern_step % 2 == 0: @@ -290,7 +292,7 @@ class Patterns: self.pattern_step = (self.pattern_step + 1) % 2 self.last_update = current_time - def color_transition_step(self): + def color_transition(self): current_time = utime.ticks_ms() # Check for hold duration first @@ -338,7 +340,7 @@ class Patterns: self.last_update = current_time - def flicker_step(self): + def flicker(self): current_time = utime.ticks_ms() if utime.ticks_diff(current_time, self.last_update) >= self.delay/5: base_color = self.colors[0] @@ -351,7 +353,7 @@ class Patterns: self.fill(flicker_color) self.last_update = current_time - def scanner_step(self): + def scanner(self): """ Mimics a 'Knight Rider' style scanner, moving in one direction. """ @@ -386,7 +388,7 @@ class Patterns: self.last_update = current_time - def bidirectional_scanner_step(self): + def bidirectional_scanner(self): """ Mimics a 'Knight Rider' style scanner, moving back and forth. """ @@ -426,7 +428,7 @@ class Patterns: self.last_update = current_time - def strip_cycle_step(self): + def strip_cycle(self): """ Cycles through each strip, turning them on and off one by one. """ @@ -450,3 +452,63 @@ class Patterns: self.pattern_step += 1 self.last_update = current_time + + def rainbow_spiral(self): + """ + Creates a rainbow effect that cycles through each strip individually. + Each strip shows its own rainbow pattern. + """ + current_time = utime.ticks_ms() + if utime.ticks_diff(current_time, self.last_update) >= self.delay/5: + def wheel(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) + + # Apply rainbow to each strip individually + for strip_idx, strip in enumerate(self.strips): + strip_length = len(strip) + for i in range(strip_length): + # Each strip gets its own rainbow cycle with offset based on strip index + rc_index = (i * 256 // strip_length) + self.pattern_step + (strip_idx * 32) + strip[i] = self.apply_brightness(wheel(rc_index & 255)) + + self.write() + self.pattern_step = (self.pattern_step + 1) % 256 + self.last_update = current_time + + def rainbow_strips(self): + """ + Each strip is a single color, rainbow effect is between strips. + Creates a rainbow pattern across the 8 strips. + """ + current_time = utime.ticks_ms() + if utime.ticks_diff(current_time, self.last_update) >= self.delay/5: + def wheel(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) + + # Each strip gets a single color from the rainbow + for strip_idx, strip in enumerate(self.strips): + # Calculate rainbow position for this strip + rainbow_pos = (strip_idx * 32 + self.pattern_step) % 256 + color = self.apply_brightness(wheel(rainbow_pos)) + + # Fill entire strip with this single color + for i in range(len(strip)): + strip[i] = color + + self.write() + self.pattern_step = (self.pattern_step + 1) % 256 + self.last_update = current_time