Add circle loading pattern
This commit is contained in:
@@ -23,6 +23,7 @@ class Patterns(PatternBase): # Inherit from PatternBase
|
|||||||
"o": self.off,
|
"o": self.off,
|
||||||
"on": self.on,
|
"on": self.on,
|
||||||
"bl": self.blink,
|
"bl": self.blink,
|
||||||
|
"cl": self.circle_loading,
|
||||||
}
|
}
|
||||||
self.step = 0
|
self.step = 0
|
||||||
self.run = True
|
self.run = True
|
||||||
@@ -64,6 +65,79 @@ class Patterns(PatternBase): # Inherit from PatternBase
|
|||||||
self.run = False
|
self.run = False
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
|
def circle_loading(self):
|
||||||
|
"""Circle loading pattern - grows to n2, then tail moves forward at n3 until min length n4"""
|
||||||
|
self.run = True
|
||||||
|
head = 0
|
||||||
|
tail = 0
|
||||||
|
|
||||||
|
# Calculate timing
|
||||||
|
head_rate = max(1, int(self.n1)) # n1 = head moves per second
|
||||||
|
tail_rate = max(1, int(self.n3)) # n3 = tail moves per second
|
||||||
|
max_length = max(1, int(self.n2)) # n2 = max length
|
||||||
|
min_length = max(0, int(self.n4)) # n4 = min length
|
||||||
|
|
||||||
|
head_delay = 1000 // head_rate # ms between head movements
|
||||||
|
tail_delay = 1000 // tail_rate # ms between tail movements
|
||||||
|
|
||||||
|
last_head_move = utime.ticks_ms()
|
||||||
|
last_tail_move = utime.ticks_ms()
|
||||||
|
|
||||||
|
phase = "growing" # "growing", "shrinking", or "off"
|
||||||
|
|
||||||
|
while self.run:
|
||||||
|
self.wdt.feed()
|
||||||
|
current_time = utime.ticks_ms()
|
||||||
|
|
||||||
|
# Clear all LEDs
|
||||||
|
self.n.fill((0, 0, 0))
|
||||||
|
|
||||||
|
# Calculate segment length
|
||||||
|
segment_length = (head - tail) % self.num_leds
|
||||||
|
if segment_length == 0 and head != tail:
|
||||||
|
segment_length = self.num_leds
|
||||||
|
|
||||||
|
# Draw segment from tail to head
|
||||||
|
color = self.apply_brightness(self.colors[0])
|
||||||
|
for i in range(segment_length + 1):
|
||||||
|
led_pos = (tail + i) % self.num_leds
|
||||||
|
self.n[led_pos] = color
|
||||||
|
|
||||||
|
# Move head continuously at n1 LEDs per second
|
||||||
|
if utime.ticks_diff(current_time, last_head_move) >= head_delay:
|
||||||
|
head = (head + 1) % self.num_leds
|
||||||
|
last_head_move = current_time
|
||||||
|
|
||||||
|
# Tail behavior based on phase
|
||||||
|
if phase == "growing":
|
||||||
|
# Growing phase: tail stays at 0 until max length reached
|
||||||
|
if segment_length >= max_length:
|
||||||
|
phase = "shrinking"
|
||||||
|
elif phase == "shrinking":
|
||||||
|
# Shrinking phase: move tail forward at n3 LEDs per second
|
||||||
|
if utime.ticks_diff(current_time, last_tail_move) >= tail_delay:
|
||||||
|
tail = (tail + 1) % self.num_leds
|
||||||
|
last_tail_move = current_time
|
||||||
|
|
||||||
|
# Check if we've reached min length
|
||||||
|
current_length = (head - tail) % self.num_leds
|
||||||
|
if current_length == 0 and head != tail:
|
||||||
|
current_length = self.num_leds
|
||||||
|
|
||||||
|
# For min_length = 0, we need at least 1 LED (the head)
|
||||||
|
if min_length == 0 and current_length <= 1:
|
||||||
|
phase = "off" # All LEDs off for 1 step
|
||||||
|
elif min_length > 0 and current_length <= min_length:
|
||||||
|
phase = "growing" # Cycle repeats
|
||||||
|
else: # phase == "off"
|
||||||
|
# Off phase: all LEDs off for 1 step, then restart
|
||||||
|
phase = "growing"
|
||||||
|
|
||||||
|
self.n.write()
|
||||||
|
|
||||||
|
self.run = False
|
||||||
|
self.running = False
|
||||||
|
|
||||||
# def flicker(self):
|
# def flicker(self):
|
||||||
# current_time = utime.ticks_ms()
|
# current_time = utime.ticks_ms()
|
||||||
# base_color = self.colors[0]
|
# base_color = self.colors[0]
|
||||||
|
|||||||
128
test/circle_loading.py
Normal file
128
test/circle_loading.py
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test script for circle loading pattern with multiple test cases
|
||||||
|
Run with: mpremote run test/circle_loading.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} head/sec, n2={p.n2} max length, n3={p.n3} tail/sec, n4={p.n4} min length")
|
||||||
|
print(f"Color: {p.colors[0]}")
|
||||||
|
print(f"Running for {duration_ms//1000} seconds...")
|
||||||
|
|
||||||
|
# Initialize watchdog timer
|
||||||
|
wdt = WDT(timeout=10000)
|
||||||
|
wdt.feed()
|
||||||
|
|
||||||
|
# Start pattern
|
||||||
|
p.select("cl")
|
||||||
|
|
||||||
|
# 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_circle_loading():
|
||||||
|
print("Testing circle loading 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=100,
|
||||||
|
delay=2000 # Base cycle time
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"LED Pin: {settings['led_pin']}")
|
||||||
|
print(f"LEDs: {settings['num_leds']}")
|
||||||
|
print(f"Brightness: {p.brightness}")
|
||||||
|
|
||||||
|
# Test Case 1: Your specified parameters
|
||||||
|
p.n1 = 50
|
||||||
|
p.n2 = 100
|
||||||
|
p.n3 = 200
|
||||||
|
p.n4 = 0
|
||||||
|
p.colors = [(255, 0, 0)] # Red
|
||||||
|
run_test_case(p, "Test 1: n1=50, n2=100, n3=200, n4=0", 15000)
|
||||||
|
|
||||||
|
# Test Case 2: Slow head, fast tail
|
||||||
|
p.n1 = 10 # Head moves 10 LEDs/second
|
||||||
|
p.n2 = 30 # Max length 30 LEDs
|
||||||
|
p.n3 = 20 # Tail moves 20 LEDs/second
|
||||||
|
p.n4 = 5 # Min length 5 LEDs
|
||||||
|
p.colors = [(0, 255, 0)] # Green
|
||||||
|
run_test_case(p, "Test 2: n1=10, n2=30, n3=20, n4=5", 10000)
|
||||||
|
|
||||||
|
# Test Case 3: Equal head and tail speed
|
||||||
|
p.n1 = 15 # Head moves 15 LEDs/second
|
||||||
|
p.n2 = 25 # Max length 25 LEDs
|
||||||
|
p.n3 = 15 # Tail moves 15 LEDs/second
|
||||||
|
p.n4 = 3 # Min length 3 LEDs
|
||||||
|
p.colors = [(0, 0, 255)] # Blue
|
||||||
|
run_test_case(p, "Test 3: n1=15, n2=25, n3=15, n4=3", 8000)
|
||||||
|
|
||||||
|
# Test Case 4: Very fast head, slow tail
|
||||||
|
p.n1 = 30 # Head moves 30 LEDs/second
|
||||||
|
p.n2 = 40 # Max length 40 LEDs
|
||||||
|
p.n3 = 5 # Tail moves 5 LEDs/second
|
||||||
|
p.n4 = 8 # Min length 8 LEDs
|
||||||
|
p.colors = [(255, 255, 0)] # Yellow
|
||||||
|
run_test_case(p, "Test 4: n1=30, n2=40, n3=5, n4=8", 12000)
|
||||||
|
|
||||||
|
# Test Case 5: Long segment, fast cycle
|
||||||
|
p.n1 = 25 # Head moves 25 LEDs/second
|
||||||
|
p.n2 = 60 # Max length 60 LEDs
|
||||||
|
p.n3 = 30 # Tail moves 30 LEDs/second
|
||||||
|
p.n4 = 2 # Min length 2 LEDs
|
||||||
|
p.colors = [(255, 0, 255)] # Magenta
|
||||||
|
run_test_case(p, "Test 5: n1=25, n2=60, n3=30, n4=2", 10000)
|
||||||
|
|
||||||
|
# Test Case 6: Very slow head, very fast tail
|
||||||
|
p.n1 = 5 # Head moves 5 LEDs/second
|
||||||
|
p.n2 = 20 # Max length 20 LEDs
|
||||||
|
p.n3 = 40 # Tail moves 40 LEDs/second
|
||||||
|
p.n4 = 1 # Min length 1 LED
|
||||||
|
p.colors = [(0, 255, 255)] # Cyan
|
||||||
|
run_test_case(p, "Test 6: n1=5, n2=20, n3=40, n4=1", 8000)
|
||||||
|
|
||||||
|
# Test Case 7: Medium speeds, short segment
|
||||||
|
p.n1 = 12 # Head moves 12 LEDs/second
|
||||||
|
p.n2 = 15 # Max length 15 LEDs
|
||||||
|
p.n3 = 18 # Tail moves 18 LEDs/second
|
||||||
|
p.n4 = 4 # Min length 4 LEDs
|
||||||
|
p.colors = [(255, 128, 0)] # Orange
|
||||||
|
run_test_case(p, "Test 7: n1=12, n2=15, n3=18, n4=4", 6000)
|
||||||
|
|
||||||
|
# Test Case 8: Ultra fast everything
|
||||||
|
p.n1 = 100 # Head moves 100 LEDs/second
|
||||||
|
p.n2 = 50 # Max length 50 LEDs
|
||||||
|
p.n3 = 150 # Tail moves 150 LEDs/second
|
||||||
|
p.n4 = 10 # Min length 10 LEDs
|
||||||
|
p.colors = [(128, 0, 255)] # Purple
|
||||||
|
run_test_case(p, "Test 8: n1=100, n2=50, n3=150, n4=10", 5000)
|
||||||
|
|
||||||
|
print("\n=== All tests completed ===")
|
||||||
|
|
||||||
|
# Turn off LEDs
|
||||||
|
p.off()
|
||||||
|
print("LEDs turned off")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_circle_loading()
|
||||||
Reference in New Issue
Block a user