From b7305e8652ea170fe7b0c685df1b0a4c334acb24 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Fri, 22 May 2020 13:00:46 -0400 Subject: [PATCH 1/3] Add examples, bugfixes. --- .../animation/rainbowchase.py | 15 ++---- .../animation/rainbowcomet.py | 1 - .../animation/rainbowsparkle.py | 3 +- adafruit_led_animation/helper.py | 38 +++++++------- adafruit_led_animation/sequence.py | 2 +- examples/led_animation_basic_animations.py | 50 +++++++++++++++++++ ..._gridmap.py => led_animation_pixel_map.py} | 11 ++-- examples/led_animation_rainbow_animations.py | 42 ++++++++++++++++ examples/led_animation_sequence.py | 10 ++-- examples/led_animation_sparkle_animations.py | 31 ++++++++++++ 10 files changed, 160 insertions(+), 43 deletions(-) create mode 100644 examples/led_animation_basic_animations.py rename examples/{led_animation_gridmap.py => led_animation_pixel_map.py} (78%) create mode 100644 examples/led_animation_rainbow_animations.py create mode 100644 examples/led_animation_sparkle_animations.py diff --git a/adafruit_led_animation/animation/rainbowchase.py b/adafruit_led_animation/animation/rainbowchase.py index 3024419..1b0c51f 100644 --- a/adafruit_led_animation/animation/rainbowchase.py +++ b/adafruit_led_animation/animation/rainbowchase.py @@ -58,22 +58,15 @@ class RainbowChase(Chase): :param size: Number of pixels to turn on in a row. :param spacing: Number of pixels to turn off in a row. :param reverse: Reverse direction of movement. - :param wheel_step: How many colors to skip in `colorwheel` per bar (default 8) + :param step: How many colors to skip in `colorwheel` per bar (default 8) """ # pylint: disable=too-many-arguments def __init__( - self, - pixel_object, - speed, - size=2, - spacing=3, - reverse=False, - name=None, - wheel_step=8, + self, pixel_object, speed, size=2, spacing=3, reverse=False, name=None, step=8, ): - self._num_colors = 256 // wheel_step - self._colors = [colorwheel(n % 256) for n in range(0, 512, wheel_step)] + self._num_colors = 256 // step + self._colors = [colorwheel(n % 256) for n in range(0, 512, step)] self._color_idx = 0 super().__init__(pixel_object, speed, 0, size, spacing, reverse, name) diff --git a/adafruit_led_animation/animation/rainbowcomet.py b/adafruit_led_animation/animation/rainbowcomet.py index beb667d..01c65cc 100644 --- a/adafruit_led_animation/animation/rainbowcomet.py +++ b/adafruit_led_animation/animation/rainbowcomet.py @@ -54,7 +54,6 @@ class RainbowComet(Comet): :param pixel_object: The initialised LED object. :param float speed: Animation speed in seconds, e.g. ``0.1``. - :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. :param int tail_length: The length of the comet. Defaults to 10. Cannot exceed the number of pixels present in the pixel object, e.g. if the strip is 30 pixels long, the ``tail_length`` cannot exceed 30 pixels. diff --git a/adafruit_led_animation/animation/rainbowsparkle.py b/adafruit_led_animation/animation/rainbowsparkle.py index 232fb90..e52cec0 100644 --- a/adafruit_led_animation/animation/rainbowsparkle.py +++ b/adafruit_led_animation/animation/rainbowsparkle.py @@ -73,6 +73,7 @@ def __init__( step=1, name=None, background_brightness=0.2, + precompute_rainbow=True, ): self._num_sparkles = num_sparkles if num_sparkles is None: @@ -86,7 +87,7 @@ def __init__( period=period, step=step, name=name, - precompute_rainbow=True, + precompute_rainbow=precompute_rainbow, ) def generate_rainbow(self): diff --git a/adafruit_led_animation/helper.py b/adafruit_led_animation/helper.py index bd3d3e7..b2bda99 100644 --- a/adafruit_led_animation/helper.py +++ b/adafruit_led_animation/helper.py @@ -186,14 +186,14 @@ def auto_write(self, value): self._pixels.auto_write = value @classmethod - def vertical_lines(cls, pixels, width, height, gridmapper): + def vertical_lines(cls, pixel_object, width, height, gridmap): """ Generate a PixelMap of horizontal lines on a strip arranged in a grid. - :param pixels: pixel object + :param pixel_object: pixel object :param width: width of grid :param height: height of grid - :param gridmapper: a function to map x and y coordinates to the grid + :param gridmap: a function to map x and y coordinates to the grid see vertical_strip_gridmap and horizontal_strip_gridmap :return: PixelMap @@ -205,22 +205,22 @@ def vertical_lines(cls, pixels, width, height, gridmapper): PixelMap.vertical_lines(pixels, 32, 8, vertical_strip_gridmap(8)) """ - if len(pixels) < width * height: + if len(pixel_object) < width * height: raise ValueError("number of pixels is less than width x height") mapping = [] for x in range(width): - mapping.append([gridmapper(x, y) for y in range(height)]) - return cls(pixels, mapping, individual_pixels=True) + mapping.append([gridmap(x, y) for y in range(height)]) + return cls(pixel_object, mapping, individual_pixels=True) @classmethod - def horizontal_lines(cls, pixels, width, height, gridmapper): + def horizontal_lines(cls, pixel_object, width, height, gridmap): """ Generate a PixelMap of horizontal lines on a strip arranged in a grid. - :param pixels: pixel object + :param pixel_object: pixel object :param width: width of grid :param height: height of grid - :param gridmapper: a function to map x and y coordinates to the grid + :param gridmap: a function to map x and y coordinates to the grid see vertical_strip_gridmap and horizontal_strip_gridmap :return: PixelMap @@ -231,20 +231,20 @@ def horizontal_lines(cls, pixels, width, height, gridmapper): PixelMap.horizontal_lines(pixels, 16, 16, vertical_strip_gridmap(16)) """ - if len(pixels) < width * height: + if len(pixel_object) < width * height: raise ValueError("number of pixels is less than width x height") mapping = [] for y in range(height): - mapping.append([gridmapper(x, y) for x in range(width)]) - return cls(pixels, mapping, individual_pixels=True) + mapping.append([gridmap(x, y) for x in range(width)]) + return cls(pixel_object, mapping, individual_pixels=True) def vertical_strip_gridmap(height, alternating=True): """ Returns a function that determines the pixel number for a grid with strips arranged vertically. - :param height: strip height in pixels - :param alternating: strips alternate directions in a zigzag + :param height: grid height in pixels + :param alternating: Whether or not the lines in the grid run alternate directions in a zigzag :return: mapper(x, y) """ @@ -260,8 +260,8 @@ def horizontal_strip_gridmap(width, alternating=True): """ Determines the pixel number for a grid with strips arranged horizontally. - :param width: strip width in pixels - :param alternating: strips alternate directions in a zigzag + :param width: grid width in pixels + :param alternating: Whether or not the lines in the grid run alternate directions in a zigzag :return: mapper(x, y) """ @@ -277,7 +277,7 @@ class PixelSubset: """ PixelSubset lets you work with a subset of a pixel object. - :param strip: An object that implements the Neopixel or Dotstar protocol. + :param pixel_object: An object that implements the Neopixel or Dotstar protocol. :param int start: Starting pixel number. :param int end: Ending pixel number. @@ -294,8 +294,8 @@ class PixelSubset: pixels.show() """ - def __init__(self, strip, start, end): - self._pixels = strip + def __init__(self, pixel_object, start, end): + self._pixels = pixel_object self._start = start self._end = end self.n = self._end - self._start diff --git a/adafruit_led_animation/sequence.py b/adafruit_led_animation/sequence.py index 5ee06d8..cb93c92 100644 --- a/adafruit_led_animation/sequence.py +++ b/adafruit_led_animation/sequence.py @@ -103,7 +103,7 @@ def __init__( name=None ): if advance_interval and advance_on_cycle_complete: - raise ValueError("Cannot use both advance_interval and auto_clear") + raise ValueError("Cannot use both advance_interval and advance_on_cycle_complete.") self._members = members self._advance_interval = ( advance_interval * NANOS_PER_SECOND if advance_interval else None diff --git a/examples/led_animation_basic_animations.py b/examples/led_animation_basic_animations.py new file mode 100644 index 0000000..e5089be --- /dev/null +++ b/examples/led_animation_basic_animations.py @@ -0,0 +1,50 @@ +""" +This example displays the basic animations in sequence, at a five second interval. + +For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using +a different form of NeoPixels. + +This example may not work on SAMD21 (M0) boards. +""" +import board +import neopixel + +from adafruit_led_animation.animation.solid import Solid +from adafruit_led_animation.animation.colorcycle import ColorCycle +from adafruit_led_animation.animation.blink import Blink +from adafruit_led_animation.animation.comet import Comet +from adafruit_led_animation.animation.chase import Chase +from adafruit_led_animation.animation.pulse import Pulse +from adafruit_led_animation.sequence import AnimationSequence +from adafruit_led_animation.color import ( + PURPLE, + WHITE, + AMBER, + JADE, + TEAL, + PINK, + MAGENTA, + ORANGE, +) + +# Update to match the pin connected to your NeoPixels +pixel_pin = board.D6 +# Update to match the number of NeoPixels you have connected +pixel_num = 32 + +pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) + +solid = Solid(pixels, color=PINK) +colorcycle = ColorCycle(pixels, speed=0.4, colors=[MAGENTA, ORANGE, TEAL]) +blink = Blink(pixels, speed=0.5, color=JADE) +comet = Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) +chase = Chase(pixels, speed=0.1, color=WHITE, size=3, spacing=6) +pulse = Pulse(pixels, speed=0.1, color=AMBER, period=3) + + +animations = AnimationSequence( + solid, comet, blink, chase, colorcycle, pulse, advance_interval=5, auto_clear=True, +) + +while True: + animations.animate() diff --git a/examples/led_animation_gridmap.py b/examples/led_animation_pixel_map.py similarity index 78% rename from examples/led_animation_gridmap.py rename to examples/led_animation_pixel_map.py index 0d1de28..b83e884 100644 --- a/examples/led_animation_gridmap.py +++ b/examples/led_animation_pixel_map.py @@ -1,9 +1,10 @@ """ -This example shows usage of the gridmap helper to easily treat a single strip as a horizontal or +This example shows usage of the PixelMap helper to easily treat a single strip as a horizontal or vertical grid for animation purposes. For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using -a different form of NeoPixels. +a different form of NeoPixels. Note that if you are using a number of pixels other than 32, you +will need to alter the PixelMap values as well for this example to work. This example does not work on SAMD21 (M0) boards. """ @@ -19,8 +20,12 @@ from adafruit_led_animation import helper from adafruit_led_animation.color import PURPLE, JADE, AMBER +# Update to match the pin connected to your NeoPixels +pixel_pin = board.D6 +# Update to match the number of NeoPixels you have connected +pixel_num = 32 -pixels = neopixel.NeoPixel(board.D6, 32, brightness=0.2, auto_write=False) +pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) pixel_wing_vertical = helper.PixelMap.vertical_lines( pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False) diff --git a/examples/led_animation_rainbow_animations.py b/examples/led_animation_rainbow_animations.py new file mode 100644 index 0000000..27e5441 --- /dev/null +++ b/examples/led_animation_rainbow_animations.py @@ -0,0 +1,42 @@ +""" +This example uses AnimationsSequence to display multiple animations in sequence, at a five second +interval. + +For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using +a different form of NeoPixels. + +This example does not work on SAMD21 (M0) boards. +""" +import board +import neopixel + +from adafruit_led_animation.animation.rainbow import Rainbow +from adafruit_led_animation.animation.rainbowchase import RainbowChase +from adafruit_led_animation.animation.rainbowcomet import RainbowComet +from adafruit_led_animation.animation.rainbowsparkle import RainbowSparkle +from adafruit_led_animation.sequence import AnimationSequence + +# Update to match the pin connected to your NeoPixels +pixel_pin = board.D6 +# Update to match the number of NeoPixels you have connected +pixel_num = 32 + +pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) + +rainbow = Rainbow(pixels, speed=0.1, period=2) +rainbow_chase = RainbowChase(pixels, speed=0.1, size=5, spacing=3) +rainbow_comet = RainbowComet(pixels, speed=0.1, tail_length=7, bounce=True) +rainbow_sparkle = RainbowSparkle(pixels, speed=0.1, num_sparkles=15) + + +animations = AnimationSequence( + rainbow, + rainbow_chase, + rainbow_comet, + rainbow_sparkle, + advance_interval=5, + auto_clear=True, +) + +while True: + animations.animate() diff --git a/examples/led_animation_sequence.py b/examples/led_animation_sequence.py index 8b2bb0d..bac4525 100644 --- a/examples/led_animation_sequence.py +++ b/examples/led_animation_sequence.py @@ -4,8 +4,6 @@ For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using a different form of NeoPixels. - -This example does not work on SAMD21 (M0) boards. """ import board import neopixel @@ -13,9 +11,8 @@ from adafruit_led_animation.animation.blink import Blink from adafruit_led_animation.animation.comet import Comet from adafruit_led_animation.animation.chase import Chase -from adafruit_led_animation.animation.pulse import Pulse from adafruit_led_animation.sequence import AnimationSequence -from adafruit_led_animation.color import PURPLE, WHITE, AMBER, JADE +from adafruit_led_animation.color import PURPLE, AMBER, JADE # Update to match the pin connected to your NeoPixels pixel_pin = board.D6 @@ -26,12 +23,11 @@ blink = Blink(pixels, speed=0.5, color=JADE) comet = Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) -chase = Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) -pulse = Pulse(pixels, speed=0.1, period=3, color=AMBER) +chase = Chase(pixels, speed=0.1, size=3, spacing=6, color=AMBER) animations = AnimationSequence( - comet, blink, chase, pulse, advance_interval=5, auto_clear=True, + comet, blink, chase, advance_interval=5, auto_clear=True, random_order=True, ) while True: diff --git a/examples/led_animation_sparkle_animations.py b/examples/led_animation_sparkle_animations.py new file mode 100644 index 0000000..f8c633f --- /dev/null +++ b/examples/led_animation_sparkle_animations.py @@ -0,0 +1,31 @@ +""" +This example uses AnimationsSequence to display multiple animations in sequence, at a five second +interval. + +For NeoPixel FeatherWing. Update pixel_pin and pixel_num to match your wiring if using +a different form of NeoPixels. +""" +import board +import neopixel + +from adafruit_led_animation.animation.sparkle import Sparkle +from adafruit_led_animation.animation.sparklepulse import SparklePulse +from adafruit_led_animation.sequence import AnimationSequence +from adafruit_led_animation.color import AMBER, JADE + +# Update to match the pin connected to your NeoPixels +pixel_pin = board.D6 +# Update to match the number of NeoPixels you have connected +pixel_num = 32 + +pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) + +sparkle = Sparkle(pixels, speed=0.05, color=AMBER, num_sparkles=10) +sparkle_pulse = SparklePulse(pixels, speed=0.05, period=3, color=JADE) + +animations = AnimationSequence( + sparkle, sparkle_pulse, advance_interval=5, auto_clear=True, +) + +while True: + animations.animate() From 14e7c24100ff0d7a4707b8f30d4de3bc9b09f7fd Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Fri, 22 May 2020 19:56:50 -0400 Subject: [PATCH 2/3] fix group to not crash --- adafruit_led_animation/animation/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_led_animation/animation/__init__.py b/adafruit_led_animation/animation/__init__.py index 6a52005..6327ead 100644 --- a/adafruit_led_animation/animation/__init__.py +++ b/adafruit_led_animation/animation/__init__.py @@ -146,7 +146,7 @@ def peers(self, peer_list): :param list peer_list: List of peer animations. """ if peer_list is not None: - self._peers = [self] + peer_list + self._peers = [self] + list(peer_list) def freeze(self): """ From 210fa1d7d1f4dd0f61e4833b27492c437cae92c3 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Fri, 22 May 2020 20:49:16 -0400 Subject: [PATCH 3/3] Finalise example updates and bugfixes. --- adafruit_led_animation/sequence.py | 4 +++- examples/led_animation_basic_animations.py | 6 +++--- examples/led_animation_pixel_map.py | 2 +- examples/led_animation_sequence.py | 6 ++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/adafruit_led_animation/sequence.py b/adafruit_led_animation/sequence.py index cb93c92..3532cde 100644 --- a/adafruit_led_animation/sequence.py +++ b/adafruit_led_animation/sequence.py @@ -103,7 +103,9 @@ def __init__( name=None ): if advance_interval and advance_on_cycle_complete: - raise ValueError("Cannot use both advance_interval and advance_on_cycle_complete.") + raise ValueError( + "Cannot use both advance_interval and advance_on_cycle_complete." + ) self._members = members self._advance_interval = ( advance_interval * NANOS_PER_SECOND if advance_interval else None diff --git a/examples/led_animation_basic_animations.py b/examples/led_animation_basic_animations.py index e5089be..551957f 100644 --- a/examples/led_animation_basic_animations.py +++ b/examples/led_animation_basic_animations.py @@ -35,15 +35,15 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) solid = Solid(pixels, color=PINK) -colorcycle = ColorCycle(pixels, speed=0.4, colors=[MAGENTA, ORANGE, TEAL]) blink = Blink(pixels, speed=0.5, color=JADE) -comet = Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) +colorcycle = ColorCycle(pixels, speed=0.4, colors=[MAGENTA, ORANGE, TEAL]) chase = Chase(pixels, speed=0.1, color=WHITE, size=3, spacing=6) +comet = Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) pulse = Pulse(pixels, speed=0.1, color=AMBER, period=3) animations = AnimationSequence( - solid, comet, blink, chase, colorcycle, pulse, advance_interval=5, auto_clear=True, + solid, blink, colorcycle, chase, comet, pulse, advance_interval=5, auto_clear=True, ) while True: diff --git a/examples/led_animation_pixel_map.py b/examples/led_animation_pixel_map.py index b83e884..6dd2a93 100644 --- a/examples/led_animation_pixel_map.py +++ b/examples/led_animation_pixel_map.py @@ -40,7 +40,7 @@ comet_v = Comet(pixel_wing_vertical, speed=0.1, color=AMBER, tail_length=6, bounce=True) chase_h = Chase(pixel_wing_horizontal, speed=0.1, size=3, spacing=6, color=JADE) rainbow_chase_v = RainbowChase( - pixel_wing_vertical, speed=0.1, size=3, spacing=2, wheel_step=8 + pixel_wing_vertical, speed=0.1, size=3, spacing=2, step=8 ) rainbow_comet_v = RainbowComet( pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True diff --git a/examples/led_animation_sequence.py b/examples/led_animation_sequence.py index bac4525..4f1bd3d 100644 --- a/examples/led_animation_sequence.py +++ b/examples/led_animation_sequence.py @@ -19,16 +19,14 @@ # Update to match the number of NeoPixels you have connected pixel_num = 32 -pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) +pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.1, auto_write=False) blink = Blink(pixels, speed=0.5, color=JADE) comet = Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) chase = Chase(pixels, speed=0.1, size=3, spacing=6, color=AMBER) -animations = AnimationSequence( - comet, blink, chase, advance_interval=5, auto_clear=True, random_order=True, -) +animations = AnimationSequence(blink, comet, chase, advance_interval=3, auto_clear=True) while True: animations.animate()