commit 089610f98ca515970bfeff3ba5aede07445a620f
Author: jimmy <git@jimmy.nz>
Date:   Thu May 2 21:05:54 2024 +1200

    Add initial patterns

diff --git a/patterns.py b/patterns.py
new file mode 100644
index 0000000..bc2c030
--- /dev/null
+++ b/patterns.py
@@ -0,0 +1,114 @@
+from machine import Pin
+from neopixel import NeoPixel
+import _thread
+import time, math
+import sys
+
+class LedPatterns:
+    def __init__(self, pin, num_leds):
+        self.num_leds = num_leds
+        self.np = NeoPixel(Pin(pin), num_leds)
+        self.run = True
+    
+    def color_chase(self, color, wait):
+        self.run = True
+        for i in range(self.num_leds):
+            self.np[i] = color
+            self.np.write()
+            if not run:
+                break
+            time.sleep(wait)
+    
+    def wheel(self, pos):
+        if pos < 0 or pos > 255:
+            return (0, 0, 0)
+        if pos < 85:
+            return (255 - pos * 3, pos * 3, 0)
+        if pos < 170:
+            pos -= 85
+            return (0, 255 - pos * 3, pos * 3)
+        pos -= 170
+        return (pos * 3, 0, 255 - pos * 3)
+    
+    def rainbow_cycle(self, wait):
+        run = True
+        for j in range(255):
+            for i in range(self.num_leds):
+                self.np[i] = self.wheel((i * 256 // self.num_leds) + j)
+            self.np.write()
+            if not run:
+                break
+            time.sleep(wait)
+    
+    def breathing(self, color, duration):
+        steps = 256
+        for _ in range(steps):
+            brightness = int(255 * abs(steps / 2 - _) / (steps / 2))
+            self.np.fill((brightness * color[0] // 255, brightness * color[1] // 255, brightness * color[2] // 255))
+            self.np.write()
+            time.sleep(duration / steps)
+    
+    def color_transition(self, start_color, end_color, duration):
+        steps = 256
+        for step in range(steps):
+            color = (
+                int(start_color[0] + (end_color[0] - start_color[0]) * step / steps),
+                int(start_color[1] + (end_color[1] - start_color[1]) * step / steps),
+                int(start_color[2] + (end_color[2] - start_color[2]) * step / steps),
+            )
+            self.np.fill(color)
+            self.np.write()
+            if not self.running():
+                return
+            time.sleep(duration / steps)
+            
+    def scanner(self, color, speed):
+        position = 0
+        direction = 1
+
+        while True:
+            self.np.fill((0, 0, 0))
+            self.np[position] = color
+            self.np.write()
+            time.sleep(speed)
+            position += direction
+            if position == self.num_leds - 1 or position == 0:
+                direction *= -1
+    
+    def bidirectional_scanner(self, color_left, color_right=None, speed=0.1):
+        color_right = color_right or color_left
+        position_left = 0
+        position_right = self.num_leds - 1
+        direction_left = 1
+        direction_right = -1
+        while True:
+            self.np.fill((0, 0, 0))
+            self.np[position_left] = color_left
+            self.np[position_right] = color_right
+            self.np.write()
+            time.sleep(speed)
+
+            position_left += direction_left
+            position_right += direction_right
+
+            if position_left == self.num_leds - 1 or position_left == 0:
+                direction_left *= -1
+            if position_right == self.num_leds - 1 or position_right == 0:
+                direction_right *= -1
+    
+    def sine_wave_propagation(self, color, speed):
+        frequency = 10
+        phase = 0
+        while True:
+            self.np.fill((0, 0, 0)) 
+            for i in range(self.num_leds):
+                brightness = int(127.5 * (math.sin(frequency * i + phase) + 1))
+                self.np[i] = (brightness * color[0] // 255, brightness * color[1] // 255, brightness * color[2] // 255)
+            self.np.write()
+            time.sleep(speed)
+            phase += 0.1
+
+    def fill(self,color):
+        for i in range(self.num_leds):
+            self.np[i] = color
+            self.np.write()