Adafruit_Learning_System_Gu.../Glowing_Bottle_Castle/code.py
2022-02-22 14:21:18 -05:00

226 lines
6.6 KiB
Python
Executable file

# SPDX-FileCopyrightText: 2020 Erin St Blaine for Adafruit Industries
# SPDX-FileCopyrightText: 2020 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Bottle Piano with Capacitive Touch
Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!
Written by Melissa LeBlanc, Erin St Blaine & Limor Fried for Adafruit Industries
Copyright (c) 2019-2020 Adafruit Industries
Licensed under the MIT license.
All text above must be included in any redistribution.
"""
import time
import digitalio
import board
import neopixel
import busio
import adafruit_mpr121
from audiocore import WaveFile
from audiopwmio import PWMAudioOut as AudioOut
from adafruit_led_animation.animation.rainbow import Rainbow
from adafruit_led_animation.animation.rainbowchase import RainbowChase
from adafruit_led_animation.animation.chase import Chase
from adafruit_led_animation.animation.rainbowcomet import RainbowComet
from adafruit_led_animation.sequence import AnimationSequence
from adafruit_led_animation.color import (
BLACK,
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
MAGENTA,
PURPLE,
AMBER,
TEAL,
)
from adafruit_debouncer import Debouncer
# pylint: disable=global-statement
# NeoPixel strip setup -- set your total number of pixels here -----------------
PIXEL_NUM = 200
pixel_pin = board.A1
pixels = neopixel.NeoPixel(pixel_pin, PIXEL_NUM, brightness=1, auto_write=False)
LAST_BUTTON = None
'''
Customize your light strip for individual notes. Each line represents a bottle.
Change the numbers to reflect the first and last pixel in each ring. You can also
change the colors assigned to each bottle here.
'''
bottle_lights = (
(0, 10, RED),
(15, 30, ORANGE),
(31, 52, AMBER),
(53, 72, YELLOW),
(77, 96, GREEN),
(98, 119, TEAL),
(120, 145, BLUE),
(150, 173, PURPLE),
(180, 200, MAGENTA),
)
# Cap touch board setup ------------------------------------------------------
i2c = busio.I2C(board.SCL, board.SDA)
mpr121 = adafruit_mpr121.MPR121(i2c)
# Demo MODE LED Animations ------------------------------------------------------
rainbow = Rainbow(pixels, speed=0, period=10, name="rainbow", step=1)
rainbow_chase = RainbowChase(pixels, speed=0, size=5, spacing=10)
chase = Chase(pixels, speed=0.1, color=RED, size=1, spacing=6)
rainbow_comet = RainbowComet(pixels, speed=0.01, tail_length=60, bounce=True)
# Animation Sequence Playlist -- rearrange to change the order of animations
animations = AnimationSequence(
rainbow_chase,
chase,
rainbow_comet,
auto_clear=True,
auto_reset=True,
)
def go_dark():
'''set all pixels to black'''
pixels.fill(BLACK)
pixels.show()
# Debouncer ------------------------------------------------------
buttons = [Debouncer(mpr121[i]) for i in range(12)]
# Audio Setup ------------------------------------------------------
spkr_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
spkr_enable.direction = digitalio.Direction.OUTPUT
spkr_enable.value = True
audio = AudioOut(board.SPEAKER)
tracks = (
WaveFile(open("sounds/F2.wav", "rb")), # 0
WaveFile(open("sounds/G2.wav", "rb")), # 1
WaveFile(open("sounds/A2.wav", "rb")), # 2
WaveFile(open("sounds/Bb2.wav", "rb")), # 3
WaveFile(open("sounds/C2.wav", "rb")), # 4
WaveFile(open("sounds/D3.wav", "rb")), # 5
WaveFile(open("sounds/E3.wav", "rb")), # 6
WaveFile(open("sounds/F3.wav", "rb")), # 7
WaveFile(open("sounds/F1.wav", "rb")), # 7
WaveFile(open("sounds/G1.wav", "rb")), # 8
WaveFile(open("sounds/A1.wav", "rb")), # 9
WaveFile(open("sounds/Bb1.wav", "rb")), # 10
WaveFile(open("sounds/C1.wav", "rb")), # 11
WaveFile(open("sounds/D2.wav", "rb")), # 12
WaveFile(open("sounds/E2.wav", "rb")), # 13
WaveFile(open("sounds/F2.wav", "rb")), # 13
)
# Add or change song track names here. They will play in the order listed.
demo_tracks = (
WaveFile(open("sounds/undersea.wav", "rb")),
WaveFile(open("sounds/tequila.wav", "rb")),
WaveFile(open("sounds/lion.wav", "rb")),
)
MODE = 0 # Initial mode = OFF
SONG = 0
def light_up(bottle):
'''light up the bottles'''
lights = bottle_lights[bottle]
for pixel_id in range(lights[0], lights[1]):
pixels[pixel_id] = lights[2]
def play_bottle(bottle_id, is_octave):
''' play audio tracks and light up bottles'''
global MODE
go_dark()
light_up(bottle_id)
if is_octave:
audio.play(tracks[bottle_id + 7]) # Start playing sound
light_up(8)
else:
audio.play(tracks[bottle_id]) # Start playing sound
pixels.show()
MODE = 2
def check_buttons(touched):
''' check to see if buttons have been pressed'''
global MODE, LAST_BUTTON
octave = touched[11]
off = touched[9]
if octave:
light_up(8)
for pad in range(1, 9):
if LAST_BUTTON is not None and not touched[LAST_BUTTON]:
LAST_BUTTON = None
if pad != LAST_BUTTON and touched[pad]:
LAST_BUTTON = pad
play_bottle(pad - 1, octave)
if off:
MODE = 9
go_dark()
if touched[10]:
go_dark()
audio.play(demo_tracks[SONG])
while audio.playing:
animations.animate()
MODE = 3
while True:
# Idle mode: Play a Rainbow animation when nothing's being touched
if MODE == 0:
pixels.brightness = 0.3 #rainbow mode is much brighter than the other modes, so adjust here
rainbow.animate()
for button in buttons:
button.update()
check_buttons(mpr121.touched_pins)
time.sleep(0.1)
for i in range(12):
if buttons[i].fell:
MODE = 1
# If not idle mode
if MODE >= 1:
pixels.brightness = 1
check_buttons(mpr121.touched_pins)
time.sleep(0.1)
if MODE == 2: # mode 2 is individual notes
if audio.playing:
pixels.show()
while audio.playing:
check_buttons(mpr121.touched_pins)
time.sleep(0.07)
else:
MODE = 0 # Return to idle mode
if MODE == 3:
SONG = SONG + 1
animations.next()
if SONG == 3:
MODE = 0
SONG = 0
else:
MODE = 0 # Return to idle mode
if MODE == 9: # MODE 9 is "off" mode, listening for a new button press to wake up.
# for button in buttons:
# button.update()
for i in range(12):
if buttons[i].fell:
MODE = 1