diff --git a/boards/PIMORONI_TINYFX/uf2-manifest.txt b/boards/PIMORONI_TINYFX/uf2-manifest.txt index 5f55736..43d7153 100644 --- a/boards/PIMORONI_TINYFX/uf2-manifest.txt +++ b/boards/PIMORONI_TINYFX/uf2-manifest.txt @@ -1,6 +1,8 @@ main.py examples/*.py examples/effects/*.py +examples/effects/mono/*.py +examples/effects/colour/*.py examples/showcase/*.py lib/*.py lib/picofx/*.py diff --git a/examples/tiny_fx/README.md b/examples/tiny_fx/README.md index 57cfe0d..80ebd3b 100644 --- a/examples/tiny_fx/README.md +++ b/examples/tiny_fx/README.md @@ -3,16 +3,24 @@ These are micropython examples for the Pimoroni [TinyFX](https://shop.pimoroni.com/products/tiny_fx), a stamp-sized light and sound effects controller board for model making, construction kits, and dioramas. - [Function Examples](#function-examples) -- [Effect Examples](#effect-examples) +- [Mono Effect Examples](#mono-effect-examples) - [Single Blink](#single-blink) - - [Blink Wave](#blink-wave) - - [Binary Counter](#binary-counter) + - [Single Flashing](#single-flashing) + - [Single Flicker](#single-flicker) - [Single Pulse](#single-pulse) + - [Single Random](#single-random) + - [Blink Wave](#blink-wave) + - [Flashing Sequence](#flashing-sequence) - [Pulse Wave](#pulse-wave) + - [Binary Counter](#binary-counter) - [Traffic Light](#traffic-light) - - [Wave Sequence](#wave-sequence) +- [Colour Effect Examples](#colour-effect-examples) + - [Rainbow](#rainbow) + - [Random](#random) + - [Hue Step](#hue-step) - [Audio Examples](#audio-examples) - [Showcase Examples](#showcase-examples) + - [Rescue Vehicle](#rescue-vehicle) - [Ship Thrusters](#ship-thrusters) - [Space Tales](#space-tales) - [Space Tales with PIR Sensor](#space-tales-with-pir-sensor) @@ -22,48 +30,86 @@ These are micropython examples for the Pimoroni [TinyFX](https://shop.pimoroni.c -## Effect Examples +## Mono Effect Examples ### Single Blink -[effects/single_blink.py](effects/single_blink.py) +[effects/mono/single_blink.py](effects/mono/single_blink.py) Play a blinking effect on one of TinyFX's outputs. -### Blink Wave -[effects/blink_wave.py](effects/blink_wave.py) +### Single Flashing +[effects/mono/single_flashing.py](effects/mono/single_flashing.py) -Play a wave of blinks on TinyFX's outputs. +Play a flashing effect on one of TinyFX's outputs. -### Binary Counter -[effects/binary_counter.py](effects/binary_counter.py) +### Single Flicker +[effects/mono/single_flicker.py](effects/mono/single_flicker.py) -Play an incrementing binary counter on TinyFX's outputs. +Play a flickering effect on one of TinyFX's outputs. ### Single Pulse -[effects/single_pulse.py](effects/single_pulse.py) +[effects/mono/single_pulse.py](effects/mono/single_pulse.py) Play a pulsing effect on one of TinyFX's outputs. +### Single Random +[effects/mono/single_random.py](effects/mono/single_random.py) + +Play a randomly changing brightness effect on one of TinyFX's outputs. + + +### Blink Wave +[effects/mono/blink_wave.py](effects/mono/blink_wave.py) + +Play a wave of blinks on TinyFX's outputs. + + +### Flashing Sequence +[effects/mono/flashing_sequence.py](effects/mono/flashing_sequence.py) + +Play a flashing sequence across TinyFX's outputs. + + ### Pulse Wave -[effects/pulse_wave.py](effects/pulse_wave.py) +[effects/mono/pulse_wave.py](effects/mono/pulse_wave.py) Play a wave of pulses on TinyFX's outputs. +### Binary Counter +[effects/binary_counter.py](effects/binary_counter.py) + +Play an incrementing binary counter on TinyFX's outputs. + + ### Traffic Light -[effects/traffic_light.py](effects/traffic_light.py) +[effects/mono/traffic_light.py](effects/mono/traffic_light.py) Play a traffic light sequence on TinyFX's outputs. -### Wave Sequence -[effects/wave.py](effects/wave.py) +## Colour Effect Examples + +### Rainbow +[effects/colour/rainbow.py](effects/colour/rainbow.py) -Read Yukon's onboard Buttons. +Play a rainbow effect on TinyFX's RGB output. + + +### Random +[effects/colour/random.py](effects/colour/random.py) + +Play a randomly changing brightness and colour effect on TinyFX's RGB output. + + +### Hue Step +[effects/colour/hue_step.py](effects/colour/hue_step.py) + +Play a stepped hue effect on TinyFX's RGB output. ## Audio Examples @@ -72,6 +118,12 @@ Read Yukon's onboard Buttons. ## Showcase Examples +### Rescue Vehicle +[showcase/rescue_vehicle.py](showcase/rescue_vehicle.py) + +Play an alternating flashing sequence on two of TinyFX's outputs, recreating the effect of rescue vehicle beacons. The other outputs are static for illuminated head and tail lights. + + ### Ship Thrusters [showcase/ship_thrusters.py](showcase/ship_thrusters.py) @@ -87,5 +139,4 @@ Play effects for each space themed "postcard". ### Space Tales with PIR Sensor [showcase/space_tales_pir.py](showcase/space_tales_with_pir.py) -Play effects for each space themed "postcard" when someone walks past. -A PIR sensor is used to activate the effect, which will turn off after a certain time. +Play effects for each space themed "postcard" when someone walks past. A PIR sensor is used to activate the effect, which will turn off after a certain time. diff --git a/examples/tiny_fx/examples/effects/colour/hue_step.py b/examples/tiny_fx/examples/effects/colour/hue_step.py new file mode 100644 index 0000000..753a680 --- /dev/null +++ b/examples/tiny_fx/examples/effects/colour/hue_step.py @@ -0,0 +1,35 @@ +from tiny_fx import TinyFX +from picofx import ColourPlayer +from picofx.colour import HueStepFX + +""" +Play a stepped hue effect on TinyFX's RGB output. + +Press "Boot" to exit the program. +""" + +# Variables +tiny = TinyFX() # Create a new TinyFX object to interact with the board +player = ColourPlayer(tiny.rgb) # Create a new effect player to control TinyFX's RGB output + + +# Create and set up a rainbow effect to play +player.effects = HueStepFX(interval=1.0, # The time (in seconds) between each hue step + hue=0.0, # The hue of the colour to start at (from 0.0 to 1.0) + sat=1.0, # The saturation/intensity of the colour (from 0.0 to 1.0) + val=1.0, # The value/brightness of the colour (from 0.0 to 1.0) + steps=6) # The number of steps to take around the colour wheel + + +# Wrap the code in a try block, to catch any exceptions (including KeyboardInterrupt) +try: + player.start() # Start the effects running + + # Loop until the effect stops or the "Boot" button is pressed + while player.is_running() and not tiny.boot_pressed(): + pass + +# Stop any running effects and turn off all the outputs +finally: + player.stop() + tiny.clear() diff --git a/examples/tiny_fx/examples/effects/colour/random_colour.py b/examples/tiny_fx/examples/effects/colour/random.py similarity index 100% rename from examples/tiny_fx/examples/effects/colour/random_colour.py rename to examples/tiny_fx/examples/effects/colour/random.py diff --git a/picofx/__init__.py b/picofx/__init__.py index 732d9ad..d72ef2b 100644 --- a/picofx/__init__.py +++ b/picofx/__init__.py @@ -68,8 +68,8 @@ def set_hsv(self, h, s, v): class Updateable: - def __init__(self, speed): - self.speed = speed + def __init__(self): + pass def tick(self, delta_ms): pass @@ -80,7 +80,7 @@ def reset(self): class Cycling(Updateable): def __init__(self, speed): - super().__init__(speed) + self.speed = speed self.__offset_ms = 0 self.__offset = 0 diff --git a/picofx/colour/__init__.py b/picofx/colour/__init__.py index 2b83a48..58bdaaa 100644 --- a/picofx/colour/__init__.py +++ b/picofx/colour/__init__.py @@ -4,10 +4,12 @@ from .colour import RGBFX, HSVFX from .rainbow import RainbowFX, RainbowWaveFX +from .step import HueStepFX COLOUR_EFFECTS = [ RGBFX, HSVFX, RainbowFX, - RainbowWaveFX + RainbowWaveFX, + HueStepFX ] diff --git a/picofx/colour/step.py b/picofx/colour/step.py new file mode 100644 index 0000000..f6045d6 --- /dev/null +++ b/picofx/colour/step.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2024 Christopher Parrott for Pimoroni Ltd +# +# SPDX-License-Identifier: MIT + +from picofx import Updateable, rgb_from_hsv + + +class HueStepFX(Updateable): + def __init__(self, interval=1.0, hue=0.0, sat=1.0, val=1.0, steps=6): + self.interval = interval + self.start_hue = hue + self.sat = sat + self.val = val + self.__steps = steps + self.__current_step = 0 + self.__time = 0 + + def __call__(self): + hue = (self.start_hue + (self.__current_step / self.__steps)) % 1.0 + r, g, b = rgb_from_hsv(hue, self.sat, self.val) + return int(r * 255), int(g * 255), int(b * 255) + + def tick(self, delta_ms): + self.__time += delta_ms + + # Check if the dim duration has elapsed + if self.__time >= (self.interval * 1000): + self.__time -= (self.interval * 1000) + + self.__current_step = (self.__current_step + 1) % self.__steps diff --git a/picofx/mono/binary.py b/picofx/mono/binary.py index 23dcd62..d885092 100644 --- a/picofx/mono/binary.py +++ b/picofx/mono/binary.py @@ -6,7 +6,6 @@ class BinaryCounterFX(Updateable): - def __init__(self, interval=0.1, count=0, step=1): self.interval = interval self.counter = count