Skip to content

Commit 949e0ba

Browse files
committed
Adding code and audio files for lightsaber
Adding code and folder of audio files for the Feather RP2040 Prop-Maker lightsaber
1 parent 8706ad6 commit 949e0ba

22 files changed

+176
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import os
7+
import random
8+
import board
9+
import pwmio
10+
import audiocore
11+
import audiobusio
12+
from adafruit_debouncer import Button
13+
from digitalio import DigitalInOut, Direction, Pull
14+
import neopixel
15+
import adafruit_lis3dh
16+
import simpleio
17+
18+
# CUSTOMIZE SENSITIVITY HERE: smaller numbers = more sensitive to motion
19+
HIT_THRESHOLD = 120
20+
SWING_THRESHOLD = 130
21+
RED = (255, 0, 0)
22+
YELLOW = (125, 255, 0)
23+
GREEN = (0, 255, 0)
24+
CYAN = (0, 125, 255)
25+
BLUE = (0, 0, 255)
26+
PURPLE = (125, 0, 255)
27+
WHITE = (255, 255, 255)
28+
COLORS = [RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE]
29+
SABER_COLOR = 3
30+
CLASH_COLOR = 6
31+
32+
# enable external power pin
33+
# provides power to the external components
34+
external_power = DigitalInOut(board.EXTERNAL_POWER)
35+
external_power.direction = Direction.OUTPUT
36+
external_power.value = True
37+
38+
wavs = []
39+
for filename in os.listdir('/sounds'):
40+
if filename.lower().endswith('.wav') and not filename.startswith('.'):
41+
wavs.append("/sounds/"+filename)
42+
wavs.sort()
43+
print(wavs)
44+
print(len(wavs))
45+
46+
audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA)
47+
48+
def play_wav(num, loop=False):
49+
"""
50+
Play a WAV file in the 'sounds' directory.
51+
:param name: partial file name string, complete name will be built around
52+
this, e.g. passing 'foo' will play file 'sounds/foo.wav'.
53+
:param loop: if True, sound will repeat indefinitely (until interrupted
54+
by another sound).
55+
"""
56+
try:
57+
n = wavs[num]
58+
wave_file = open(n, "rb")
59+
wave = audiocore.WaveFile(wave_file)
60+
audio.play(wave, loop=loop)
61+
except: # pylint: disable=bare-except
62+
return
63+
64+
# external button
65+
pin = DigitalInOut(board.EXTERNAL_BUTTON)
66+
pin.direction = Direction.INPUT
67+
pin.pull = Pull.UP
68+
switch = Button(pin, long_duration_ms = 1000)
69+
switch_state = False
70+
71+
# external neopixels
72+
num_pixels = 100
73+
pixels = neopixel.NeoPixel(board.EXTERNAL_NEOPIXELS, num_pixels, auto_write=True)
74+
pixels.brightness = 0.8
75+
76+
# onboard LIS3DH
77+
i2c = board.I2C()
78+
int1 = DigitalInOut(board.ACCELEROMETER_INTERRUPT)
79+
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
80+
lis3dh.range = adafruit_lis3dh.RANGE_2_G
81+
lis3dh.set_tap(1, HIT_THRESHOLD)
82+
83+
red_led = pwmio.PWMOut(board.D10)
84+
green_led = pwmio.PWMOut(board.D11)
85+
blue_led = pwmio.PWMOut(board.D12)
86+
87+
def set_rgb_led(color):
88+
# convert from 0-255 (neopixel range) to 65535-0 (pwm range)
89+
red_led.duty_cycle = int(simpleio.map_range(color[0], 0, 255, 65535, 0))
90+
green_led.duty_cycle = int(simpleio.map_range(color[1], 0, 255, 65535, 0))
91+
blue_led.duty_cycle = int(simpleio.map_range(color[2], 0, 255, 65535, 0))
92+
93+
set_rgb_led(COLORS[SABER_COLOR])
94+
95+
mode = 0
96+
swing = False
97+
hit = False
98+
99+
while True:
100+
switch.update()
101+
# startup
102+
if mode == 0:
103+
print(mode)
104+
play_wav(0, loop=False)
105+
for i in range(num_pixels):
106+
pixels[i] = COLORS[SABER_COLOR]
107+
pixels.show()
108+
time.sleep(1)
109+
play_wav(1, loop=True)
110+
mode = 1
111+
# default
112+
elif mode == 1:
113+
x, y, z = lis3dh.acceleration
114+
accel_total = x * x + z * z
115+
if lis3dh.tapped:
116+
print("tapped")
117+
mode = "hit"
118+
elif accel_total >= SWING_THRESHOLD:
119+
print("swing")
120+
mode = "swing"
121+
if switch.short_count == 1:
122+
mode = 3
123+
if switch.long_press:
124+
audio.stop()
125+
play_wav(19, loop=True)
126+
print("change color")
127+
mode = 5
128+
# clash or move
129+
elif mode == "hit":
130+
audio.stop()
131+
play_wav(random.randint(3, 10), loop=False)
132+
while audio.playing:
133+
pixels.fill(WHITE)
134+
pixels.show()
135+
pixels.fill(COLORS[SABER_COLOR])
136+
pixels.show()
137+
play_wav(1, loop=True)
138+
mode = 1
139+
elif mode == "swing":
140+
audio.stop()
141+
play_wav(random.randint(11, 18), loop=False)
142+
while audio.playing:
143+
pixels.fill(COLORS[SABER_COLOR])
144+
pixels.show()
145+
pixels.fill(COLORS[SABER_COLOR])
146+
pixels.show()
147+
play_wav(1, loop=True)
148+
mode = 1
149+
# turn off
150+
elif mode == 3:
151+
audio.stop()
152+
play_wav(2, loop=False)
153+
for i in range(99, 0, -1):
154+
pixels[i] = (0, 0, 0)
155+
pixels.show()
156+
time.sleep(1)
157+
external_power.value = False
158+
mode = 4
159+
# go to startup from off
160+
elif mode == 4:
161+
if switch.short_count == 1:
162+
external_power.value = True
163+
mode = 0
164+
# change color
165+
elif mode == 5:
166+
if switch.short_count == 1:
167+
SABER_COLOR = (SABER_COLOR + 1) % 6
168+
pixels.fill(COLORS[SABER_COLOR])
169+
pixels.show()
170+
set_rgb_led(COLORS[SABER_COLOR])
171+
if switch.long_press:
172+
play_wav(1, loop=True)
173+
pixels.fill(COLORS[SABER_COLOR])
174+
pixels.show()
175+
set_rgb_led(COLORS[SABER_COLOR])
176+
mode = 1
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.

0 commit comments

Comments
 (0)