Adafruit_Learning_System_Gu.../Feather_RP2040_Prop-Maker_Lightsaber/code.py
DJDevon3 41485ea5b6 Add code comment for Accel Range
Accelerometer range is basically hit detection sensitivity.  Had a beginner in Discord that didn't know how to change it because it's not documented in the learn guide.  Need a better way to make this parameter configurable and easy to use. Please also add something into the learn guide about using this for lowering sensitivity.  By default the lightsaber is set to 2G which is its most sensitive setting.
2023-11-08 12:21:55 -05:00

177 lines
5 KiB
Python

# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import os
import random
import board
import pwmio
import audiocore
import audiobusio
from adafruit_debouncer import Button
from digitalio import DigitalInOut, Direction, Pull
import neopixel
import adafruit_lis3dh
import simpleio
# CUSTOMIZE SENSITIVITY HERE: smaller numbers = more sensitive to motion
HIT_THRESHOLD = 120
SWING_THRESHOLD = 130
RED = (255, 0, 0)
YELLOW = (125, 255, 0)
GREEN = (0, 255, 0)
CYAN = (0, 125, 255)
BLUE = (0, 0, 255)
PURPLE = (125, 0, 255)
WHITE = (255, 255, 255)
COLORS = [RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE]
SABER_COLOR = 3
CLASH_COLOR = 6
# enable external power pin
# provides power to the external components
external_power = DigitalInOut(board.EXTERNAL_POWER)
external_power.direction = Direction.OUTPUT
external_power.value = True
wavs = []
for filename in os.listdir('/sounds'):
if filename.lower().endswith('.wav') and not filename.startswith('.'):
wavs.append("/sounds/"+filename)
wavs.sort()
print(wavs)
print(len(wavs))
audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA)
def play_wav(num, 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).
"""
try:
n = wavs[num]
wave_file = open(n, "rb")
wave = audiocore.WaveFile(wave_file)
audio.play(wave, loop=loop)
except: # pylint: disable=bare-except
return
# external button
pin = DigitalInOut(board.EXTERNAL_BUTTON)
pin.direction = Direction.INPUT
pin.pull = Pull.UP
switch = Button(pin, long_duration_ms = 1000)
switch_state = False
# external neopixels
num_pixels = 100
pixels = neopixel.NeoPixel(board.EXTERNAL_NEOPIXELS, num_pixels, auto_write=True)
pixels.brightness = 0.8
# onboard LIS3DH
i2c = board.I2C()
int1 = DigitalInOut(board.ACCELEROMETER_INTERRUPT)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
# Accelerometer Range (can be 2_G, 4_G, 8_G, 16_G)
lis3dh.range = adafruit_lis3dh.RANGE_2_G
lis3dh.set_tap(1, HIT_THRESHOLD)
red_led = pwmio.PWMOut(board.D10)
green_led = pwmio.PWMOut(board.D11)
blue_led = pwmio.PWMOut(board.D12)
def set_rgb_led(color):
# convert from 0-255 (neopixel range) to 65535-0 (pwm range)
red_led.duty_cycle = int(simpleio.map_range(color[0], 0, 255, 65535, 0))
green_led.duty_cycle = int(simpleio.map_range(color[1], 0, 255, 65535, 0))
blue_led.duty_cycle = int(simpleio.map_range(color[2], 0, 255, 65535, 0))
set_rgb_led(COLORS[SABER_COLOR])
mode = 0
swing = False
hit = False
while True:
switch.update()
# startup
if mode == 0:
print(mode)
play_wav(0, loop=False)
for i in range(num_pixels):
pixels[i] = COLORS[SABER_COLOR]
pixels.show()
time.sleep(1)
play_wav(1, loop=True)
mode = 1
# default
elif mode == 1:
x, y, z = lis3dh.acceleration
accel_total = x * x + z * z
if lis3dh.tapped:
print("tapped")
mode = "hit"
elif accel_total >= SWING_THRESHOLD:
print("swing")
mode = "swing"
if switch.short_count == 1:
mode = 3
if switch.long_press:
audio.stop()
play_wav(19, loop=True)
print("change color")
mode = 5
# clash or move
elif mode == "hit":
audio.stop()
play_wav(random.randint(3, 10), loop=False)
while audio.playing:
pixels.fill(WHITE)
pixels.show()
pixels.fill(COLORS[SABER_COLOR])
pixels.show()
play_wav(1, loop=True)
mode = 1
elif mode == "swing":
audio.stop()
play_wav(random.randint(11, 18), loop=False)
while audio.playing:
pixels.fill(COLORS[SABER_COLOR])
pixels.show()
pixels.fill(COLORS[SABER_COLOR])
pixels.show()
play_wav(1, loop=True)
mode = 1
# turn off
elif mode == 3:
audio.stop()
play_wav(2, loop=False)
for i in range(99, 0, -1):
pixels[i] = (0, 0, 0)
pixels.show()
time.sleep(1)
external_power.value = False
mode = 4
# go to startup from off
elif mode == 4:
if switch.short_count == 1:
external_power.value = True
mode = 0
# change color
elif mode == 5:
if switch.short_count == 1:
SABER_COLOR = (SABER_COLOR + 1) % 6
pixels.fill(COLORS[SABER_COLOR])
pixels.show()
set_rgb_led(COLORS[SABER_COLOR])
if switch.long_press:
play_wav(1, loop=True)
pixels.fill(COLORS[SABER_COLOR])
pixels.show()
set_rgb_led(COLORS[SABER_COLOR])
mode = 1