/ Lucio_Blaster_2020 / code.py
code.py
1 # SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 # Lucio 2020 6 # Feather M4 + Propmaker + amps + lots of neopixels 7 import board 8 import busio 9 from digitalio import DigitalInOut, Direction, Pull 10 import audioio 11 import audiomixer 12 import audiomp3 13 import adafruit_lis3dh 14 import neopixel 15 from adafruit_led_animation.animation.solid import Solid 16 from adafruit_led_animation.animation.comet import Comet 17 from adafruit_led_animation.animation.pulse import Pulse 18 from adafruit_led_animation.helper import PixelSubset 19 from adafruit_led_animation.group import AnimationGroup 20 from adafruit_led_animation.color import RED, ORANGE, WHITE 21 22 ORANGE_DIM = 0x801400 # half value version 23 RED_DIM = 0x800000 24 25 # ---Set Volume Max Here--- 26 VOLUME_MULT = 0.65 # 1 = full volume, 0.1 is very quiet, 0 is muted 27 28 # ---SWITCH/BUTTON SETUP--- 29 mode_switch = DigitalInOut(board.D9) 30 mode_switch.switch_to_input(pull=Pull.UP) 31 mode_state = mode_switch.value 32 trig_button = DigitalInOut(board.A4) 33 trig_button.switch_to_input(pull=Pull.UP) 34 alt_button = DigitalInOut(board.A5) 35 alt_button.switch_to_input(pull=Pull.UP) 36 37 # ---ACCELEROMETER SETUP--- 38 # Set up accelerometer on I2C bus, 4G range: 39 i2c = busio.I2C(board.SCL, board.SDA) 40 int1 = DigitalInOut(board.D6) 41 accel = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1) 42 43 # ---SPEAKER SETUP--- 44 enable = DigitalInOut(board.D10) 45 enable.direction = Direction.OUTPUT 46 enable.value = True 47 # Set up speakers and mixer. Stereo files, where music has empty right channel, FX empty left 48 speaker = audioio.AudioOut(board.A0, right_channel=board.A1) 49 mixer = audiomixer.Mixer(channel_count=2, buffer_size=2304, sample_rate=22050) 50 51 # ---NEOPIXEL SETUP--- 52 pixel_pin = board.D5 53 pixel_num = 154 54 pixels = neopixel.NeoPixel( 55 pixel_pin, pixel_num, brightness=0.6, auto_write=False, pixel_order=neopixel.GRBW 56 ) 57 # ^ change pixel_order depending on RGB vs. RGBW pixels 58 59 60 # ---Pixel Map--- 61 # this is the physical order in which the strips are plugged 62 pixel_stripA = PixelSubset(pixels, 0, 18) # 18 pixel strip 63 pixel_stripB = PixelSubset(pixels, 18, 36) # 18 pixel strip 64 pixel_jewel = PixelSubset(pixels, 36, 43) # 7 pixel jewel 65 pixel_ringsAll = PixelSubset(pixels, 43, 151) # all of the rings 66 # or use rings individually: 67 # pixel_ringA = PixelSubset(pixels, 43, 59) # 16 pixel ring 68 # pixel_ringB = PixelSubset(pixels, 59, 75) # 16 pixel ring 69 # pixel_ringC = PixelSubset(pixels, 75, 91) # 16 pixel ring 70 # pixel_ringD = PixelSubset(pixels, 91, 151) # 60 pixel ring 71 72 # ---BPM--- 73 BPM = 128 74 BEAT = 60 / BPM # quarter note beat 75 b16TH = BEAT / 4 # 16TH note 76 b64TH = BEAT / 16 # sixty-fourth 77 78 # ---Anim Setup--- 79 # heal color mode 80 # Pulse 'speed' = smoothness 81 pulse_rings_m0 = Pulse(pixel_ringsAll, speed=0.01, color=ORANGE, period=BEAT) 82 pulse_jewel_m0 = Pulse(pixel_jewel, speed=0.01, color=ORANGE, period=BEAT) 83 comet_stripA_m0 = Comet( 84 pixel_stripA, speed=b64TH, color=ORANGE, tail_length=9, bounce=False 85 ) 86 comet_stripB_m0 = Comet( 87 pixel_stripB, speed=b64TH, color=ORANGE, tail_length=9, bounce=False 88 ) 89 90 # speed color mode 91 pulse_rings_m1 = Pulse(pixel_ringsAll, speed=0.02, color=RED, period=BEAT / 2) 92 pulse_jewel_m1 = Pulse(pixel_jewel, speed=0.02, color=RED, period=BEAT / 2) 93 comet_stripA_m1 = Comet( 94 pixel_stripA, speed=b64TH, color=RED, tail_length=9, bounce=False 95 ) 96 comet_stripB_m1 = Comet( 97 pixel_stripB, speed=b64TH, color=RED, tail_length=9, bounce=False 98 ) 99 100 solid_white = Solid(pixel_ringsAll, color=WHITE) 101 102 # ---Anim Modes--- 103 vu_strip_animations_mode0 = AnimationGroup(comet_stripA_m0, comet_stripB_m0, sync=True) 104 vu_strip_animations_mode1 = AnimationGroup(comet_stripA_m1, comet_stripB_m1, sync=True) 105 106 # ---Audio Setup--- 107 if mode_state: 108 BGM = "/lucio/bgmheal.mp3" 109 else: 110 BGM = "/lucio/bgmspeed.mp3" 111 sample0 = audiomp3.MP3Decoder(open(BGM, "rb")) 112 FX = "/lucio/shoot.mp3" 113 sample1 = audiomp3.MP3Decoder(open(FX, "rb")) 114 speaker.play(mixer) 115 mixer.voice[0].play(sample0, loop=True) 116 mixer.voice[0].level = 0.3 * VOLUME_MULT 117 mixer.voice[1].level = 0.7 * VOLUME_MULT 118 119 120 while True: 121 if mode_state: # heal mode on startup 122 vu_strip_animations_mode0.animate() 123 pulse_rings_m0.animate() 124 pulse_jewel_m0.animate() 125 else: # speed mode on startup 126 vu_strip_animations_mode1.animate() 127 pulse_rings_m1.animate() 128 pulse_jewel_m1.animate() 129 130 # Change modes 131 if mode_switch.value: 132 if mode_state == 0: # state has changed, toggle it 133 BGM = "/lucio/bgmheal.mp3" 134 sample0.file = open(BGM, "rb") 135 mixer.voice[0].play(sample0, loop=True) 136 vu_strip_animations_mode0.animate() 137 pulse_rings_m0.animate() 138 pulse_jewel_m0.animate() 139 mode_state = 1 140 else: 141 if mode_state == 1: 142 BGM = "/lucio/bgmspeed.mp3" 143 sample0.file = open(BGM, "rb") 144 mixer.voice[0].play(sample0, loop=True) 145 vu_strip_animations_mode1.animate() 146 pulse_rings_m1.animate() 147 pulse_jewel_m1.animate() 148 mode_state = 0 149 150 x, _, _ = accel.acceleration # get accelerometer values 151 152 if not mixer.voice[1].playing: 153 if not trig_button.value: # trigger squeezed 154 FX_sample = "/lucio/shoot.mp3" 155 sample1.file = open(FX_sample, "rb") 156 mixer.voice[1].play(sample1) 157 if mode_state: 158 solid_white.animate() 159 else: 160 solid_white.animate() 161 162 if not alt_button.value: # alt trigger squeezed 163 FX_sample = "/lucio/alt_shoot.mp3" 164 sample1.file = open(FX_sample, "rb") 165 mixer.voice[1].play(sample1) 166 if mode_state: 167 solid_white.animate() 168 else: 169 solid_white.animate() 170 171 if accel.acceleration.x > 8: # reload 172 FX_sample = "/lucio/reload.mp3" 173 sample1.file = open(FX_sample, "rb") 174 mixer.voice[1].play(sample1) 175 if mode_state: 176 solid_white.animate() 177 else: 178 solid_white.animate() 179 180 if accel.acceleration.x < -8: # Ultimate 181 FX_sample = "/lucio/ultimate.mp3" 182 sample1.file = open(FX_sample, "rb") 183 mixer.voice[1].play(sample1) 184 if mode_state: 185 solid_white.animate() 186 else: 187 solid_white.animate()