From 79ae49e0a042f3cf3c693c8e7d24c09352210e76 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 16 May 2020 13:58:49 -0400 Subject: [PATCH 1/6] Make colorwheel fast in older builds of circuitpython --- adafruit_led_animation/color.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adafruit_led_animation/color.py b/adafruit_led_animation/color.py index 0cdb0d2..28203ee 100644 --- a/adafruit_led_animation/color.py +++ b/adafruit_led_animation/color.py @@ -45,7 +45,11 @@ try: - from _pixelbuf import colorwheel # pylint: disable=unused-import + # Backwards compat for 5.3.0 and prior + try: + from _pixelbuf import colorwheel # pylint: disable=unused-import + except ImportError: + from _pixelbuf import wheel as colorwheel # pylint: disable=unused-import except ImportError: # Ensure we have a wheel if not built in def colorwheel(pos): From cdd61d6be13310ab4a2c3d2a027343234642137d Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 16 May 2020 14:11:17 -0400 Subject: [PATCH 2/6] split library up further to help with low memory boards --- adafruit_led_animation/animation.py | 504 ------------------ adafruit_led_animation/animation/__init__.py | 201 +++++++ adafruit_led_animation/animation/blink.py | 50 ++ adafruit_led_animation/animation/chase.py | 132 +++++ .../animation/colorcycle.py | 73 +++ adafruit_led_animation/animation/comet.py | 132 +++++ adafruit_led_animation/animation/pulse.py | 71 +++ .../{ => animation}/rainbow.py | 97 +--- .../animation/rainbowchase.py | 71 +++ .../animation/rainbowcomet.py | 87 +++ adafruit_led_animation/animation/solid.py | 48 ++ adafruit_led_animation/animation/sparkle.py | 95 ++++ .../{sparkle.py => animation/sparklepulse.py} | 71 +-- adafruit_led_animation/color.py | 2 +- examples/led_animation_all_animations.py | 18 +- examples/led_animation_gridmap.py | 10 +- 16 files changed, 985 insertions(+), 677 deletions(-) delete mode 100644 adafruit_led_animation/animation.py create mode 100644 adafruit_led_animation/animation/__init__.py create mode 100644 adafruit_led_animation/animation/blink.py create mode 100644 adafruit_led_animation/animation/chase.py create mode 100644 adafruit_led_animation/animation/colorcycle.py create mode 100644 adafruit_led_animation/animation/comet.py create mode 100644 adafruit_led_animation/animation/pulse.py rename adafruit_led_animation/{ => animation}/rainbow.py (50%) create mode 100644 adafruit_led_animation/animation/rainbowchase.py create mode 100644 adafruit_led_animation/animation/rainbowcomet.py create mode 100644 adafruit_led_animation/animation/solid.py create mode 100644 adafruit_led_animation/animation/sparkle.py rename adafruit_led_animation/{sparkle.py => animation/sparklepulse.py} (62%) diff --git a/adafruit_led_animation/animation.py b/adafruit_led_animation/animation.py deleted file mode 100644 index 51a7e9d..0000000 --- a/adafruit_led_animation/animation.py +++ /dev/null @@ -1,504 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2019-2020 Roy Hooper -# Copyright (c) 2020 Kattni Rembor for Adafruit Industries -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -""" -`adafruit_led_animation.animation` -================================================================================ - -Animation base class, and basic animations for CircuitPython helper library for LED animations. - -* Author(s): Roy Hooper, Kattni Rembor - -Implementation Notes --------------------- - -**Hardware:** - -* `Adafruit NeoPixels `_ -* `Adafruit DotStars `_ - -**Software and Dependencies:** - -* Adafruit CircuitPython firmware for the supported boards: - https://circuitpython.org/downloads - -""" - -from math import ceil -from . import NANOS_PER_SECOND, monotonic_ns -from .color import BLACK, RAINBOW - -__version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" - - -class Animation: - # pylint: disable=too-many-instance-attributes - """ - Base class for animations. - """ - cycle_complete_supported = False - - # pylint: disable=too-many-arguments - def __init__(self, pixel_object, speed, color, peers=None, paused=False, name=None): - self.pixel_object = pixel_object - self.pixel_object.auto_write = False - self.peers = peers if peers else [] - """A sequence of animations to trigger .draw() on when this animation draws.""" - self._speed_ns = 0 - self._color = None - self._paused = paused - self._next_update = monotonic_ns() - self._time_left_at_pause = 0 - self._also_notify = [] - self.speed = speed # sets _speed_ns - self.color = color # Triggers _recompute_color - self.name = name - self.notify_cycles = 1 - """Number of cycles to trigger additional cycle_done notifications after""" - self.draw_count = 0 - """Number of animation frames drawn.""" - self.cycle_count = 0 - """Number of animation cycles completed.""" - - def __str__(self): - return "<%s: %s>" % (self.__class__.__name__, self.name) - - def animate(self): - """ - Call animate() from your code's main loop. It will draw the animation draw() at intervals - configured by the speed property (set from init). - - :return: True if the animation draw cycle was triggered, otherwise False. - """ - if self._paused: - return False - - now = monotonic_ns() - if now < self._next_update: - return False - - self.draw() - self.draw_count += 1 - - # Draw related animations together - if self.peers: - for peer in self.peers: - peer.draw() - - self._next_update = now + self._speed_ns - return True - - def draw(self): - """ - Animation subclasses must implement draw() to render the animation sequence. - Draw must call show(). - """ - raise NotImplementedError() - - def show(self): - """ - Displays the updated pixels. Called during animates with changes. - """ - self.pixel_object.show() - - def freeze(self): - """ - Stops the animation until resumed. - """ - self._paused = True - self._time_left_at_pause = max(0, monotonic_ns() - self._next_update) - - def resume(self): - """ - Resumes the animation. - """ - self._next_update = monotonic_ns() + self._time_left_at_pause - self._time_left_at_pause = 0 - self._paused = False - - def fill(self, color): - """ - Fills the pixel object with a color. - """ - self.pixel_object.fill(color) - - @property - def color(self): - """ - The current color. - """ - return self._color - - @color.setter - def color(self, color): - if self._color == color: - return - if isinstance(color, int): - color = (color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF) - self._color = color - self._recompute_color(color) - - @property - def speed(self): - """ - The animation speed in fractional seconds. - """ - return self._speed_ns / NANOS_PER_SECOND - - @speed.setter - def speed(self, seconds): - self._speed_ns = int(seconds * NANOS_PER_SECOND) - - def _recompute_color(self, color): - """ - Called if the color is changed, which includes at initialization. - Override as needed. - """ - - def cycle_complete(self): - """ - Called by some animations when they complete an animation cycle. - Animations that support cycle complete notifications will have X property set to False. - Override as needed. - """ - self.cycle_count += 1 - if self.cycle_count % self.notify_cycles == 0: - for callback in self._also_notify: - callback(self) - - def add_cycle_complete_receiver(self, callback): - """ - Adds an additional callback when the cycle completes. - - :param callback: Additional callback to trigger when a cycle completes. The callback - is passed the animation object instance. - """ - self._also_notify.append(callback) - - def reset(self): - """ - Resets the animation sequence. - """ - - -class ColorCycle(Animation): - """ - Animate a sequence of one or more colors, cycling at the specified speed. - - :param pixel_object: The initialised LED object. - :param float speed: Animation speed in seconds, e.g. ``0.1``. - :param colors: A list of colors to cycle through in ``(r, g, b)`` tuple, or ``0x000000`` hex - format. Defaults to a rainbow color cycle. - """ - - def __init__(self, pixel_object, speed, colors=RAINBOW, name=None): - self.colors = colors - super().__init__(pixel_object, speed, colors[0], name=name) - self._generator = self._color_generator() - next(self._generator) - - cycle_complete_supported = True - - def draw(self): - self.pixel_object.fill(self.color) - self.show() - next(self._generator) - - def _color_generator(self): - index = 0 - while True: - self._color = self.colors[index] - yield - index = (index + 1) % len(self.colors) - if index == 0: - self.cycle_complete() - - def reset(self): - """ - Resets to the first color. - """ - self._generator = self._color_generator() - - -class Blink(ColorCycle): - """ - Blink a color on and off. - - :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. - """ - - def __init__(self, pixel_object, speed, color, name=None): - super().__init__(pixel_object, speed, [color, BLACK], name=name) - - def _recompute_color(self, color): - self.colors = [color, BLACK] - - -class Solid(ColorCycle): - """ - A solid color. - - :param pixel_object: The initialised LED object. - :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. - """ - - def __init__(self, pixel_object, color, name=None): - super().__init__(pixel_object, speed=1, colors=[color], name=name) - - def _recompute_color(self, color): - self.colors = [color] - - -class Comet(Animation): - """ - A comet animation. - - :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. - :param bool reverse: Animates the comet in the reverse order. Defaults to ``False``. - :param bool bounce: Comet will bounce back and forth. Defaults to ``True``. - """ - - # pylint: disable=too-many-arguments - def __init__( - self, - pixel_object, - speed, - color, - tail_length=10, - reverse=False, - bounce=False, - name=None, - ): - self._tail_length = tail_length + 1 - self._color_step = 0.9 / tail_length - self._color_offset = 0.1 - self._comet_colors = None - self._reverse_comet_colors = None - self._initial_reverse = reverse - self.reverse = reverse - self.bounce = bounce - self._computed_color = color - self._generator = self._comet_generator() - super().__init__(pixel_object, speed, color, name=name) - - cycle_complete_supported = True - - def _recompute_color(self, color): - pass - - def __recompute_color(self, color): - self._comet_colors = [BLACK] + [ - [ - int(color[rgb] * ((n * self._color_step) + self._color_offset)) - for rgb in range(len(color)) - ] - for n in range(self._tail_length - 1) - ] - self._reverse_comet_colors = list(reversed(self._comet_colors)) - self._computed_color = color - - def _get_range(self, num_pixels): - if self.reverse: - return range(num_pixels, -self._tail_length - 1, -1) - return range(-self._tail_length, num_pixels + 1) - - def _comet_generator(self): - num_pixels = len(self.pixel_object) - cycle_passes = 0 - while True: - if self._color != self._computed_color or not self._comet_colors: - self.__recompute_color(self._color) - colors = self._reverse_comet_colors if self.reverse else self._comet_colors - for start in self._get_range(num_pixels): - - if start + self._tail_length < num_pixels: - end = self._tail_length - else: - end = num_pixels - start - if start <= 0: - num_visible = self._tail_length + start - self.pixel_object[0:num_visible] = colors[ - self._tail_length - num_visible : - ] - else: - self.pixel_object[start : start + end] = colors[0:end] - self.show() - yield - cycle_passes += 1 - if self.bounce: - self.reverse = not self.reverse - if not self.bounce or cycle_passes == 2: - self.cycle_complete() - cycle_passes = 0 - - def draw(self): - next(self._generator) - - def reset(self): - """ - Resets to the first color. - """ - self._generator = self._comet_generator() - self.reverse = self._initial_reverse - - -class Pulse(Animation): - """ - Pulse all pixels a single color. - - :param pixel_object: The initialised LED object. - :param float speed: Animation refresh rate in seconds, e.g. ``0.1``. - :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. - :param period: Period to pulse the LEDs over. Default 5. - """ - - # pylint: disable=too-many-arguments - def __init__(self, pixel_object, speed, color, period=5, name=None): - super().__init__(pixel_object, speed, color, name=name) - self._period = period - self._generator = None - self.reset() - - cycle_complete_supported = True - - def draw(self): - color = next(self._generator) - self.fill(color) - self.show() - - def reset(self): - """ - Resets the animation. - """ - white = len(self.pixel_object[0]) > 3 and isinstance( - self.pixel_object[0][-1], int - ) - from adafruit_led_animation.helper import ( # pylint: disable=import-outside-toplevel - pulse_generator, - ) - - self._generator = pulse_generator(self._period, self, white) - - -class Chase(Animation): - """ - Chase pixels in one direction in a single color, like a theater marquee sign. - - :param pixel_object: The initialised LED object. - :param float speed: Animation speed rate in seconds, e.g. ``0.1``. - :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. - :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. - """ - - # pylint: disable=too-many-arguments - def __init__( - self, pixel_object, speed, color, size=2, spacing=3, reverse=False, name=None - ): - self._size = size - self._spacing = spacing - self._repeat_width = size + spacing - self._num_repeats = ceil(len(pixel_object) / self._repeat_width) - self._overflow = len(pixel_object) % self._repeat_width - self._direction = 1 if not reverse else -1 - self._reverse = reverse - self._offset = 0 - - def _resetter(): - self._offset = 0 - self._reverse = reverse - self._direction = 1 if not reverse else -1 - - self._reset = _resetter - - super().__init__(pixel_object, speed, color, name=name) - - cycle_complete_supported = True - - @property - def reverse(self): - """ - Whether the animation is reversed - """ - return self._reverse - - @reverse.setter - def reverse(self, value): - self._reverse = value - self._direction = -1 if self._reverse else 1 - - def draw(self): - def bar_colors(): - bar_no = 0 - for i in range(self._offset, 0, -1): - if i > self._spacing: - yield self.bar_color(bar_no, i) - else: - yield self.space_color(bar_no, i) - bar_no = 1 - while True: - for bar_pixel in range(self._size): - yield self.bar_color(bar_no, bar_pixel) - for space_pixel in range(self._spacing): - yield self.space_color(bar_no, space_pixel) - bar_no += 1 - - colorgen = bar_colors() - self.pixel_object[:] = [next(colorgen) for _ in self.pixel_object] - self.show() - - if self.draw_count % len(self.pixel_object) == 0: - self.cycle_complete() - self._offset = (self._offset + self._direction) % self._repeat_width - - def bar_color(self, n, pixel_no=0): # pylint: disable=unused-argument - """ - Generate the color for the n'th bar_color in the Chase - - :param n: The pixel group to get the color for - :param pixel_no: Which pixel in the group to get the color for - """ - return self.color - - def space_color(self, n, pixel_no=0): # pylint: disable=unused-argument,no-self-use - """ - Generate the spacing color for the n'th bar_color in the Chase - - :param n: The pixel group to get the spacing color for - :param pixel_no: Which pixel in the group to get the spacing color for - """ - return 0 - - def reset(self): - """ - Reset the animation. - """ - self._reset() diff --git a/adafruit_led_animation/animation/__init__.py b/adafruit_led_animation/animation/__init__.py new file mode 100644 index 0000000..b54f76c --- /dev/null +++ b/adafruit_led_animation/animation/__init__.py @@ -0,0 +1,201 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation` +================================================================================ + +Animation base class, and basic animations for CircuitPython helper library for LED animations. + +* Author(s): Roy Hooper, Kattni Rembor + +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + +""" + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" + +from time import monotonic_ns + +from adafruit_led_animation import NANOS_PER_SECOND + + +class Animation: + # pylint: disable=too-many-instance-attributes + """ + Base class for animations. + """ + cycle_complete_supported = False + + # pylint: disable=too-many-arguments + def __init__(self, pixel_object, speed, color, peers=None, paused=False, name=None): + self.pixel_object = pixel_object + self.pixel_object.auto_write = False + self.peers = peers if peers else [] + """A sequence of animations to trigger .draw() on when this animation draws.""" + self._speed_ns = 0 + self._color = None + self._paused = paused + self._next_update = monotonic_ns() + self._time_left_at_pause = 0 + self._also_notify = [] + self.speed = speed # sets _speed_ns + self.color = color # Triggers _recompute_color + self.name = name + self.notify_cycles = 1 + """Number of cycles to trigger additional cycle_done notifications after""" + self.draw_count = 0 + """Number of animation frames drawn.""" + self.cycle_count = 0 + """Number of animation cycles completed.""" + + def __str__(self): + return "<%s: %s>" % (self.__class__.__name__, self.name) + + def animate(self): + """ + Call animate() from your code's main loop. It will draw the animation draw() at intervals + configured by the speed property (set from init). + + :return: True if the animation draw cycle was triggered, otherwise False. + """ + if self._paused: + return False + + now = monotonic_ns() + if now < self._next_update: + return False + + self.draw() + self.draw_count += 1 + + # Draw related animations together + if self.peers: + for peer in self.peers: + peer.draw() + + self._next_update = now + self._speed_ns + return True + + def draw(self): + """ + Animation subclasses must implement draw() to render the animation sequence. + Draw must call show(). + """ + raise NotImplementedError() + + def show(self): + """ + Displays the updated pixels. Called during animates with changes. + """ + self.pixel_object.show() + + def freeze(self): + """ + Stops the animation until resumed. + """ + self._paused = True + self._time_left_at_pause = max(0, monotonic_ns() - self._next_update) + + def resume(self): + """ + Resumes the animation. + """ + self._next_update = monotonic_ns() + self._time_left_at_pause + self._time_left_at_pause = 0 + self._paused = False + + def fill(self, color): + """ + Fills the pixel object with a color. + """ + self.pixel_object.fill(color) + + @property + def color(self): + """ + The current color. + """ + return self._color + + @color.setter + def color(self, color): + if self._color == color: + return + if isinstance(color, int): + color = (color >> 16 & 0xFF, color >> 8 & 0xFF, color & 0xFF) + self._color = color + self._recompute_color(color) + + @property + def speed(self): + """ + The animation speed in fractional seconds. + """ + return self._speed_ns / NANOS_PER_SECOND + + @speed.setter + def speed(self, seconds): + self._speed_ns = int(seconds * NANOS_PER_SECOND) + + def _recompute_color(self, color): + """ + Called if the color is changed, which includes at initialization. + Override as needed. + """ + + def cycle_complete(self): + """ + Called by some animations when they complete an animation cycle. + Animations that support cycle complete notifications will have X property set to False. + Override as needed. + """ + self.cycle_count += 1 + if self.cycle_count % self.notify_cycles == 0: + for callback in self._also_notify: + callback(self) + + def add_cycle_complete_receiver(self, callback): + """ + Adds an additional callback when the cycle completes. + + :param callback: Additional callback to trigger when a cycle completes. The callback + is passed the animation object instance. + """ + self._also_notify.append(callback) + + def reset(self): + """ + Resets the animation sequence. + """ diff --git a/adafruit_led_animation/animation/blink.py b/adafruit_led_animation/animation/blink.py new file mode 100644 index 0000000..0a3257f --- /dev/null +++ b/adafruit_led_animation/animation/blink.py @@ -0,0 +1,50 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.blink` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.animation.colorcycle import ColorCycle +from adafruit_led_animation.color import BLACK + + +class Blink(ColorCycle): + """ + Blink a color on and off. + + :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. + """ + + def __init__(self, pixel_object, speed, color, name=None): + super().__init__(pixel_object, speed, [color, BLACK], name=name) + + def _recompute_color(self, color): + self.colors = [color, BLACK] diff --git a/adafruit_led_animation/animation/chase.py b/adafruit_led_animation/animation/chase.py new file mode 100644 index 0000000..f689d28 --- /dev/null +++ b/adafruit_led_animation/animation/chase.py @@ -0,0 +1,132 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.chase` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from math import ceil + +from adafruit_led_animation.animation import Animation + + +class Chase(Animation): + """ + Chase pixels in one direction in a single color, like a theater marquee sign. + + :param pixel_object: The initialised LED object. + :param float speed: Animation speed rate in seconds, e.g. ``0.1``. + :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. + :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. + """ + + # pylint: disable=too-many-arguments + def __init__( + self, pixel_object, speed, color, size=2, spacing=3, reverse=False, name=None + ): + self._size = size + self._spacing = spacing + self._repeat_width = size + spacing + self._num_repeats = ceil(len(pixel_object) / self._repeat_width) + self._overflow = len(pixel_object) % self._repeat_width + self._direction = 1 if not reverse else -1 + self._reverse = reverse + self._offset = 0 + + def _resetter(): + self._offset = 0 + self._reverse = reverse + self._direction = 1 if not reverse else -1 + + self._reset = _resetter + + super().__init__(pixel_object, speed, color, name=name) + + cycle_complete_supported = True + + @property + def reverse(self): + """ + Whether the animation is reversed + """ + return self._reverse + + @reverse.setter + def reverse(self, value): + self._reverse = value + self._direction = -1 if self._reverse else 1 + + def draw(self): + def bar_colors(): + bar_no = 0 + for i in range(self._offset, 0, -1): + if i > self._spacing: + yield self.bar_color(bar_no, i) + else: + yield self.space_color(bar_no, i) + bar_no = 1 + while True: + for bar_pixel in range(self._size): + yield self.bar_color(bar_no, bar_pixel) + for space_pixel in range(self._spacing): + yield self.space_color(bar_no, space_pixel) + bar_no += 1 + + colorgen = bar_colors() + self.pixel_object[:] = [next(colorgen) for _ in self.pixel_object] + self.show() + + if self.draw_count % len(self.pixel_object) == 0: + self.cycle_complete() + self._offset = (self._offset + self._direction) % self._repeat_width + + def bar_color(self, n, pixel_no=0): # pylint: disable=unused-argument + """ + Generate the color for the n'th bar_color in the Chase + + :param n: The pixel group to get the color for + :param pixel_no: Which pixel in the group to get the color for + """ + return self.color + + def space_color(self, n, pixel_no=0): # pylint: disable=unused-argument,no-self-use + """ + Generate the spacing color for the n'th bar_color in the Chase + + :param n: The pixel group to get the spacing color for + :param pixel_no: Which pixel in the group to get the spacing color for + """ + return 0 + + def reset(self): + """ + Reset the animation. + """ + self._reset() diff --git a/adafruit_led_animation/animation/colorcycle.py b/adafruit_led_animation/animation/colorcycle.py new file mode 100644 index 0000000..785192d --- /dev/null +++ b/adafruit_led_animation/animation/colorcycle.py @@ -0,0 +1,73 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.colorcycle` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.animation import Animation +from adafruit_led_animation.color import RAINBOW + + +class ColorCycle(Animation): + """ + Animate a sequence of one or more colors, cycling at the specified speed. + + :param pixel_object: The initialised LED object. + :param float speed: Animation speed in seconds, e.g. ``0.1``. + :param colors: A list of colors to cycle through in ``(r, g, b)`` tuple, or ``0x000000`` hex + format. Defaults to a rainbow color cycle. + """ + + def __init__(self, pixel_object, speed, colors=RAINBOW, name=None): + self.colors = colors + super().__init__(pixel_object, speed, colors[0], name=name) + self._generator = self._color_generator() + next(self._generator) + + cycle_complete_supported = True + + def draw(self): + self.pixel_object.fill(self.color) + self.show() + next(self._generator) + + def _color_generator(self): + index = 0 + while True: + self._color = self.colors[index] + yield + index = (index + 1) % len(self.colors) + if index == 0: + self.cycle_complete() + + def reset(self): + """ + Resets to the first color. + """ + self._generator = self._color_generator() diff --git a/adafruit_led_animation/animation/comet.py b/adafruit_led_animation/animation/comet.py new file mode 100644 index 0000000..f558917 --- /dev/null +++ b/adafruit_led_animation/animation/comet.py @@ -0,0 +1,132 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.comet` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.animation import Animation +from adafruit_led_animation.color import BLACK + + +class Comet(Animation): + """ + A comet animation. + + :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. + :param bool reverse: Animates the comet in the reverse order. Defaults to ``False``. + :param bool bounce: Comet will bounce back and forth. Defaults to ``True``. + """ + + # pylint: disable=too-many-arguments + def __init__( + self, + pixel_object, + speed, + color, + tail_length=10, + reverse=False, + bounce=False, + name=None, + ): + self._tail_length = tail_length + 1 + self._color_step = 0.9 / tail_length + self._color_offset = 0.1 + self._comet_colors = None + self._reverse_comet_colors = None + self._initial_reverse = reverse + self.reverse = reverse + self.bounce = bounce + self._computed_color = color + self._generator = self._comet_generator() + super().__init__(pixel_object, speed, color, name=name) + + cycle_complete_supported = True + + def _recompute_color(self, color): + pass + + def __recompute_color(self, color): + self._comet_colors = [BLACK] + [ + [ + int(color[rgb] * ((n * self._color_step) + self._color_offset)) + for rgb in range(len(color)) + ] + for n in range(self._tail_length - 1) + ] + self._reverse_comet_colors = list(reversed(self._comet_colors)) + self._computed_color = color + + def _get_range(self, num_pixels): + if self.reverse: + return range(num_pixels, -self._tail_length - 1, -1) + return range(-self._tail_length, num_pixels + 1) + + def _comet_generator(self): + num_pixels = len(self.pixel_object) + cycle_passes = 0 + while True: + if self._color != self._computed_color or not self._comet_colors: + self.__recompute_color(self._color) + colors = self._reverse_comet_colors if self.reverse else self._comet_colors + for start in self._get_range(num_pixels): + + if start + self._tail_length < num_pixels: + end = self._tail_length + else: + end = num_pixels - start + if start <= 0: + num_visible = self._tail_length + start + self.pixel_object[0:num_visible] = colors[ + self._tail_length - num_visible : + ] + else: + self.pixel_object[start : start + end] = colors[0:end] + self.show() + yield + cycle_passes += 1 + if self.bounce: + self.reverse = not self.reverse + if not self.bounce or cycle_passes == 2: + self.cycle_complete() + cycle_passes = 0 + + def draw(self): + next(self._generator) + + def reset(self): + """ + Resets to the first color. + """ + self._generator = self._comet_generator() + self.reverse = self._initial_reverse diff --git a/adafruit_led_animation/animation/pulse.py b/adafruit_led_animation/animation/pulse.py new file mode 100644 index 0000000..a3bcc98 --- /dev/null +++ b/adafruit_led_animation/animation/pulse.py @@ -0,0 +1,71 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.pulse` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.animation import Animation + + +class Pulse(Animation): + """ + Pulse all pixels a single color. + + :param pixel_object: The initialised LED object. + :param float speed: Animation refresh rate in seconds, e.g. ``0.1``. + :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. + :param period: Period to pulse the LEDs over. Default 5. + """ + + # pylint: disable=too-many-arguments + def __init__(self, pixel_object, speed, color, period=5, name=None): + super().__init__(pixel_object, speed, color, name=name) + self._period = period + self._generator = None + self.reset() + + cycle_complete_supported = True + + def draw(self): + color = next(self._generator) + self.fill(color) + self.show() + + def reset(self): + """ + Resets the animation. + """ + white = len(self.pixel_object[0]) > 3 and isinstance( + self.pixel_object[0][-1], int + ) + from adafruit_led_animation.helper import ( # pylint: disable=import-outside-toplevel + pulse_generator, + ) + + self._generator = pulse_generator(self._period, self, white) diff --git a/adafruit_led_animation/rainbow.py b/adafruit_led_animation/animation/rainbow.py similarity index 50% rename from adafruit_led_animation/rainbow.py rename to adafruit_led_animation/animation/rainbow.py index 78500b1..76cf021 100644 --- a/adafruit_led_animation/rainbow.py +++ b/adafruit_led_animation/animation/rainbow.py @@ -21,10 +21,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """ -`adafruit_led_animation.rainbow` +`adafruit_led_animation.animation.rainbow` ================================================================================ Rainbow animations for CircuitPython helper library for LED animations. +TODO * Author(s): Roy Hooper, Kattni Rembor @@ -43,9 +44,9 @@ """ -from adafruit_led_animation.animation import Animation, Chase, Comet +from adafruit_led_animation.animation import Animation from adafruit_led_animation.color import BLACK, colorwheel -from . import NANOS_PER_SECOND, monotonic_ns +from adafruit_led_animation import NANOS_PER_SECOND, monotonic_ns __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" @@ -101,93 +102,3 @@ def reset(self): Resets the animation. """ self._generator = self._color_wheel_generator() - - -class RainbowChase(Chase): - """ - Chase pixels in one direction, like a theater marquee but with rainbows! - - :param pixel_object: The initialised LED object. - :param float speed: Animation speed rate in seconds, e.g. ``0.1``. - :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. - :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) - """ - - # pylint: disable=too-many-arguments - def __init__( - self, - pixel_object, - speed, - size=2, - spacing=3, - reverse=False, - name=None, - wheel_step=8, - ): - self._num_colors = 256 // wheel_step - self._colors = [colorwheel(n % 256) for n in range(0, 512, wheel_step)] - self._color_idx = 0 - super().__init__(pixel_object, speed, 0, size, spacing, reverse, name) - - def bar_color(self, n, pixel_no=0): - return self._colors[self._color_idx - n] - - def cycle_complete(self): - self._color_idx = (self._color_idx + self._direction) % len(self._colors) - super().cycle_complete() - - -class RainbowComet(Comet): - """ - A rainbow comet animation. - - :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. - :param bool reverse: Animates the comet in the reverse order. Defaults to ``False``. - :param bool bounce: Comet will bounce back and forth. Defaults to ``True``. - :param int colorwheel_offset: Offset from start of colorwheel (0-255). - """ - - # pylint: disable=too-many-arguments - def __init__( - self, - pixel_object, - speed, - tail_length=10, - reverse=False, - bounce=False, - colorwheel_offset=0, - name=None, - ): - self._colorwheel_is_tuple = isinstance(colorwheel(0), tuple) - self._colorwheel_offset = colorwheel_offset - - super().__init__(pixel_object, speed, 0, tail_length, reverse, bounce, name) - - def _calc_brightness(self, n, color): - brightness = (n * self._color_step) + self._color_offset - if not self._colorwheel_is_tuple: - color = (color & 0xFF, ((color & 0xFF00) >> 8), (color >> 16)) - return [int(i * brightness) for i in color] - - def __recompute_color(self, color): - factor = int(256 / self._tail_length) - self._comet_colors = [BLACK] + [ - self._calc_brightness( - n, - colorwheel( - int((n * factor) + self._color_offset + self._colorwheel_offset) - % 256 - ), - ) - for n in range(self._tail_length - 1) - ] - self._reverse_comet_colors = list(reversed(self._comet_colors)) - self._computed_color = color diff --git a/adafruit_led_animation/animation/rainbowchase.py b/adafruit_led_animation/animation/rainbowchase.py new file mode 100644 index 0000000..bc54472 --- /dev/null +++ b/adafruit_led_animation/animation/rainbowchase.py @@ -0,0 +1,71 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.rainbowchase` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.color import colorwheel +from adafruit_led_animation.animation.chase import Chase + + +class RainbowChase(Chase): + """ + Chase pixels in one direction, like a theater marquee but with rainbows! + + :param pixel_object: The initialised LED object. + :param float speed: Animation speed rate in seconds, e.g. ``0.1``. + :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. + :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) + """ + + # pylint: disable=too-many-arguments + def __init__( + self, + pixel_object, + speed, + size=2, + spacing=3, + reverse=False, + name=None, + wheel_step=8, + ): + self._num_colors = 256 // wheel_step + self._colors = [colorwheel(n % 256) for n in range(0, 512, wheel_step)] + self._color_idx = 0 + super().__init__(pixel_object, speed, 0, size, spacing, reverse, name) + + def bar_color(self, n, pixel_no=0): + return self._colors[self._color_idx - n] + + def cycle_complete(self): + self._color_idx = (self._color_idx + self._direction) % len(self._colors) + super().cycle_complete() diff --git a/adafruit_led_animation/animation/rainbowcomet.py b/adafruit_led_animation/animation/rainbowcomet.py new file mode 100644 index 0000000..88de529 --- /dev/null +++ b/adafruit_led_animation/animation/rainbowcomet.py @@ -0,0 +1,87 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.rainbowcomet` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.animation.comet import Comet +from adafruit_led_animation.color import colorwheel, BLACK + + +class RainbowComet(Comet): + """ + A rainbow comet animation. + + :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. + :param bool reverse: Animates the comet in the reverse order. Defaults to ``False``. + :param bool bounce: Comet will bounce back and forth. Defaults to ``True``. + :param int colorwheel_offset: Offset from start of colorwheel (0-255). + """ + + # pylint: disable=too-many-arguments + def __init__( + self, + pixel_object, + speed, + tail_length=10, + reverse=False, + bounce=False, + colorwheel_offset=0, + name=None, + ): + self._colorwheel_is_tuple = isinstance(colorwheel(0), tuple) + self._colorwheel_offset = colorwheel_offset + + super().__init__(pixel_object, speed, 0, tail_length, reverse, bounce, name) + + def _calc_brightness(self, n, color): + brightness = (n * self._color_step) + self._color_offset + if not self._colorwheel_is_tuple: + color = (color & 0xFF, ((color & 0xFF00) >> 8), (color >> 16)) + return [int(i * brightness) for i in color] + + def __recompute_color(self, color): + factor = int(256 / self._tail_length) + self._comet_colors = [BLACK] + [ + self._calc_brightness( + n, + colorwheel( + int((n * factor) + self._color_offset + self._colorwheel_offset) + % 256 + ), + ) + for n in range(self._tail_length - 1) + ] + self._reverse_comet_colors = list(reversed(self._comet_colors)) + self._computed_color = color diff --git a/adafruit_led_animation/animation/solid.py b/adafruit_led_animation/animation/solid.py new file mode 100644 index 0000000..10aa56f --- /dev/null +++ b/adafruit_led_animation/animation/solid.py @@ -0,0 +1,48 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.solid` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +from adafruit_led_animation.animation.colorcycle import ColorCycle + + +class Solid(ColorCycle): + """ + A solid color. + + :param pixel_object: The initialised LED object. + :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. + """ + + def __init__(self, pixel_object, color, name=None): + super().__init__(pixel_object, speed=1, colors=[color], name=name) + + def _recompute_color(self, color): + self.colors = [color] diff --git a/adafruit_led_animation/animation/sparkle.py b/adafruit_led_animation/animation/sparkle.py new file mode 100644 index 0000000..c1ed704 --- /dev/null +++ b/adafruit_led_animation/animation/sparkle.py @@ -0,0 +1,95 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.sparkle` +================================================================================ + +Sparkle animations for CircuitPython helper library for LED animations. +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + +""" + +import random +from adafruit_led_animation.animation import Animation + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" + + +class Sparkle(Animation): + """ + Sparkle animation of a single color. + + :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 num_sparkles: Number of sparkles to generate per animation cycle. + """ + + # pylint: disable=too-many-arguments + def __init__(self, pixel_object, speed, color, num_sparkles=1, name=None): + if len(pixel_object) < 2: + raise ValueError("Sparkle needs at least 2 pixels") + self._half_color = None + self._dim_color = None + self._num_sparkles = num_sparkles + super().__init__(pixel_object, speed, color, name=name) + + def _recompute_color(self, color): + half_color = tuple(color[rgb] // 4 for rgb in range(len(color))) + dim_color = tuple(color[rgb] // 10 for rgb in range(len(color))) + for pixel in range(len(self.pixel_object)): + if self.pixel_object[pixel] == self._half_color: + self.pixel_object[pixel] = half_color + elif self.pixel_object[pixel] == self._dim_color: + self.pixel_object[pixel] = dim_color + self._half_color = half_color + self._dim_color = dim_color + + def draw(self): + pixels = [ + random.randint(0, (len(self.pixel_object) - 2)) + for n in range(self._num_sparkles) + ] + for pixel in pixels: + self.pixel_object[pixel] = self._color + self.show() + for pixel in pixels: + self.pixel_object[pixel] = self._half_color + self.pixel_object[pixel + 1] = self._dim_color + self.show() diff --git a/adafruit_led_animation/sparkle.py b/adafruit_led_animation/animation/sparklepulse.py similarity index 62% rename from adafruit_led_animation/sparkle.py rename to adafruit_led_animation/animation/sparklepulse.py index 8ac5b36..dcd4740 100644 --- a/adafruit_led_animation/sparkle.py +++ b/adafruit_led_animation/animation/sparklepulse.py @@ -21,79 +21,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """ -`adafruit_led_animation.sparkle` +`adafruit_led_animation.animation.sparklepluse` ================================================================================ -Sparkle animations for CircuitPython helper library for LED animations. +TODO - -* Author(s): Roy Hooper, Kattni Rembor - -Implementation Notes --------------------- - -**Hardware:** - -* `Adafruit NeoPixels `_ -* `Adafruit DotStars `_ - -**Software and Dependencies:** - -* Adafruit CircuitPython firmware for the supported boards: - https://circuitpython.org/downloads +* Author(s): TODO """ import random -from adafruit_led_animation.animation import Animation -from . import NANOS_PER_SECOND, monotonic_ns - -__version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" - - -class Sparkle(Animation): - """ - Sparkle animation of a single color. - - :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 num_sparkles: Number of sparkles to generate per animation cycle. - """ - - # pylint: disable=too-many-arguments - def __init__(self, pixel_object, speed, color, num_sparkles=1, name=None): - if len(pixel_object) < 2: - raise ValueError("Sparkle needs at least 2 pixels") - self._half_color = None - self._dim_color = None - self._num_sparkles = num_sparkles - super().__init__(pixel_object, speed, color, name=name) - - def _recompute_color(self, color): - half_color = tuple(color[rgb] // 4 for rgb in range(len(color))) - dim_color = tuple(color[rgb] // 10 for rgb in range(len(color))) - for pixel in range(len(self.pixel_object)): - if self.pixel_object[pixel] == self._half_color: - self.pixel_object[pixel] = half_color - elif self.pixel_object[pixel] == self._dim_color: - self.pixel_object[pixel] = dim_color - self._half_color = half_color - self._dim_color = dim_color +from time import monotonic_ns - def draw(self): - pixels = [ - random.randint(0, (len(self.pixel_object) - 2)) - for n in range(self._num_sparkles) - ] - for pixel in pixels: - self.pixel_object[pixel] = self._color - self.show() - for pixel in pixels: - self.pixel_object[pixel] = self._half_color - self.pixel_object[pixel + 1] = self._dim_color - self.show() +from adafruit_led_animation import NANOS_PER_SECOND +from adafruit_led_animation.animation import Animation class SparklePulse(Animation): diff --git a/adafruit_led_animation/color.py b/adafruit_led_animation/color.py index 28203ee..daead03 100644 --- a/adafruit_led_animation/color.py +++ b/adafruit_led_animation/color.py @@ -45,8 +45,8 @@ try: - # Backwards compat for 5.3.0 and prior try: + # Backwards compat for 5.3.0 and prior from _pixelbuf import colorwheel # pylint: disable=unused-import except ImportError: from _pixelbuf import wheel as colorwheel # pylint: disable=unused-import diff --git a/examples/led_animation_all_animations.py b/examples/led_animation_all_animations.py index 8ec5b20..e78d188 100644 --- a/examples/led_animation_all_animations.py +++ b/examples/led_animation_all_animations.py @@ -9,8 +9,8 @@ import board import neopixel -import adafruit_led_animation.rainbow -import adafruit_led_animation.sparkle +import adafruit_led_animation.animation.blink +import adafruit_led_animation.animation.sparklepulse from adafruit_led_animation import animation from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation.color import PURPLE, WHITE, AMBER, JADE @@ -22,22 +22,22 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) -blink = animation.Blink(pixels, speed=0.5, color=JADE) +blink = adafruit_led_animation.animation.animation.blink.Blink(pixels, speed=0.5, color=JADE) comet = animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) chase = animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) pulse = animation.Pulse(pixels, speed=0.1, period=3, color=AMBER) -sparkle = adafruit_led_animation.sparkle.Sparkle( +sparkle = adafruit_led_animation.animation.animation.sparkle.Sparkle( pixels, speed=0.1, color=PURPLE, num_sparkles=10 ) -solid = animation.Solid(pixels, color=JADE) -rainbow = adafruit_led_animation.rainbow.Rainbow(pixels, speed=0.1, period=2) -sparkle_pulse = adafruit_led_animation.sparkle.SparklePulse( +solid = adafruit_led_animation.animation.animation.solid.Solid(pixels, color=JADE) +rainbow = adafruit_led_animation.animation.animation.rainbow.Rainbow(pixels, speed=0.1, period=2) +sparkle_pulse = adafruit_led_animation.animation.animation.sparklepulse.SparklePulse( pixels, speed=0.1, period=3, color=JADE ) -rainbow_comet = adafruit_led_animation.rainbow.RainbowComet( +rainbow_comet = adafruit_led_animation.animation.animation.rainbowcomet.RainbowComet( pixels, speed=0.1, tail_length=7, bounce=True ) -rainbow_chase = adafruit_led_animation.rainbow.RainbowChase( +rainbow_chase = adafruit_led_animation.animation.animation.rainbowchase.RainbowChase( pixels, speed=0.1, size=3, spacing=2, wheel_step=8 ) diff --git a/examples/led_animation_gridmap.py b/examples/led_animation_gridmap.py index 2931aab..336c5a2 100644 --- a/examples/led_animation_gridmap.py +++ b/examples/led_animation_gridmap.py @@ -10,7 +10,7 @@ import board import neopixel -import adafruit_led_animation.rainbow +import adafruit_led_animation.animation.rainbow import adafruit_led_animation.sequence from adafruit_led_animation import animation from adafruit_led_animation import helper @@ -35,16 +35,16 @@ chase_h = animation.Chase( pixel_wing_horizontal, speed=0.1, size=3, spacing=6, color=JADE ) -rainbow_chase_v = adafruit_led_animation.rainbow.RainbowChase( +rainbow_chase_v = adafruit_led_animation.animation.animation.rainbowchase.RainbowChase( pixel_wing_vertical, speed=0.1, size=3, spacing=2, wheel_step=8 ) -rainbow_comet_v = adafruit_led_animation.rainbow.RainbowComet( +rainbow_comet_v = adafruit_led_animation.animation.animation.rainbowcomet.RainbowComet( pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True ) -rainbow_v = adafruit_led_animation.rainbow.Rainbow( +rainbow_v = adafruit_led_animation.animation.animation.rainbow.Rainbow( pixel_wing_vertical, speed=0.1, period=2 ) -rainbow_chase_h = adafruit_led_animation.rainbow.RainbowChase( +rainbow_chase_h = adafruit_led_animation.animation.animation.rainbowchase.RainbowChase( pixel_wing_horizontal, speed=0.1, size=3, spacing=3 ) From 5c90cfafac7759c13d9b706bf4da2b0795c9a4dd Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sun, 17 May 2020 14:04:06 -0400 Subject: [PATCH 3/6] rainbowsparkles --- adafruit_led_animation/animation/rainbow.py | 49 ++++++++++-- .../animation/rainbowsparkle.py | 76 +++++++++++++++++++ 2 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 adafruit_led_animation/animation/rainbowsparkle.py diff --git a/adafruit_led_animation/animation/rainbow.py b/adafruit_led_animation/animation/rainbow.py index 76cf021..46be0e2 100644 --- a/adafruit_led_animation/animation/rainbow.py +++ b/adafruit_led_animation/animation/rainbow.py @@ -52,26 +52,43 @@ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" + class Rainbow(Animation): """ The classic rainbow color wheel. :param pixel_object: The initialised LED object. :param float speed: Animation refresh rate in seconds, e.g. ``0.1``. - :param period: Period to cycle the rainbow over. Default 5. + :param float period: Period to cycle the rainbow over in seconds. Default 5. + :param float step: Color wheel step. Default 1. + :param str name: Name of animation (optional, useful for sequences and debugging). + :param bool precompute_rainbow: Whether to precompute the rainbow. Uses more memory. (default True). """ # pylint: disable=too-many-arguments - def __init__(self, pixel_object, speed, period=5, name=None): + def __init__(self, pixel_object, speed, period=5, step=1, name=None, precompute_rainbow=True): super().__init__(pixel_object, speed, BLACK, name=name) self._period = period + self._step = step + self._wheel_index = 0 + self.colors = None self._generator = self._color_wheel_generator() + if precompute_rainbow: + self.generate_rainbow() + + def generate_rainbow(self): + self.colors = [] + i = 0 + while i < 256: + self.colors.append(colorwheel(int(i))) + i += self._step cycle_complete_supported = True def _color_wheel_generator(self): period = int(self._period * NANOS_PER_SECOND) + num_pixels = len(self.pixel_object) last_update = monotonic_ns() cycle_position = 0 last_pos = 0 @@ -84,16 +101,34 @@ def _color_wheel_generator(self): if pos < last_pos: cycle_completed = True last_pos = pos - wheel_index = int((pos / period) * 256) - self.pixel_object[:] = [ - colorwheel((i + wheel_index) % 255) - for i, _ in enumerate(self.pixel_object) - ] + wheel_index = int((pos / period) * len(self.colors)) + + if self.colors: + self._draw_precomputed(num_pixels, wheel_index) + else: + wheel_index = int((pos / period) * 256) + self.pixel_object[:] = [ + colorwheel((i + wheel_index) % 255) + for i in range(num_pixels) + ] + self._wheel_index = wheel_index self.show() if cycle_completed: self.cycle_complete() yield + def _draw_precomputed(self, num_pixels, wheel_index): + for i in range(0, num_pixels, len(self.colors)): + num = len(self.colors) + if i + len(self.colors) > num_pixels: + num = num_pixels - i + if wheel_index + num > len(self.colors): + colors_left = len(self.colors) - wheel_index + self.pixel_object[i:i + colors_left] = self.colors[wheel_index:] + self.pixel_object[i + colors_left:i + num] = self.colors[:num - colors_left] + else: + self.pixel_object[i:i + num] = self.colors[wheel_index:wheel_index + num] + def draw(self): next(self._generator) diff --git a/adafruit_led_animation/animation/rainbowsparkle.py b/adafruit_led_animation/animation/rainbowsparkle.py new file mode 100644 index 0000000..8f1d5fc --- /dev/null +++ b/adafruit_led_animation/animation/rainbowsparkle.py @@ -0,0 +1,76 @@ +# The MIT License (MIT) +# +# Copyright (c) 2019-2020 Roy Hooper +# Copyright (c) 2020 Kattni Rembor for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_led_animation.animation.rainbowcomet` +================================================================================ + +TODO + +* Author(s): Roy Hooper, Kattni Rembor + +""" + +import random + +from adafruit_led_animation.animation.rainbow import Rainbow + + +class RainbowSparkle(Rainbow): + + def __init__(self, pixel_object, speed, period=5, num_sparkles=None, step=1, name=None, + bg_brightness=0.2): + self._num_sparkles = num_sparkles + if num_sparkles is None: + self._num_sparkles = max(1, int(len(pixel_object) / 20)) + self._sparkle_duration = 2 + self._bg_brightness = bg_brightness + self._bright_colors = None + super().__init__(pixel_object=pixel_object, speed=speed, period=period, step=step, name=name, + precompute_rainbow=True) + + def generate_rainbow(self, step=1): + super().generate_rainbow() + self._bright_colors = self.colors[:] + for i, color in enumerate(self.colors): + if isinstance(self.colors[i], int): + self.colors[i] = ( + int(self._bg_brightness * ((color & 0xff0000) >> 16)), + int(self._bg_brightness * ((color & 0xff00) >> 8)), + int(self._bg_brightness * (color & 0xff)) + ) + else: + self.colors[i] = ( + int(self._bg_brightness * color[0]), + int(self._bg_brightness * color[1]), + int(self._bg_brightness * color[2]) + ) + + def show(self): + pixels = [ + random.randint(0, len(self.pixel_object)-1) + for n in range(self._num_sparkles) + ] + for pixel in pixels: + bc = (self._wheel_index + pixel) % len(self._bright_colors) + self.pixel_object[pixel] = self._bright_colors[bc] + super().show() From 74b0f6c12c6a520473a075715406c34817046688 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Sun, 17 May 2020 15:00:13 -0400 Subject: [PATCH 4/6] Docs, pylint. --- adafruit_led_animation/animation/__init__.py | 6 +- adafruit_led_animation/animation/blink.py | 16 +++- adafruit_led_animation/animation/chase.py | 16 +++- .../animation/colorcycle.py | 16 +++- adafruit_led_animation/animation/comet.py | 16 +++- adafruit_led_animation/animation/pulse.py | 16 +++- adafruit_led_animation/animation/rainbow.py | 25 +++--- .../animation/rainbowchase.py | 16 +++- .../animation/rainbowcomet.py | 16 +++- .../animation/rainbowsparkle.py | 76 ++++++++++++++----- adafruit_led_animation/animation/solid.py | 16 +++- adafruit_led_animation/animation/sparkle.py | 3 +- .../animation/sparklepulse.py | 22 ++++-- docs/api.rst | 39 +++++++++- docs/conf.py | 6 +- examples/led_animation_all_animations.py | 8 +- 16 files changed, 258 insertions(+), 55 deletions(-) diff --git a/adafruit_led_animation/animation/__init__.py b/adafruit_led_animation/animation/__init__.py index b54f76c..83a2aa3 100644 --- a/adafruit_led_animation/animation/__init__.py +++ b/adafruit_led_animation/animation/__init__.py @@ -24,7 +24,7 @@ `adafruit_led_animation.animation` ================================================================================ -Animation base class, and basic animations for CircuitPython helper library for LED animations. +Animation base class for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor @@ -46,9 +46,7 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" -from time import monotonic_ns - -from adafruit_led_animation import NANOS_PER_SECOND +from adafruit_led_animation import NANOS_PER_SECOND, monotonic_ns class Animation: diff --git a/adafruit_led_animation/animation/blink.py b/adafruit_led_animation/animation/blink.py index 0a3257f..fe6ec10 100644 --- a/adafruit_led_animation/animation/blink.py +++ b/adafruit_led_animation/animation/blink.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.blink` ================================================================================ -TODO +Blink animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.animation.colorcycle import ColorCycle diff --git a/adafruit_led_animation/animation/chase.py b/adafruit_led_animation/animation/chase.py index f689d28..bd7a308 100644 --- a/adafruit_led_animation/animation/chase.py +++ b/adafruit_led_animation/animation/chase.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.chase` ================================================================================ -TODO +Theatre chase animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from math import ceil diff --git a/adafruit_led_animation/animation/colorcycle.py b/adafruit_led_animation/animation/colorcycle.py index 785192d..42b590e 100644 --- a/adafruit_led_animation/animation/colorcycle.py +++ b/adafruit_led_animation/animation/colorcycle.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.colorcycle` ================================================================================ -TODO +Color cycle animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.animation import Animation diff --git a/adafruit_led_animation/animation/comet.py b/adafruit_led_animation/animation/comet.py index f558917..4476128 100644 --- a/adafruit_led_animation/animation/comet.py +++ b/adafruit_led_animation/animation/comet.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.comet` ================================================================================ -TODO +Comet animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.animation import Animation diff --git a/adafruit_led_animation/animation/pulse.py b/adafruit_led_animation/animation/pulse.py index a3bcc98..1b3aa33 100644 --- a/adafruit_led_animation/animation/pulse.py +++ b/adafruit_led_animation/animation/pulse.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.pulse` ================================================================================ -TODO +Pulse animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.animation import Animation diff --git a/adafruit_led_animation/animation/rainbow.py b/adafruit_led_animation/animation/rainbow.py index 46be0e2..c102dd5 100644 --- a/adafruit_led_animation/animation/rainbow.py +++ b/adafruit_led_animation/animation/rainbow.py @@ -24,8 +24,7 @@ `adafruit_led_animation.animation.rainbow` ================================================================================ -Rainbow animations for CircuitPython helper library for LED animations. -TODO +Rainbow animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor @@ -52,7 +51,6 @@ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" - class Rainbow(Animation): """ The classic rainbow color wheel. @@ -62,11 +60,14 @@ class Rainbow(Animation): :param float period: Period to cycle the rainbow over in seconds. Default 5. :param float step: Color wheel step. Default 1. :param str name: Name of animation (optional, useful for sequences and debugging). - :param bool precompute_rainbow: Whether to precompute the rainbow. Uses more memory. (default True). + :param bool precompute_rainbow: Whether to precompute the rainbow. Uses more memory. + (default True). """ # pylint: disable=too-many-arguments - def __init__(self, pixel_object, speed, period=5, step=1, name=None, precompute_rainbow=True): + def __init__( + self, pixel_object, speed, period=5, step=1, name=None, precompute_rainbow=True + ): super().__init__(pixel_object, speed, BLACK, name=name) self._period = period self._step = step @@ -77,6 +78,7 @@ def __init__(self, pixel_object, speed, period=5, step=1, name=None, precompute_ self.generate_rainbow() def generate_rainbow(self): + """Generates the rainbow.""" self.colors = [] i = 0 while i < 256: @@ -108,8 +110,7 @@ def _color_wheel_generator(self): else: wheel_index = int((pos / period) * 256) self.pixel_object[:] = [ - colorwheel((i + wheel_index) % 255) - for i in range(num_pixels) + colorwheel((i + wheel_index) % 255) for i in range(num_pixels) ] self._wheel_index = wheel_index self.show() @@ -124,10 +125,14 @@ def _draw_precomputed(self, num_pixels, wheel_index): num = num_pixels - i if wheel_index + num > len(self.colors): colors_left = len(self.colors) - wheel_index - self.pixel_object[i:i + colors_left] = self.colors[wheel_index:] - self.pixel_object[i + colors_left:i + num] = self.colors[:num - colors_left] + self.pixel_object[i : i + colors_left] = self.colors[wheel_index:] + self.pixel_object[i + colors_left : i + num] = self.colors[ + : num - colors_left + ] else: - self.pixel_object[i:i + num] = self.colors[wheel_index:wheel_index + num] + self.pixel_object[i : i + num] = self.colors[ + wheel_index : wheel_index + num + ] def draw(self): next(self._generator) diff --git a/adafruit_led_animation/animation/rainbowchase.py b/adafruit_led_animation/animation/rainbowchase.py index bc54472..8394fdb 100644 --- a/adafruit_led_animation/animation/rainbowchase.py +++ b/adafruit_led_animation/animation/rainbowchase.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.rainbowchase` ================================================================================ -TODO +Rainbow chase animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.color import colorwheel diff --git a/adafruit_led_animation/animation/rainbowcomet.py b/adafruit_led_animation/animation/rainbowcomet.py index 88de529..beb667d 100644 --- a/adafruit_led_animation/animation/rainbowcomet.py +++ b/adafruit_led_animation/animation/rainbowcomet.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.rainbowcomet` ================================================================================ -TODO +Rainbow comet for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.animation.comet import Comet diff --git a/adafruit_led_animation/animation/rainbowsparkle.py b/adafruit_led_animation/animation/rainbowsparkle.py index 8f1d5fc..c71e799 100644 --- a/adafruit_led_animation/animation/rainbowsparkle.py +++ b/adafruit_led_animation/animation/rainbowsparkle.py @@ -21,56 +21,96 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """ -`adafruit_led_animation.animation.rainbowcomet` +`adafruit_led_animation.animation.rainbowsparkle` ================================================================================ -TODO +Rainbow sparkle for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + """ import random - from adafruit_led_animation.animation.rainbow import Rainbow class RainbowSparkle(Rainbow): + """Rainbow sparkle animation. + + :param pixel_object: The initialised LED object. + :param float speed: Animation refresh rate in seconds, e.g. ``0.1``. + :param float period: Period to cycle the rainbow over in seconds. Default 5. + :param float step: Color wheel step. Default 1. + :param str name: Name of animation (optional, useful for sequences and debugging). + :param float background_brightness: The brightness of the background rainbow. Defaults to + ``0.2`` or 20 percent. + :param bool precompute_rainbow: Whether to precompute the rainbow. Uses more memory. + (default True). + """ - def __init__(self, pixel_object, speed, period=5, num_sparkles=None, step=1, name=None, - bg_brightness=0.2): + # pylint: disable=too-many-arguments + def __init__( + self, + pixel_object, + speed, + period=5, + num_sparkles=None, + step=1, + name=None, + background_brightness=0.2, + ): self._num_sparkles = num_sparkles if num_sparkles is None: self._num_sparkles = max(1, int(len(pixel_object) / 20)) self._sparkle_duration = 2 - self._bg_brightness = bg_brightness + self._background_brightness = background_brightness self._bright_colors = None - super().__init__(pixel_object=pixel_object, speed=speed, period=period, step=step, name=name, - precompute_rainbow=True) + super().__init__( + pixel_object=pixel_object, + speed=speed, + period=period, + step=step, + name=name, + precompute_rainbow=True, + ) - def generate_rainbow(self, step=1): + def generate_rainbow(self): super().generate_rainbow() self._bright_colors = self.colors[:] for i, color in enumerate(self.colors): if isinstance(self.colors[i], int): self.colors[i] = ( - int(self._bg_brightness * ((color & 0xff0000) >> 16)), - int(self._bg_brightness * ((color & 0xff00) >> 8)), - int(self._bg_brightness * (color & 0xff)) + int(self._background_brightness * ((color & 0xFF0000) >> 16)), + int(self._background_brightness * ((color & 0xFF00) >> 8)), + int(self._background_brightness * (color & 0xFF)), ) else: self.colors[i] = ( - int(self._bg_brightness * color[0]), - int(self._bg_brightness * color[1]), - int(self._bg_brightness * color[2]) + int(self._background_brightness * color[0]), + int(self._background_brightness * color[1]), + int(self._background_brightness * color[2]), ) def show(self): pixels = [ - random.randint(0, len(self.pixel_object)-1) + random.randint(0, len(self.pixel_object) - 1) for n in range(self._num_sparkles) ] for pixel in pixels: - bc = (self._wheel_index + pixel) % len(self._bright_colors) - self.pixel_object[pixel] = self._bright_colors[bc] + self.pixel_object[pixel] = self._bright_colors[ + (self._wheel_index + pixel) % len(self._bright_colors) + ] super().show() diff --git a/adafruit_led_animation/animation/solid.py b/adafruit_led_animation/animation/solid.py index 10aa56f..7fa90e6 100644 --- a/adafruit_led_animation/animation/solid.py +++ b/adafruit_led_animation/animation/solid.py @@ -24,10 +24,24 @@ `adafruit_led_animation.animation.solid` ================================================================================ -TODO +Solid animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + + """ from adafruit_led_animation.animation.colorcycle import ColorCycle diff --git a/adafruit_led_animation/animation/sparkle.py b/adafruit_led_animation/animation/sparkle.py index c1ed704..81c57a4 100644 --- a/adafruit_led_animation/animation/sparkle.py +++ b/adafruit_led_animation/animation/sparkle.py @@ -24,8 +24,7 @@ `adafruit_led_animation.animation.sparkle` ================================================================================ -Sparkle animations for CircuitPython helper library for LED animations. -TODO +Sparkle animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, Kattni Rembor diff --git a/adafruit_led_animation/animation/sparklepulse.py b/adafruit_led_animation/animation/sparklepulse.py index dcd4740..1c7e3b4 100644 --- a/adafruit_led_animation/animation/sparklepulse.py +++ b/adafruit_led_animation/animation/sparklepulse.py @@ -24,16 +24,28 @@ `adafruit_led_animation.animation.sparklepluse` ================================================================================ -TODO +Sparklepulse animation for CircuitPython helper library for LED animations. + +* Author(s): Roy Hooper, dmolavi + +Implementation Notes +-------------------- + +**Hardware:** + +* `Adafruit NeoPixels `_ +* `Adafruit DotStars `_ + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads -* Author(s): TODO """ import random -from time import monotonic_ns - -from adafruit_led_animation import NANOS_PER_SECOND +from adafruit_led_animation import NANOS_PER_SECOND, monotonic_ns from adafruit_led_animation.animation import Animation diff --git a/docs/api.rst b/docs/api.rst index 61f7163..041b153 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,7 +4,7 @@ .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" -.. automodule:: adafruit_led_animation.animation +.. automodule:: adafruit_led_animation.animation.animation :members: .. automodule:: adafruit_led_animation.color @@ -19,8 +19,41 @@ .. automodule:: adafruit_led_animation.sequence :members: -.. automodule:: adafruit_led_animation.rainbow +.. automodule:: adafruit_led_animation.animation.rainbow :members: -.. automodule:: adafruit_led_animation.sparkle +.. automodule:: adafruit_led_animation.animation.sparkle + :members: + +.. automodule:: adafruit_led_animation.animation.blink + :members: + +.. automodule:: adafruit_led_animation.animation.chase + :members: + +.. automodule:: adafruit_led_animation.animation.colorcycle + :members: + +.. automodule:: adafruit_led_animation.animation.comet + :members: + +.. automodule:: adafruit_led_animation.animation.pulse + :members: + +.. automodule:: adafruit_led_animation.animation.rainbowchase + :members: + +.. automodule:: adafruit_led_animation.animation.rainbowcomet + :members: + +.. automodule:: adafruit_led_animation.animation.rainbowsparkle + :members: + +.. automodule:: adafruit_led_animation.animation.solid + :members: + +.. automodule:: adafruit_led_animation.animation.sparkle + :members: + +.. automodule:: adafruit_led_animation.animation.sparklepulse :members: diff --git a/docs/conf.py b/docs/conf.py index ec64647..d34ea33 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,7 @@ # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = ["led_animation"] +autodoc_mock_imports = ["adafruit_led_animation", "adafruit_led_animation.animation"] intersphinx_mapping = { @@ -39,8 +39,8 @@ # General information about the project. project = "LED_Animation Library" -copyright = "2017 Adam Patt" -author = "Adam Patt" +copyright = "2018 Roy Hoopert" +author = "Roy Hooper" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/examples/led_animation_all_animations.py b/examples/led_animation_all_animations.py index e78d188..dc859b5 100644 --- a/examples/led_animation_all_animations.py +++ b/examples/led_animation_all_animations.py @@ -22,7 +22,9 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) -blink = adafruit_led_animation.animation.animation.blink.Blink(pixels, speed=0.5, color=JADE) +blink = adafruit_led_animation.animation.animation.blink.Blink( + pixels, speed=0.5, color=JADE +) comet = animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) chase = animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) pulse = animation.Pulse(pixels, speed=0.1, period=3, color=AMBER) @@ -30,7 +32,9 @@ pixels, speed=0.1, color=PURPLE, num_sparkles=10 ) solid = adafruit_led_animation.animation.animation.solid.Solid(pixels, color=JADE) -rainbow = adafruit_led_animation.animation.animation.rainbow.Rainbow(pixels, speed=0.1, period=2) +rainbow = adafruit_led_animation.animation.animation.rainbow.Rainbow( + pixels, speed=0.1, period=2 +) sparkle_pulse = adafruit_led_animation.animation.animation.sparklepulse.SparklePulse( pixels, speed=0.1, period=3, color=JADE ) From cbfa114e7d104a6757d3ab749153d1b284a9c8c2 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Sun, 17 May 2020 15:52:51 -0400 Subject: [PATCH 5/6] Sphinx and example updates to match API. --- .../animation/rainbowsparkle.py | 2 + .../animation/sparklepulse.py | 4 +- docs/api.rst | 21 ++++---- docs/conf.py | 2 +- examples/led_animation_all_animations.py | 54 ++++++++++--------- examples/led_animation_gridmap.py | 25 +++++---- examples/led_animation_simpletest.py | 7 +-- 7 files changed, 60 insertions(+), 55 deletions(-) diff --git a/adafruit_led_animation/animation/rainbowsparkle.py b/adafruit_led_animation/animation/rainbowsparkle.py index c71e799..c6be5e0 100644 --- a/adafruit_led_animation/animation/rainbowsparkle.py +++ b/adafruit_led_animation/animation/rainbowsparkle.py @@ -53,6 +53,8 @@ class RainbowSparkle(Rainbow): :param pixel_object: The initialised LED object. :param float speed: Animation refresh rate in seconds, e.g. ``0.1``. :param float period: Period to cycle the rainbow over in seconds. Default 5. + :param int num_sparkles: The number of sparkles to display. Defaults to 1/20 of the pixel + object length. :param float step: Color wheel step. Default 1. :param str name: Name of animation (optional, useful for sequences and debugging). :param float background_brightness: The brightness of the background rainbow. Defaults to diff --git a/adafruit_led_animation/animation/sparklepulse.py b/adafruit_led_animation/animation/sparklepulse.py index 1c7e3b4..26ab1e9 100644 --- a/adafruit_led_animation/animation/sparklepulse.py +++ b/adafruit_led_animation/animation/sparklepulse.py @@ -21,10 +21,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """ -`adafruit_led_animation.animation.sparklepluse` +`adafruit_led_animation.animation.sparklepulse` ================================================================================ -Sparklepulse animation for CircuitPython helper library for LED animations. +Sparkle-pulse animation for CircuitPython helper library for LED animations. * Author(s): Roy Hooper, dmolavi diff --git a/docs/api.rst b/docs/api.rst index 041b153..b4aa897 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,7 +4,7 @@ .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" -.. automodule:: adafruit_led_animation.animation.animation +.. automodule:: adafruit_led_animation.animation :members: .. automodule:: adafruit_led_animation.color @@ -19,40 +19,37 @@ .. automodule:: adafruit_led_animation.sequence :members: -.. automodule:: adafruit_led_animation.animation.rainbow +.. automodule:: adafruit_led_animation.animation.blink :members: -.. automodule:: adafruit_led_animation.animation.sparkle +.. automodule:: adafruit_led_animation.animation.solid :members: -.. automodule:: adafruit_led_animation.animation.blink +.. automodule:: adafruit_led_animation.animation.colorcycle :members: .. automodule:: adafruit_led_animation.animation.chase :members: -.. automodule:: adafruit_led_animation.animation.colorcycle - :members: - .. automodule:: adafruit_led_animation.animation.comet :members: .. automodule:: adafruit_led_animation.animation.pulse :members: -.. automodule:: adafruit_led_animation.animation.rainbowchase +.. automodule:: adafruit_led_animation.animation.rainbow :members: -.. automodule:: adafruit_led_animation.animation.rainbowcomet +.. automodule:: adafruit_led_animation.animation.sparkle :members: -.. automodule:: adafruit_led_animation.animation.rainbowsparkle +.. automodule:: adafruit_led_animation.animation.rainbowchase :members: -.. automodule:: adafruit_led_animation.animation.solid +.. automodule:: adafruit_led_animation.animation.rainbowcomet :members: -.. automodule:: adafruit_led_animation.animation.sparkle +.. automodule:: adafruit_led_animation.animation.rainbowsparkle :members: .. automodule:: adafruit_led_animation.animation.sparklepulse diff --git a/docs/conf.py b/docs/conf.py index d34ea33..fec636b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,7 @@ # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = ["adafruit_led_animation", "adafruit_led_animation.animation"] +autodoc_mock_imports = [] intersphinx_mapping = { diff --git a/examples/led_animation_all_animations.py b/examples/led_animation_all_animations.py index dc859b5..95f0d76 100644 --- a/examples/led_animation_all_animations.py +++ b/examples/led_animation_all_animations.py @@ -9,11 +9,20 @@ import board import neopixel -import adafruit_led_animation.animation.blink -import adafruit_led_animation.animation.sparklepulse -from adafruit_led_animation import animation +import adafruit_led_animation.animation.blink as blink_animation +import adafruit_led_animation.animation.sparklepulse as sparklepulse_animation +import adafruit_led_animation.animation.comet as comet_animation +import adafruit_led_animation.animation.chase as chase_animation +import adafruit_led_animation.animation.pulse as pulse_animation +import adafruit_led_animation.animation.sparkle as sparkle_animation +import adafruit_led_animation.animation.rainbowchase as rainbowchase_animation +import adafruit_led_animation.animation.rainbowsparkle as rainbowsparkle_animation +import adafruit_led_animation.animation.rainbowcomet as rainbowcomet_animation +import adafruit_led_animation.animation.solid as solid_animation +import adafruit_led_animation.animation.colorcycle as colorcycle_animation +import adafruit_led_animation.animation.rainbow as rainbow_animation from adafruit_led_animation.sequence import AnimationSequence -from adafruit_led_animation.color import PURPLE, WHITE, AMBER, JADE +from adafruit_led_animation.color import PURPLE, WHITE, AMBER, JADE, MAGENTA, ORANGE # Update to match the pin connected to your NeoPixels pixel_pin = board.D6 @@ -22,40 +31,33 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) -blink = adafruit_led_animation.animation.animation.blink.Blink( - pixels, speed=0.5, color=JADE -) -comet = animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) -chase = animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) -pulse = animation.Pulse(pixels, speed=0.1, period=3, color=AMBER) -sparkle = adafruit_led_animation.animation.animation.sparkle.Sparkle( - pixels, speed=0.1, color=PURPLE, num_sparkles=10 -) -solid = adafruit_led_animation.animation.animation.solid.Solid(pixels, color=JADE) -rainbow = adafruit_led_animation.animation.animation.rainbow.Rainbow( - pixels, speed=0.1, period=2 -) -sparkle_pulse = adafruit_led_animation.animation.animation.sparklepulse.SparklePulse( - pixels, speed=0.1, period=3, color=JADE -) -rainbow_comet = adafruit_led_animation.animation.animation.rainbowcomet.RainbowComet( - pixels, speed=0.1, tail_length=7, bounce=True -) -rainbow_chase = adafruit_led_animation.animation.animation.rainbowchase.RainbowChase( +blink = blink_animation.Blink(pixels, speed=0.5, color=JADE) +colorcycle = colorcycle_animation.ColorCycle(pixels, speed=0.4, colors=[MAGENTA, ORANGE]) +comet = comet_animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) +chase = chase_animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) +pulse = pulse_animation.Pulse(pixels, speed=0.1, period=3, color=AMBER) +sparkle = sparkle_animation.Sparkle(pixels, speed=0.1, color=PURPLE, num_sparkles=10) +solid = solid_animation.Solid(pixels, color=JADE) +rainbow = rainbow_animation.Rainbow(pixels, speed=0.1, period=2) +sparkle_pulse = sparklepulse_animation.SparklePulse(pixels, speed=0.1, period=3, color=JADE) +rainbow_comet = rainbowcomet_animation.RainbowComet(pixels, speed=0.1, tail_length=7, bounce=True) +rainbow_chase = rainbowchase_animation.RainbowChase( pixels, speed=0.1, size=3, spacing=2, wheel_step=8 ) +rainbow_sparkle = rainbowsparkle_animation.RainbowSparkle(pixels, speed=0.1, num_sparkles=15) animations = AnimationSequence( comet, blink, + rainbow_sparkle, chase, pulse, sparkle, - solid, rainbow, - sparkle_pulse, + solid, rainbow_comet, + sparkle_pulse, rainbow_chase, advance_interval=5, auto_clear=True, diff --git a/examples/led_animation_gridmap.py b/examples/led_animation_gridmap.py index 336c5a2..e6ed72d 100644 --- a/examples/led_animation_gridmap.py +++ b/examples/led_animation_gridmap.py @@ -10,9 +10,12 @@ import board import neopixel -import adafruit_led_animation.animation.rainbow -import adafruit_led_animation.sequence -from adafruit_led_animation import animation +import adafruit_led_animation.animation.comet as comet_animation +import adafruit_led_animation.animation.rainbowcomet as rainbowcomet_animation +import adafruit_led_animation.animation.rainbowchase as rainbowchase_animation +import adafruit_led_animation.animation.chase as chase_animation +import adafruit_led_animation.animation.rainbow as rainbow_animation +from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation import helper from adafruit_led_animation.color import PURPLE, JADE, AMBER @@ -26,29 +29,29 @@ pixels, 8, 4, helper.horizontal_strip_gridmap(8, alternating=False) ) -comet_h = animation.Comet( +comet_h = comet_animation.Comet( pixel_wing_horizontal, speed=0.1, color=PURPLE, tail_length=3, bounce=True ) -comet_v = animation.Comet( +comet_v = comet_animation.Comet( pixel_wing_vertical, speed=0.1, color=AMBER, tail_length=6, bounce=True ) -chase_h = animation.Chase( +chase_h = chase_animation.Chase( pixel_wing_horizontal, speed=0.1, size=3, spacing=6, color=JADE ) -rainbow_chase_v = adafruit_led_animation.animation.animation.rainbowchase.RainbowChase( +rainbow_chase_v = rainbowchase_animation.RainbowChase( pixel_wing_vertical, speed=0.1, size=3, spacing=2, wheel_step=8 ) -rainbow_comet_v = adafruit_led_animation.animation.animation.rainbowcomet.RainbowComet( +rainbow_comet_v = rainbowcomet_animation.RainbowComet( pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True ) -rainbow_v = adafruit_led_animation.animation.animation.rainbow.Rainbow( +rainbow_v = rainbow_animation.Rainbow( pixel_wing_vertical, speed=0.1, period=2 ) -rainbow_chase_h = adafruit_led_animation.animation.animation.rainbowchase.RainbowChase( +rainbow_chase_h = rainbowchase_animation.RainbowChase( pixel_wing_horizontal, speed=0.1, size=3, spacing=3 ) -animations = adafruit_led_animation.sequence.AnimationSequence( +animations = AnimationSequence( rainbow_v, comet_h, rainbow_comet_v, diff --git a/examples/led_animation_simpletest.py b/examples/led_animation_simpletest.py index bb53d95..b363b26 100644 --- a/examples/led_animation_simpletest.py +++ b/examples/led_animation_simpletest.py @@ -9,7 +9,8 @@ """ import board import neopixel -from adafruit_led_animation.animation import Comet, Chase +import adafruit_led_animation.animation.comet as comet_animation +import adafruit_led_animation.animation.chase as chase_animation from adafruit_led_animation.sequence import AnimationSequence from adafruit_led_animation.color import PURPLE, WHITE @@ -20,8 +21,8 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) -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) +comet = comet_animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) +chase = chase_animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) animations = AnimationSequence(comet, chase, advance_interval=5) From 726850708d1e898d2522b7b2093fafac0cde17c1 Mon Sep 17 00:00:00 2001 From: Kattni Rembor Date: Sun, 17 May 2020 16:09:21 -0400 Subject: [PATCH 6/6] Black. --- examples/led_animation_all_animations.py | 20 +++++++++++++++----- examples/led_animation_gridmap.py | 4 +--- examples/led_animation_simpletest.py | 4 +++- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/examples/led_animation_all_animations.py b/examples/led_animation_all_animations.py index 95f0d76..954ff69 100644 --- a/examples/led_animation_all_animations.py +++ b/examples/led_animation_all_animations.py @@ -32,19 +32,29 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) blink = blink_animation.Blink(pixels, speed=0.5, color=JADE) -colorcycle = colorcycle_animation.ColorCycle(pixels, speed=0.4, colors=[MAGENTA, ORANGE]) -comet = comet_animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) +colorcycle = colorcycle_animation.ColorCycle( + pixels, speed=0.4, colors=[MAGENTA, ORANGE] +) +comet = comet_animation.Comet( + pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True +) chase = chase_animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) pulse = pulse_animation.Pulse(pixels, speed=0.1, period=3, color=AMBER) sparkle = sparkle_animation.Sparkle(pixels, speed=0.1, color=PURPLE, num_sparkles=10) solid = solid_animation.Solid(pixels, color=JADE) rainbow = rainbow_animation.Rainbow(pixels, speed=0.1, period=2) -sparkle_pulse = sparklepulse_animation.SparklePulse(pixels, speed=0.1, period=3, color=JADE) -rainbow_comet = rainbowcomet_animation.RainbowComet(pixels, speed=0.1, tail_length=7, bounce=True) +sparkle_pulse = sparklepulse_animation.SparklePulse( + pixels, speed=0.1, period=3, color=JADE +) +rainbow_comet = rainbowcomet_animation.RainbowComet( + pixels, speed=0.1, tail_length=7, bounce=True +) rainbow_chase = rainbowchase_animation.RainbowChase( pixels, speed=0.1, size=3, spacing=2, wheel_step=8 ) -rainbow_sparkle = rainbowsparkle_animation.RainbowSparkle(pixels, speed=0.1, num_sparkles=15) +rainbow_sparkle = rainbowsparkle_animation.RainbowSparkle( + pixels, speed=0.1, num_sparkles=15 +) animations = AnimationSequence( diff --git a/examples/led_animation_gridmap.py b/examples/led_animation_gridmap.py index e6ed72d..d696751 100644 --- a/examples/led_animation_gridmap.py +++ b/examples/led_animation_gridmap.py @@ -44,9 +44,7 @@ rainbow_comet_v = rainbowcomet_animation.RainbowComet( pixel_wing_vertical, speed=0.1, tail_length=7, bounce=True ) -rainbow_v = rainbow_animation.Rainbow( - pixel_wing_vertical, speed=0.1, period=2 -) +rainbow_v = rainbow_animation.Rainbow(pixel_wing_vertical, speed=0.1, period=2) rainbow_chase_h = rainbowchase_animation.RainbowChase( pixel_wing_horizontal, speed=0.1, size=3, spacing=3 ) diff --git a/examples/led_animation_simpletest.py b/examples/led_animation_simpletest.py index b363b26..686b7f8 100644 --- a/examples/led_animation_simpletest.py +++ b/examples/led_animation_simpletest.py @@ -21,7 +21,9 @@ pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.2, auto_write=False) -comet = comet_animation.Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True) +comet = comet_animation.Comet( + pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True +) chase = chase_animation.Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE) animations = AnimationSequence(comet, chase, advance_interval=5)