Hello All. I am very new to coding (my knowledge is limited to a class on C++ programming), and I decided to take on a project that requires a bit of coding know how. I am following Adafruit's instructions on how to build a Lightsaber using their FeatherWing and M4 boards, which uses a Python code to run it's instructions. As is, the code works well, but I want to edit a certain line.
As is, the code uses a folder with .wav audio files, and based on whatever function is happening on the accelerometer (nothing, on, off, hit, swing, etc..), the code plays one of those files. However, it is only set up to play one file per action. The original code for this section is:
The logic line I am wanting to follow is this: Action happens, sound is searched for, if that sound file with random number does not exist, run original code without random number, thus correct sound should play.
I have tried to look for tutorials online, but the basic ones don't really seem to put me on the same lines as I am wanting to do (as they tend to use simple examples to relay what the code does.) I'm not sure if the Try/ Except command will do what I want, or if I am wanting to run an If/else/elif command.
I am not wanting the code written for me, but any push in the right direction or guidance would help tremendously.
The full code (if anyone is interested) is from the Adafruit Prop-Maker Lightsaber website, and is:
As is, the code uses a folder with .wav audio files, and based on whatever function is happening on the accelerometer (nothing, on, off, hit, swing, etc..), the code plays one of those files. However, it is only set up to play one file per action. The original code for this section is:
''' 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). """ print("playing", name) try: wave_file = open('sounds/' + name + '.wav', 'rb') wave = audioio.WaveFile(wave_file) audio.play(wave, loop=loop) except: returnI am wanting to have multiple sounds per action, thus I figured that I could simply add a random number generator, and whenever an action is performed, it will add a random number from 1 to however many sound fonts I get, and thus every time an action is performed, it will play the random sound font. So far I edited the code to Import Random, and edited:
""" 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). """ print("playing", name) try: numbers = [1,2,3,4,5,6,7,8] value = random.choice(numbers) wave_file = open('sounds/' + name + value +'.wav', 'rb') wave = audioio.WaveFile(wave_file) audio.play(wave, loop=loop) except: returnI have not run this code yet to see if it works, as I haven't gotten the sound files yet. However, after looking at the sound fonts I intend to purchase, I find that different actions have a different amount of sound (16 swing, 8 hit, 2 off, 1 on, etc), so I can forsee even if I chose a limited number of these sounds to use, any sound that doesn't have the random number assigned to it will throw back an error. (ex, code looks for on3.wav, but only wav file for on is on.wav)
The logic line I am wanting to follow is this: Action happens, sound is searched for, if that sound file with random number does not exist, run original code without random number, thus correct sound should play.
I have tried to look for tutorials online, but the basic ones don't really seem to put me on the same lines as I am wanting to do (as they tend to use simple examples to relay what the code does.) I'm not sure if the Try/ Except command will do what I want, or if I am wanting to run an If/else/elif command.
I am not wanting the code written for me, but any push in the right direction or guidance would help tremendously.
The full code (if anyone is interested) is from the Adafruit Prop-Maker Lightsaber website, and is:
"""LASER SWORD (pew pew) example for Adafruit Hallowing & NeoPixel strip""" # pylint: disable=bare-except import time import math import gc from digitalio import DigitalInOut, Direction, Pull import audioio import busio import board import neopixel import adafruit_lis3dh # CUSTOMIZE YOUR COLOR HERE: # (red, green, blue) -- each 0 (off) to 255 (brightest) # COLOR = (255, 0, 0) # red COLOR = (100, 0, 255) # purple # COLOR = (0, 100, 255) #cyan # CUSTOMIZE SENSITIVITY HERE: smaller numbers = more sensitive to motion HIT_THRESHOLD = 350 # 250 SWING_THRESHOLD = 125 NUM_PIXELS = 114 # NUM_PIXELS = 85 NEOPIXEL_PIN = board.D5 POWER_PIN = board.D10 SWITCH_PIN = board.D9 enable = DigitalInOut(POWER_PIN) enable.direction = Direction.OUTPUT enable.value =False red_led = DigitalInOut(board.D11) red_led.direction = Direction.OUTPUT green_led = DigitalInOut(board.D12) green_led.direction = Direction.OUTPUT blue_led = DigitalInOut(board.D13) blue_led.direction = Direction.OUTPUT audio = audioio.AudioOut(board.A0) # Speaker mode = 0 # Initial mode = OFF strip = neopixel.NeoPixel(NEOPIXEL_PIN, NUM_PIXELS, brightness=1, auto_write=False) strip.fill(0) # NeoPixels off ASAP on startup strip.show() switch = DigitalInOut(SWITCH_PIN) switch.direction = Direction.INPUT switch.pull = Pull.UP time.sleep(0.1) # Set up accelerometer on I2C bus, 4G range: i2c = busio.I2C(board.SCL, board.SDA) accel = adafruit_lis3dh.LIS3DH_I2C(i2c) accel.range = adafruit_lis3dh.RANGE_4_G # "Idle" color is 1/4 brightness, "swinging" color is full brightness... COLOR_IDLE = (int(COLOR[0] / 1), int(COLOR[1] / 1), int(COLOR[2] / 1)) COLOR_SWING = COLOR COLOR_HIT = (255, 255, 255) # "hit" color is 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). """ print("playing", name) try: wave_file = open('sounds/' + name + '.wav', 'rb') wave = audioio.WaveFile(wave_file) audio.play(wave, loop=loop) except: return def power(sound, duration, reverse): """ Animate NeoPixels with accompanying sound effect for power on / off. @param sound: sound name (similar format to play_wav() above) @param duration: estimated duration of sound, in seconds (>0.0) @param reverse: if True, do power-off effect (reverses animation) """ if reverse: prev = NUM_PIXELS else: prev = 0 gc.collect() # Tidy up RAM now so animation's smoother 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 fraction = elapsed / duration # Animation time, 0.0 to 1.0 if reverse: fraction = 1.0 - fraction # 1.0 to 0.0 if reverse fraction = math.pow(fraction, 0.5) # Apply nonlinear curve threshold = int(NUM_PIXELS * fraction + 0.5) num = threshold - prev # Number of pixels to light on this pass if num != 0: if reverse: strip[threshold:prev] = [0] * -num else: strip[prev:threshold] = [COLOR_IDLE] * num strip.show() # NeoPixel writes throw off time.monotonic() ever so slightly # because interrupts are disabled during the transfer. # We can compensate somewhat by adjusting the start time # back by 30 microseconds per pixel. start_time -= NUM_PIXELS * 0.00003 prev = threshold if reverse: strip.fill(0) # At end, ensure strip is off else: strip.fill(COLOR_IDLE) # or all pixels set on strip.show() while audio.playing: # Wait until audio done pass 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)) # Main program loop, repeats indefinitely while True: red_led.value = True if not switch.value: # button pressed? if mode == 0: # If currently off... enable.value = True power('on', 1.7, False) # Power up! play_wav('idle', loop=True) # Play background hum sound mode = 1 # ON (idle) mode now else: # else is currently on... power('off', 1.15, True) # Power down mode = 0 # OFF mode now enable.value = False while not switch.value: # Wait for button release time.sleep(0.2) # to avoid repeated triggering 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 for this, assuming Hallowing is mounted # sideways to stick. Also, square root isn't needed, since we're # just comparing thresholds...use squared values instead, save math.) if accel_total > HIT_THRESHOLD: # Large acceleration = HIT TRIGGER_TIME = time.monotonic() # Save initial time of hit play_wav('hit') # 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('swing') # Start playing 'swing' sound COLOR_ACTIVE = COLOR_SWING # Set color to fade from mode = 2 # SWING mode 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_IDLE, blend)) strip.show() else: # No sound now, but still MODE > 1 play_wav('idle', loop=True) # Resume background hum strip.fill(COLOR_IDLE) # Set to idle color strip.show() mode = 1 # IDLE mode now