diff --git a/patterns.py b/patterns.py index ad36f08..edab766 100644 --- a/patterns.py +++ b/patterns.py @@ -117,8 +117,11 @@ class Patterns(PatternBase): # Inherit from PatternBase pos -= 170 return (0, pos * 3, 255 - pos * 3) + # Rainbow travels along the length - each LED position gets a different color for i in range(self.num_leds): - rc_index = (i * 256 // self.num_leds) + self.pattern_step + # Map LED position along strip to rainbow color + # Full 256 color range distributed along the strip length + rc_index = ((i * 256 // self.num_leds) + self.pattern_step) % 256 self.n[i] = self.apply_brightness(wheel(rc_index & 255)) self.n.write() self.pattern_step = (self.pattern_step + 1) % 256 diff --git a/src/patterns.py b/src/patterns.py index e43c476..7961391 100644 --- a/src/patterns.py +++ b/src/patterns.py @@ -209,13 +209,14 @@ class Patterns(PatternBase): # Inherit from PatternBase # Clear all LEDs self.n.fill((0, 0, 0)) - # Create rainbow effect with n1 nodes + # Rainbow travels along the length - distribute colors along the strip for i in range(self.num_leds): - # Calculate hue based on LED position, number of nodes, and time - hue_per_node = 360 // num_nodes - node_index = i * num_nodes // self.num_leds - base_hue = node_index * hue_per_node - hue = (base_hue + self.step) % 360 + # Calculate hue based on LED position along the strip + # Distribute full 360 degrees across the strip, repeat num_nodes times + # Position along the strip (0.0 to 1.0) + position = i / self.num_leds + # Hue cycles based on position and number of nodes + hue = int((position * 360 * num_nodes + self.step) % 360) # Convert HSV to RGB rgb = self.hsv_to_rgb(hue, 255, self.brightness) diff --git a/test/rainbow.py b/test/rainbow.py deleted file mode 100644 index 6ab8261..0000000 --- a/test/rainbow.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python3 -""" -Test script for rainbow pattern -Run with: mpremote run test/rainbow.py -""" - -import patterns -import utime -from settings import Settings -from machine import WDT - -def run_test_case(p, test_name, duration_ms=5000): - """Run a test case for specified duration""" - print(f"\n--- {test_name} ---") - print(f"Parameters: n1={p.n1} nodes, delay={p.delay}ms cycle time, brightness={p.brightness}") - print(f"Running for {duration_ms//1000} seconds...") - - # Initialize watchdog timer - wdt = WDT(timeout=10000) - wdt.feed() - - # Start pattern - p.select("rb") - - # Run for specified duration - start_time = utime.ticks_ms() - while utime.ticks_diff(utime.ticks_ms(), start_time) < duration_ms: - wdt.feed() - utime.sleep_ms(100) - - # Stop pattern - p.run = False - print(f"{test_name} completed") - - # Brief pause between tests - utime.sleep_ms(500) - -def test_rainbow(): - print("Testing rainbow pattern with multiple configurations...") - - # Load settings - settings = Settings() - - # Initialize patterns using settings - p = patterns.Patterns( - pin=settings["led_pin"], - num_leds=settings["num_leds"], - brightness=255, # Full brightness - delay=1000 # Base cycle time - ) - - print(f"LED Pin: {settings['led_pin']}") - print(f"LEDs: {settings['num_leds']}") - print(f"Base Brightness: {p.brightness}") - - # Test Case 1: Single node rainbow (full spectrum) - p.n1 = 1 # 1 node (full spectrum) - p.delay = 3000 # 3 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 1: Single node (full spectrum)", 12000) - - # Test Case 2: Two node rainbow (red/green) - p.n1 = 2 # 2 nodes - p.delay = 2000 # 2 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 2: Two nodes (red/green)", 10000) - - # Test Case 3: Three node rainbow (RGB) - p.n1 = 3 # 3 nodes - p.delay = 1500 # 1.5 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 3: Three nodes (RGB)", 9000) - - # Test Case 4: Four node rainbow (RYGB) - p.n1 = 4 # 4 nodes - p.delay = 1000 # 1 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 4: Four nodes (RYGB)", 8000) - - # Test Case 5: Six node rainbow (ROYGBP) - p.n1 = 6 # 6 nodes - p.delay = 800 # 0.8 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 5: Six nodes (ROYGBP)", 8000) - - # Test Case 6: Eight node rainbow - p.n1 = 8 # 8 nodes - p.delay = 600 # 0.6 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 6: Eight nodes", 6000) - - # Test Case 7: Twelve node rainbow (fine gradation) - p.n1 = 12 # 12 nodes - p.delay = 400 # 0.4 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 7: Twelve nodes (fine gradation)", 6000) - - # Test Case 8: Many nodes, slow cycle - p.n1 = 20 # 20 nodes - p.delay = 2000 # 2 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 8: Many nodes, slow cycle", 10000) - - # Test Case 9: One second cycle - p.n1 = 5 # 5 nodes - p.delay = 1000 # 1 second cycle - p.brightness = 255 # Full brightness - run_test_case(p, "Test 9: One second cycle (5 nodes)", 6000) - - print("\n=== All tests completed ===") - - # Turn off LEDs - p.off() - print("LEDs turned off") - -if __name__ == "__main__": - test_rainbow() diff --git a/test/rainbow/1.py b/test/rainbow/1.py new file mode 100644 index 0000000..3110bbd --- /dev/null +++ b/test/rainbow/1.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 1: Single node (full spectrum), 3 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/1.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 1: Single node (full spectrum), 3 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=3000 # 3 second cycle +) + +# Configure test parameters +p.n1 = 1 # 1 node (full spectrum) +p.delay = 3000 # 3 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/2.py b/test/rainbow/2.py new file mode 100644 index 0000000..6f52576 --- /dev/null +++ b/test/rainbow/2.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 2: Two nodes, 2 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/2.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 2: Two nodes, 2 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=2000 # 2 second cycle +) + +# Configure test parameters +p.n1 = 2 # 2 nodes +p.delay = 2000 # 2 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/3.py b/test/rainbow/3.py new file mode 100644 index 0000000..dea21bd --- /dev/null +++ b/test/rainbow/3.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 3: Three nodes (RGB), 1.5 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/3.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 3: Three nodes (RGB), 1.5 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=1500 # 1.5 second cycle +) + +# Configure test parameters +p.n1 = 3 # 3 nodes +p.delay = 1500 # 1.5 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/4.py b/test/rainbow/4.py new file mode 100644 index 0000000..70f7a2c --- /dev/null +++ b/test/rainbow/4.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 4: Four nodes (RYGB), 1 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/4.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 4: Four nodes (RYGB), 1 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=1000 # 1 second cycle +) + +# Configure test parameters +p.n1 = 4 # 4 nodes +p.delay = 1000 # 1 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/5.py b/test/rainbow/5.py new file mode 100644 index 0000000..d804d2f --- /dev/null +++ b/test/rainbow/5.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 5: Six nodes (ROYGBP), 0.8 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/5.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 5: Six nodes (ROYGBP), 0.8 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=800 # 0.8 second cycle +) + +# Configure test parameters +p.n1 = 6 # 6 nodes +p.delay = 800 # 0.8 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/6.py b/test/rainbow/6.py new file mode 100644 index 0000000..bc5ff83 --- /dev/null +++ b/test/rainbow/6.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 6: Eight nodes, 0.6 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/6.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 6: Eight nodes, 0.6 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=600 # 0.6 second cycle +) + +# Configure test parameters +p.n1 = 8 # 8 nodes +p.delay = 600 # 0.6 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/7.py b/test/rainbow/7.py new file mode 100644 index 0000000..9c3786d --- /dev/null +++ b/test/rainbow/7.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 7: Twelve nodes (fine gradation), 0.4 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/7.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 7: Twelve nodes (fine gradation), 0.4 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=400 # 0.4 second cycle +) + +# Configure test parameters +p.n1 = 12 # 12 nodes +p.delay = 400 # 0.4 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/8.py b/test/rainbow/8.py new file mode 100644 index 0000000..306852e --- /dev/null +++ b/test/rainbow/8.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 8: Many nodes (20), slow cycle (2 seconds), full brightness +Runs forever +Run with: mpremote run test/rainbow/8.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 8: Many nodes (20), slow cycle (2 seconds)") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=2000 # 2 second cycle +) + +# Configure test parameters +p.n1 = 20 # 20 nodes +p.delay = 2000 # 2 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/9.py b/test/rainbow/9.py new file mode 100644 index 0000000..ddab22c --- /dev/null +++ b/test/rainbow/9.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Rainbow test 9: Five nodes, 1 second cycle, full brightness +Runs forever +Run with: mpremote run test/rainbow/9.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +print("Starting Rainbow Test 9: Five nodes, 1 second cycle") +print("Press Ctrl+C to stop") + +# Load settings +settings = Settings() + +# Initialize patterns using settings +p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=1000 # 1 second cycle +) + +# Configure test parameters +p.n1 = 5 # 5 nodes +p.delay = 1000 # 1 second cycle +p.brightness = 255 # Full brightness + +print(f"LED Pin: {settings['led_pin']}") +print(f"LEDs: {settings['num_leds']}") +print(f"Brightness: {p.brightness}") +print(f"Delay: {p.delay}ms") +print(f"Nodes: {p.n1}") + +# Initialize watchdog timer +wdt = WDT(timeout=10000) +wdt.feed() + +# Start pattern +p.select("rb") +print("Pattern started. Running forever...") + +# Run forever +try: + while True: + wdt.feed() + utime.sleep_ms(100) +except KeyboardInterrupt: + print("\nStopping...") + p.run = False + p.off() + print("LEDs turned off") + diff --git a/test/rainbow/main.py b/test/rainbow/main.py new file mode 100644 index 0000000..e8bb8f5 --- /dev/null +++ b/test/rainbow/main.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +""" +Rainbow test suite - runs all tests in sequence forever +Run with: mpremote run test/rainbow/main.py +""" + +import patterns +import utime +from settings import Settings +from machine import WDT + +def run_test_case(p, test_name, n1, delay, brightness, duration_ms=6000): + """Run a test case for specified duration""" + print(f"\n--- {test_name} ---") + print(f"Parameters: n1={n1} nodes, delay={delay}ms cycle time, brightness={brightness}") + + # Configure parameters + p.n1 = n1 + p.delay = delay + p.brightness = brightness + + # Restart the pattern with new parameters + p.run = False + while p.running: + utime.sleep_ms(1) + + p.select("rb") + + # Run for specified duration + start_time = utime.ticks_ms() + while utime.ticks_diff(utime.ticks_ms(), start_time) < duration_ms: + wdt.feed() + utime.sleep_ms(100) + + # Stop pattern + p.run = False + print(f"{test_name} completed") + + # Brief pause between tests + utime.sleep_ms(500) + +def test_rainbow_suite(): + """Run all rainbow tests continuously""" + print("Starting rainbow test suite...") + print("Runs all tests in sequence, then repeats") + print("Press Ctrl+C to stop") + + # Load settings + settings = Settings() + + # Initialize patterns using settings + p = patterns.Patterns( + pin=settings["led_pin"], + num_leds=settings["num_leds"], + brightness=255, + delay=1000 + ) + + print(f"LED Pin: {settings['led_pin']}") + print(f"LEDs: {settings['num_leds']}") + print(f"Base Brightness: {p.brightness}") + + # Initialize watchdog timer + global wdt + wdt = WDT(timeout=10000) + wdt.feed() + + # Test configurations + tests = [ + ("Test 1: Single node (full spectrum)", 1, 3000, 255, 12000), + ("Test 2: Two nodes", 2, 2000, 255, 10000), + ("Test 3: Three nodes (RGB)", 3, 1500, 255, 9000), + ("Test 4: Four nodes (RYGB)", 4, 1000, 255, 8000), + ("Test 5: Six nodes (ROYGBP)", 6, 800, 255, 8000), + ("Test 6: Eight nodes", 8, 600, 255, 6000), + ("Test 7: Twelve nodes (fine gradation)", 12, 400, 255, 6000), + ("Test 8: Many nodes (20), slow cycle", 20, 2000, 255, 10000), + ("Test 9: Five nodes", 5, 1000, 255, 6000), + ] + + cycle = 0 + try: + while True: + cycle += 1 + print(f"\n\n========== Starting Cycle {cycle} ==========") + + for test_name, n1, delay, brightness, duration in tests: + run_test_case(p, test_name, n1, delay, brightness, duration) + + print("\n========== Cycle completed ==========\n") + + except KeyboardInterrupt: + print("\n\nStopping test suite...") + p.run = False + p.off() + print("LEDs turned off") + +if __name__ == "__main__": + test_rainbow_suite() +