Adding files for Halo Energy Sword guide

adding code.py and sounds for halo energy sword guide
This commit is contained in:
Noe Ruiz 2024-05-14 08:07:34 -04:00
parent 443285e716
commit d24ca791c5
11 changed files with 215 additions and 0 deletions

215
Halo_Energy_Sword/code.py Normal file
View file

@ -0,0 +1,215 @@
# SPDX-FileCopyrightText: 2019 Kattni Rembor for Adafruit Industries
# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
RP2040 Prop-Maker Feather Energy Sword
Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!
Written by Kattni Rembor & 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 random
import digitalio
import audiocore
import audiobusio
import board
import neopixel
import adafruit_lis3dh
# CUSTOMISE COLORS HERE:
COLOR = (0, 120, 120) # Default idle is light blue
ALT_COLOR = (255, 0, 250) # hit color is purple
# CUSTOMISE IDLE PULSE SPEED HERE: 0 is fast, above 0 slows down
IDLE_PULSE_SPEED = 0 # Default is 0 seconds
SWING_BLAST_SPEED = 0.0007
# CUSTOMISE BRIGHTNESS HERE: must be a number between 0 and 1
IDLE_PULSE_BRIGHTNESS_MIN = 0.2 # Default minimum idle pulse brightness
IDLE_PULSE_BRIGHTNESS_MAX = 1 # Default maximum idle pulse brightness
# CUSTOMISE SENSITIVITY HERE: smaller numbers = more sensitive to motion
HIT_THRESHOLD = 250
SWING_THRESHOLD = 150
# Set to the length in seconds of the "on.wav" file
POWER_ON_SOUND_DURATION = 1.7
NUM_PIXELS = 73 # Number of pixels used in project
NEOPIXEL_PIN = board.EXTERNAL_NEOPIXELS
enable = digitalio.DigitalInOut(board.EXTERNAL_POWER)
enable.direction = digitalio.Direction.OUTPUT
enable.value = True
strip = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_PIXELS, brightness=1, auto_write=False)
strip.fill(0) # NeoPixels off ASAP on startup
strip.show()
# i2s audio
audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA)
wave_file = None
# Set up accelerometer on I2C bus, 4G range:
i2c = board.I2C() # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
accel = adafruit_lis3dh.LIS3DH_I2C(i2c)
accel.range = adafruit_lis3dh.RANGE_4_G
COLOR_IDLE = COLOR # 'idle' color is the default
COLOR_HIT = ALT_COLOR # "hit" color is ALT_COLOR set above
COLOR_SWING = (255, 255, 255) # "swing" color white
def play_wav(name, loop=False):
"""
Play a WAV file in the 'sounds' directory.
:param name: partial file name string, complete name will be built around
this, e.g. passing 'foo' will play file 'sounds/foo.wav'.
:param loop: if True, sound will repeat indefinitely (until interrupted
by another sound).
"""
global wave_file # pylint: disable=global-statement
print("playing", name)
if wave_file:
wave_file.close()
try:
wave_file = open('sounds/' + name + '.wav', 'rb')
wave = audiocore.WaveFile(wave_file)
audio.play(wave, loop=loop)
except OSError:
pass # we'll just skip playing then
def power_on(sound, duration):
"""
Animate NeoPixels with accompanying sound effect for power on.
:param sound: sound name (similar format to play_wav() above)
:param duration: estimated duration of sound, in seconds (>0.0)
"""
prev = 0
start_time = time.monotonic() # Save audio start time
play_wav(sound)
while True:
elapsed = time.monotonic() - start_time # Time spent playing sound
if elapsed > duration: # Past sound duration?
break # Stop animating
animation_time = elapsed / duration # Animation time, 0.0 to 1.0
threshold = int(NUM_PIXELS * animation_time + 0.5)
num = threshold - prev # Number of pixels to light on this pass
if num != 0:
strip[prev:threshold] = [ALT_COLOR] * num
strip.show()
prev = threshold
def mix(color_1, color_2, weight_2):
"""
Blend between two colors with a given ratio.
:param color_1: first color, as an (r,g,b) tuple
:param color_2: second color, as an (r,g,b) tuple
:param weight_2: Blend weight (ratio) of second color, 0.0 to 1.0
:return (r,g,b) tuple, blended color
"""
if weight_2 < 0.0:
weight_2 = 0.0
elif weight_2 > 1.0:
weight_2 = 1.0
weight_1 = 1.0 - weight_2
return (int(color_1[0] * weight_1 + color_2[0] * weight_2),
int(color_1[1] * weight_1 + color_2[1] * weight_2),
int(color_1[2] * weight_1 + color_2[2] * weight_2))
# List of swing wav files without the .wav in the name for use with play_wav()
swing_sounds = [
'swing1',
'swing2',
'swing3',
'swing4',
]
# List of hit wav files without the .wav in the name for use with play_wav()
hit_sounds = [
'hit1',
'hit2',
'hit3',
'hit4',
]
mode = 0 # Initial mode = OFF
# Setup idle pulse
idle_brightness = IDLE_PULSE_BRIGHTNESS_MIN # current brightness of idle pulse
idle_increment = 0.01 # Initial idle pulse direction
# Main loop
while True:
if mode == 0: # If currently off...
enable.value = True
power_on('on', POWER_ON_SOUND_DURATION) # Power up!
play_wav('idle', loop=True) # Play idle sound now
mode = 1 # Idle mode
# Setup for idle pulse
idle_brightness = IDLE_PULSE_BRIGHTNESS_MIN
idle_increment = 0.01
strip.fill([int(c*idle_brightness) for c in COLOR])
strip.show()
elif mode >= 1: # If not OFF mode...
x, y, z = accel.acceleration # Read accelerometer
accel_total = x * x + z * z
# (Y axis isn't needed, due to the orientation that the Prop-Maker
# Wing is mounted. Also, square root isn't needed, since we're
# comparing thresholds...use squared values instead.)
if accel_total > HIT_THRESHOLD: # Large acceleration = HIT
TRIGGER_TIME = time.monotonic() # Save initial time of hit
play_wav(random.choice(hit_sounds)) # Start playing 'hit' sound
COLOR_ACTIVE = COLOR_HIT # Set color to fade from
mode = 3 # HIT mode
elif mode == 1 and accel_total > SWING_THRESHOLD: # Mild = SWING
TRIGGER_TIME = time.monotonic() # Save initial time of swing
play_wav(random.choice(swing_sounds)) # Randomly choose from available swing sounds
# make a larson scanner animation_time
strip_backup = strip[0:-1]
for p in range(-1, len(strip)):
for i in range (p-1, p+2): # shoot a 'ray' of 3 pixels
if 0 <= i < len(strip):
strip[i] = COLOR_SWING
strip.show()
time.sleep(SWING_BLAST_SPEED)
if 0 <= (p-1) < len(strip):
strip[p-1] = strip_backup[p-1] # restore previous color at the tail
strip.show()
while audio.playing:
pass # wait till we're done
mode = 2 # we'll go back to idle mode
elif mode == 1:
# Idle pulse
idle_brightness += idle_increment # Pulse up
if idle_brightness > IDLE_PULSE_BRIGHTNESS_MAX or \
idle_brightness < IDLE_PULSE_BRIGHTNESS_MIN: # Then...
idle_increment *= -1 # Pulse direction flip
strip.fill([int(c*idle_brightness) for c in COLOR_IDLE])
strip.show()
time.sleep(IDLE_PULSE_SPEED) # Idle pulse speed set above
elif mode > 1: # If in SWING or HIT mode...
if audio.playing: # And sound currently playing...
blend = time.monotonic() - TRIGGER_TIME # Time since triggered
if mode == 2: # If SWING,
blend = abs(0.5 - blend) * 2.0 # ramp up, down
strip.fill(mix(COLOR_ACTIVE, COLOR, blend)) # Fade from hit/swing to base color
strip.show()
else: # No sound now, but still SWING or HIT modes
play_wav('idle', loop=True) # Resume idle sound
mode = 1 # Return to idle mode

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.