Skip to content

Commit 442b4a7

Browse files
authored
Merge pull request #2575 from adafruit/lightsaber_prop-maker
Adding code and audio files for lightsaber
2 parents 8706ad6 + 949e0ba commit 442b4a7

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)