feat: add pulse pattern
Configurable attack/hold/decay phases via n1/n2/n3. Single-shot when delay=0.
This commit is contained in:
@@ -1,36 +1,131 @@
|
||||
#!/usr/bin/env python3
|
||||
import uasyncio as asyncio
|
||||
import utime
|
||||
from machine import WDT
|
||||
from settings import Settings
|
||||
from patterns import Patterns
|
||||
|
||||
|
||||
def run():
|
||||
async def main():
|
||||
s = Settings()
|
||||
pin = s.get("led_pin", 10)
|
||||
num = s.get("num_leds", 30)
|
||||
|
||||
p = Patterns(pin=pin, num_leds=num)
|
||||
wdt = WDT(timeout=10000)
|
||||
|
||||
# Test 1: Basic pulse with attack, hold, and decay
|
||||
print("Test 1: Basic pulse pattern")
|
||||
p.set_param("br", 255)
|
||||
p.set_param("dl", 100)
|
||||
p.set_param("dl", 1000) # 1 second delay between pulses
|
||||
p.set_param("cl", [(255, 255, 255), (255, 255, 255)])
|
||||
p.set_param("n1", 200)
|
||||
p.set_param("n2", 200)
|
||||
p.set_param("pt", "pulse")
|
||||
|
||||
p.set_param("n1", 200) # Attack: 200ms
|
||||
p.set_param("n2", 200) # Hold: 200ms
|
||||
p.set_param("n3", 200) # Decay: 200ms
|
||||
p.select("pulse")
|
||||
task = asyncio.create_task(p.run())
|
||||
start = utime.ticks_ms()
|
||||
while utime.ticks_diff(utime.ticks_ms(), start) < 1500:
|
||||
p.tick()
|
||||
# Run for 3 seconds to see multiple pulse cycles
|
||||
while utime.ticks_diff(utime.ticks_ms(), start) < 3000:
|
||||
wdt.feed()
|
||||
utime.sleep_ms(10)
|
||||
|
||||
p.set_param("pt", "off")
|
||||
p.tick()
|
||||
utime.sleep_ms(100)
|
||||
await asyncio.sleep_ms(10)
|
||||
p.stopped = True
|
||||
await task
|
||||
|
||||
# Test 2: Fast pulse with shorter delay
|
||||
print("Test 2: Fast pulse pattern")
|
||||
p.stopped = False
|
||||
p.set_param("dl", 500) # 500ms delay between pulses
|
||||
p.set_param("n1", 100) # Attack: 100ms
|
||||
p.set_param("n2", 100) # Hold: 100ms
|
||||
p.set_param("n3", 100) # Decay: 100ms
|
||||
p.select("pulse")
|
||||
task = asyncio.create_task(p.run())
|
||||
start = utime.ticks_ms()
|
||||
# Run for 2 seconds
|
||||
while utime.ticks_diff(utime.ticks_ms(), start) < 2000:
|
||||
wdt.feed()
|
||||
await asyncio.sleep_ms(10)
|
||||
p.stopped = True
|
||||
await task
|
||||
|
||||
# Test 3: Colored pulse
|
||||
print("Test 3: Colored pulse pattern")
|
||||
p.stopped = False
|
||||
p.set_param("dl", 800)
|
||||
p.set_param("cl", [(255, 0, 0), (0, 0, 255)]) # Red pulse
|
||||
p.set_param("n1", 150)
|
||||
p.set_param("n2", 150)
|
||||
p.set_param("n3", 150)
|
||||
p.select("pulse")
|
||||
task = asyncio.create_task(p.run())
|
||||
start = utime.ticks_ms()
|
||||
# Run for 2 seconds
|
||||
while utime.ticks_diff(utime.ticks_ms(), start) < 2000:
|
||||
wdt.feed()
|
||||
await asyncio.sleep_ms(10)
|
||||
p.stopped = True
|
||||
await task
|
||||
|
||||
# Test 4: Verify delay restart timing
|
||||
print("Test 4: Testing delay restart timing")
|
||||
p.stopped = False
|
||||
p.set_param("dl", 500) # 500ms delay
|
||||
p.set_param("n1", 100) # Total attack+hold+decay = 300ms, should wait 200ms more
|
||||
p.set_param("n2", 100)
|
||||
p.set_param("n3", 100)
|
||||
p.select("pulse")
|
||||
task = asyncio.create_task(p.run())
|
||||
|
||||
# Monitor pulse cycles
|
||||
cycle_count = 0
|
||||
last_cycle_time = utime.ticks_ms()
|
||||
start = utime.ticks_ms()
|
||||
while utime.ticks_diff(utime.ticks_ms(), start) < 3000:
|
||||
wdt.feed()
|
||||
await asyncio.sleep_ms(10)
|
||||
# Check if we're near the start of a new cycle (LEDs off)
|
||||
# This is a simplified check - in practice you'd monitor LED state
|
||||
p.stopped = True
|
||||
await task
|
||||
|
||||
# Test 5: Single-shot pulse (delay=0)
|
||||
print("Test 5: Single-shot pulse (delay=0)")
|
||||
p.stopped = False
|
||||
p.set_param("dl", 0) # No delay - should run only once
|
||||
p.set_param("cl", [(0, 255, 0), (0, 255, 0)]) # Green pulse
|
||||
p.set_param("n1", 150) # Attack: 150ms
|
||||
p.set_param("n2", 150) # Hold: 150ms
|
||||
p.set_param("n3", 150) # Decay: 150ms
|
||||
p.select("pulse")
|
||||
task = asyncio.create_task(p.run())
|
||||
|
||||
# The pulse should complete once and then stop
|
||||
# Total time should be ~450ms (attack + hold + decay)
|
||||
# Wait a bit longer to verify it doesn't repeat
|
||||
start = utime.ticks_ms()
|
||||
while utime.ticks_diff(utime.ticks_ms(), start) < 1000:
|
||||
wdt.feed()
|
||||
await asyncio.sleep_ms(10)
|
||||
|
||||
# Task should have completed on its own (not stopped manually)
|
||||
# Verify it's stopped
|
||||
if not p.stopped:
|
||||
print("Warning: Pulse should have stopped automatically with delay=0")
|
||||
p.stopped = True
|
||||
await task
|
||||
|
||||
# Cleanup
|
||||
print("Test complete, turning off")
|
||||
p.stopped = False
|
||||
p.select("off")
|
||||
task = asyncio.create_task(p.run())
|
||||
await asyncio.sleep_ms(100)
|
||||
p.stopped = True
|
||||
await task
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
asyncio.run(main())
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user