143 lines
4.8 KiB
Python
143 lines
4.8 KiB
Python
"""
|
|
Crystal Chandelier with Circuit Playground BlueFruit
|
|
Adafruit invests time and resources providing this open source code.
|
|
Please support Adafruit and open source hardware by purchasing
|
|
products from Adafruit!
|
|
Written by Erin St Blaine & Limor Fried for Adafruit Industries
|
|
Copyright (c) 2020-2021 Adafruit Industries
|
|
Licensed under the MIT license.
|
|
All text above must be included in any redistribution.
|
|
"""
|
|
|
|
# pylint: disable=import-error
|
|
# pylint: disable=no-member
|
|
import board
|
|
import digitalio
|
|
import rotaryio
|
|
import neopixel
|
|
from adafruit_circuitplayground import cp
|
|
|
|
from adafruit_led_animation.helper import PixelMap
|
|
from adafruit_led_animation.sequence import AnimationSequence
|
|
from adafruit_led_animation.group import AnimationGroup
|
|
from adafruit_led_animation.animation.rainbow import Rainbow
|
|
from adafruit_led_animation.animation.comet import Comet
|
|
from adafruit_led_animation.animation.solid import Solid
|
|
from adafruit_led_animation.color import (
|
|
BLACK,
|
|
PURPLE,
|
|
)
|
|
|
|
NEOPIXEL_PIN = board.A1 # NeoPixels connected here (crystals + rings)
|
|
NUM_PIXELS = 92 # Number of pixels in the crystals and rings
|
|
|
|
MIN_BRIGHTNESS = 1 # Minimum LED brightness as a percentage (0 to 100)
|
|
MAX_BRIGHTNESS = 25 # Maximum LED brighrness as a percentage (0 to 100)
|
|
MIN_FPS = 2 # Minimum animation speed in frames per second (>0)
|
|
MAX_FPS = 8 # Maximum animation speed in frames per second (>0)
|
|
|
|
# Set initial brightness and speed to center values
|
|
BRIGHTNESS = (MIN_BRIGHTNESS + MAX_BRIGHTNESS) // 2
|
|
FPS = (MIN_FPS + MAX_FPS) // 2
|
|
SPEED = 1 / FPS # Integer frames-per-second to seconds interval
|
|
LEVEL = BRIGHTNESS * 0.01 # Integer brightness percentage to 0.0-1.0 coeff.
|
|
|
|
button = digitalio.DigitalInOut(board.A5)
|
|
button.direction = digitalio.Direction.INPUT
|
|
button.pull = digitalio.Pull.UP
|
|
BUTTON_STATE = None
|
|
BUTTON_VALUE = None
|
|
|
|
PIXELS = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_PIXELS, brightness=LEVEL,
|
|
auto_write=False)
|
|
|
|
# NeoPixels off ASAP on startup
|
|
cp.pixels.fill(0) # Onboard pixels
|
|
cp.pixels.show()
|
|
PIXELS.fill(0) # NeoPixel strip
|
|
PIXELS.show()
|
|
|
|
ENCODER = rotaryio.IncrementalEncoder(board.A2, board.A3)
|
|
|
|
# PIXEL MAPS reorder pixels so animations run in different configs ---------
|
|
|
|
# Crystals Only
|
|
PIXEL_MAP_CRYSTALS = PixelMap(PIXELS, [
|
|
84, 85, 86, 87, 88, 89, 90, 91
|
|
], individual_pixels=True)
|
|
|
|
# Rings Only
|
|
PIXEL_MAP_RINGS = PixelMap(PIXELS, [
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
|
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
|
|
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
|
|
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83
|
|
], individual_pixels=True)
|
|
|
|
|
|
|
|
# LED ANIMATIONS -----------------------------------------------------------
|
|
|
|
RAINBOW = Rainbow(PIXEL_MAP_RINGS, speed=0.01, period=10, step=3)
|
|
CP_RAINBOW = Rainbow(cp.pixels, speed=0.01, period=10, step=3)
|
|
CRYSTAL_COMET = Comet(PIXEL_MAP_CRYSTALS, speed=SPEED, tail_length=8,
|
|
color=PURPLE, bounce=True)
|
|
DARK_RINGS = Solid(PIXELS, color=BLACK)
|
|
DARK_CPB = Solid(cp.pixels, color=BLACK)
|
|
DARK = AnimationGroup(
|
|
DARK_RINGS,
|
|
DARK_CPB,
|
|
)
|
|
|
|
# Animations Playlist, reorder as desired. AnimationGroups play at same time
|
|
ANIMATIONS = AnimationSequence(
|
|
AnimationGroup(
|
|
CRYSTAL_COMET,
|
|
RAINBOW,
|
|
CP_RAINBOW,
|
|
),
|
|
auto_clear=True,
|
|
auto_reset=True,
|
|
)
|
|
|
|
# MAIN LOOP ----------------------------------------------------------------
|
|
|
|
LAST_POSITION = ENCODER.position
|
|
MODE = 1
|
|
while True:
|
|
|
|
POSITION = ENCODER.position
|
|
if POSITION != LAST_POSITION:
|
|
MOVE = POSITION - LAST_POSITION
|
|
if cp.switch:
|
|
|
|
FPS = max(MIN_FPS, min(FPS + MOVE, MAX_FPS))
|
|
SPEED = 1.0 / FPS
|
|
CRYSTAL_COMET.speed = SPEED
|
|
#RAINBOW.speed = SPEED
|
|
#CP_RAINBOW.speed = SPEED
|
|
print("crystal speed = ", SPEED)
|
|
else:
|
|
BRIGHTNESS = max(MIN_BRIGHTNESS, min(BRIGHTNESS + MOVE,
|
|
MAX_BRIGHTNESS))
|
|
LEVEL = BRIGHTNESS * 0.1
|
|
if LEVEL > 2:
|
|
LEVEL = 2
|
|
cp.pixels.brightness = LEVEL/2
|
|
PIXEL_MAP_RINGS.brightness = LEVEL/2
|
|
PIXEL_MAP_CRYSTALS.brightness = LEVEL
|
|
print("ring brightness = ", LEVEL/2, "crystal brightness = ", LEVEL)
|
|
LAST_POSITION = POSITION
|
|
if not BUTTON_VALUE and BUTTON_STATE is None:
|
|
BUTTON_STATE = "pressed"
|
|
if BUTTON_VALUE and BUTTON_STATE == "pressed":
|
|
print("Button pressed.")
|
|
if MODE == 1:
|
|
MODE = 2
|
|
else:
|
|
MODE = 1
|
|
BUTTON_STATE = None
|
|
if MODE == 1:
|
|
ANIMATIONS.animate()
|
|
else:
|
|
DARK.animate()
|