diff --git a/colorschemes.py b/colorschemes.py index 2025537..b74fd8e 100644 --- a/colorschemes.py +++ b/colorschemes.py @@ -1,6 +1,7 @@ """This module contains a few concrete colour cycles to play with""" from math import ceil +from random import randint from colorcycletemplate import ColorCycleTemplate from apa102 import Pixel @@ -141,3 +142,49 @@ def update(strip, num_led, num_steps_per_cycle, current_step, return 1 # Repaint return update + +def create_fire(start, end): + """Return a fire updater.""" + + def update(strip, num_led, num_steps_per_cycle, current_step, + current_cycle): + r, g, b = 255, 96, 12 + for i in range(start, end+1): + flicker = randint(0, 40) + strip[i] = Pixel(r-flicker, g-flicker, b-flicker, 100) + return 1 # Repaint + return update + +def create_red_alert(start, end): + """Return a rising red updater.""" + + def update(strip, num_led, num_steps_per_cycle, current_step, + current_cycle): + brightness = round(100 * current_step / num_steps_per_cycle) + lamp = Pixel(255, 0, 0, brightness) + for i in range(start, end+1): + strip[i] = lamp + return 1 # Repaint + return update + +def create_swipe(start, end): + """Return an updater that will shift all effects in, one pixel per cycle. Add + this updater after other effects. + Params: + start, end - Inclusive ranges. Will swipe right to left if start > end. + """ + + def update(strip, num_led, num_steps_per_cycle, current_step, + current_cycle): + shift_max = abs(end-start) + shift = shift_max-current_step + if shift <= 0: + return 0 + if start < end: + for i in range(start, end+1): + strip[i] = strip[i+shift] if i+shift <= end else Pixel.BLACK + else: + for i in range(start, end-1, -1): + strip[i] = strip[i-shift] if i-shift >= end else Pixel.BLACK + return 1 # Repaint + return update diff --git a/runcolorcycle.py b/runcolorcycle.py index 304bdf2..678e9ee 100755 --- a/runcolorcycle.py +++ b/runcolorcycle.py @@ -41,8 +41,11 @@ # One slow trip through the rainbow print('One slow trip through the rainbow') - MY_CYCLE = colorschemes.Rainbow(num_steps_per_cycle=255, num_cycles=1, - **options) + MY_CYCLE = ColorCycleTemplate(num_steps_per_cycle=255, num_cycles=1, + **options) + rainbow = colorschemes.Rainbow(**options) + MY_CYCLE.append_updater(rainbow.update) + MY_CYCLE.append_updater(colorschemes.create_swipe(args.num_led-1, 0)) MY_CYCLE.start() # Five quick trips through the rainbow @@ -51,12 +54,17 @@ **options) MY_CYCLE.start() - print('Two Larson Scanners') - MY_CYCLE = ColorCycleTemplate(pause_value=0.02, num_steps_per_cycle=300, num_cycles=1, + print('A Larson Scanner, a fire, and red alert') + MY_CYCLE = ColorCycleTemplate(pause_value=0.02, num_steps_per_cycle=60, num_cycles=5, **options) MY_CYCLE.append_updater(colorschemes.blank_updater) # The scanners don't assume blank-to-start - MY_CYCLE.append_updater(colorschemes.create_larson(0, args.num_led // 2 - 1, width=8)) - MY_CYCLE.append_updater(colorschemes.create_larson(args.num_led // 2, args.num_led - 1, width=8)) + num_updaters = 3 + sec_width = args.num_led // num_updaters + sec_ranges = list(zip(range(0, args.num_led, sec_width), range(sec_width-1, args.num_led, sec_width))) + sec_ranges[-1] = (sec_ranges[-1][0], args.num_led-1) # Make sure we get them all + MY_CYCLE.append_updater(colorschemes.create_larson(*sec_ranges.pop(0), width=8)) + MY_CYCLE.append_updater(colorschemes.create_fire(*sec_ranges.pop(0))) + MY_CYCLE.append_updater(colorschemes.create_red_alert(*sec_ranges.pop(0))) MY_CYCLE.start() print('Finished the test')