Once you've finished setting up your RP2040 Prop-Maker Feather with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.
To do this, click on the Download Project Bundle button in the window below. It will download to your computer as a zipped folder.
# SPDX-FileCopyrightText: 2024 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import time
import os
import random
import board
from digitalio import DigitalInOut, Direction
import neopixel
import audiocore
import audiobusio
import keypad
import adafruit_lis3dh
from rainbowio import colorwheel
# 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
# external neopixels
num_pixels = 24
pixels = neopixel.NeoPixel(board.EXTERNAL_NEOPIXELS, num_pixels, brightness=0.4, auto_write=True)
delta_hue = 256//num_pixels
speed = 10 # higher numbers = faster rainbow spinning
i=0
# external button
switch = keypad.Keys((board.EXTERNAL_BUTTON,), value_when_pressed=False, pull=True)
colors = [
{'label': "BLUE", 'color': 0x0000FF},
{'label': "RED", 'color': 0xFF0000},
{'label': "GREEN", 'color': 0x00FF00},
{'label': "YELLOW", 'color': 0xFFFF00},
{'label': "AQUA", 'color': 0x00FFFF},
{'label': "PURPLE", 'color': 0xFF00FF},
{'label': "PINK", 'color': 0xFF0055},
{'label': "ORANGE", 'color': 0xFF5500},
{'label': "WHITE", 'color': 0x555555},
]
shake_wavs = []
color_wavs = []
for filename in os.listdir('/wavs'):
if filename.lower().endswith('.wav') and not filename.startswith('.'):
if "SHAKE" in filename:
shake_wavs.append("/wavs/" + filename)
else:
for color in colors:
if color['label'] in filename:
color_wavs.append("/wavs/" + filename)
break
audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA)
num_colors = len(color_wavs)
num_shakes = len(shake_wavs)
wav_index = 0
def open_audio(num, wavs):
n = wavs[num]
f = open(n, "rb")
w = audiocore.WaveFile(f)
# wn = wav_names[num]
return w, n
wave, wave_name = open_audio(wav_index, color_wavs)
i2c = board.I2C()
int1 = DigitalInOut(board.ACCELEROMETER_INTERRUPT)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
lis3dh.range = adafruit_lis3dh.RANGE_2_G
while True:
event = switch.events.get()
if event:
if event.pressed:
wave, wave_name = open_audio(random.randint(0, num_colors - 1), color_wavs)
audio.play(wave)
for color in colors:
if color['label'] in wave_name:
pixels.fill(color['color'])
else:
pass
time.sleep(1)
pixels.fill((0, 0, 0))
print('pressed')
if event.released:
pass
if lis3dh.shake(shake_threshold=12):
wave, wave_name = open_audio(random.randint(0, num_shakes - 1), shake_wavs)
audio.play(wave)
for l in range(len(pixels)):
pixels[l] = colorwheel( int(i*speed + l * delta_hue) % 255 )
pixels.show()
time.sleep(1)
pixels.fill((0, 0, 0))
print('shake')
Upload the Code, Sound Effects, and Libraries to the RP2040 Prop-Maker Feather
After downloading the Project Bundle, plug your RP2040 Prop-Maker Feather into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather's CIRCUITPY drive:
- lib folder
- wavs folder
- code.py
Your RP2040 Prop-Maker Feather CIRCUITPY drive should look like this after copying the lib folder, wavs folder and the code.py file.
How the CircuitPython Code Works
The code begins by turning on the EXTERNAL_POWER pin on the Feather. This pin controls the power to the terminal block pins. The NeoPixels and button use the EXTERNAL_NEOPIXELS and EXTERNAL_BUTTON pins.
# 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 # external neopixels num_pixels = 24 pixels = neopixel.NeoPixel(board.EXTERNAL_NEOPIXELS, num_pixels, brightness=0.4, auto_write=True) # external button switch = keypad.Keys((board.EXTERNAL_BUTTON,), value_when_pressed=False, pull=True)
colors = [
{'label': "BLUE", 'color': 0x0000FF},
{'label': "RED", 'color': 0xFF0000},
{'label': "GREEN", 'color': 0x00FF00},
{'label': "YELLOW", 'color': 0xFFFF00},
{'label': "AQUA", 'color': 0x00FFFF},
{'label': "PURPLE", 'color': 0xFF00FF},
{'label': "PINK", 'color': 0xFF0055},
{'label': "ORANGE", 'color': 0xFF5500},
{'label': "WHITE", 'color': 0x555555},
]
Sorting Audio
The audio files from the wavs folder are sorted into two different arrays:Â shake_wavs and color_wavs. They are sorted based on the name of the file. If "SHAKE" is in the file name, then it is added to shake_wavs. If the file name has one of the color labels from the colors dictionary, then it is added to color_wavs.
shake_wavs = []
color_wavs = []
for filename in os.listdir('/wavs'):
if filename.lower().endswith('.wav') and not filename.startswith('.'):
if "SHAKE" in filename:
shake_wavs.append("/wavs/" + filename)
else:
for color in colors:
if color['label'] in filename:
color_wavs.append("/wavs/" + filename)
break
The Loop
In the loop, the keypad object is scanned for an event. If the switch is pressed, then one of the sound files that was sorted into the color_wavs array is opened and played. The NeoPixel ring lights up with the same color that is contained in the name of the audio file.
while True:
event = switch.events.get()
if event:
if event.pressed:
wave, wave_name = open_audio(random.randint(0, num_colors - 1), color_wavs)
audio.play(wave)
for color in colors:
if color['label'] in wave_name:
pixels.fill(color['color'])
else:
pass
time.sleep(.7)
pixels.fill((0, 0, 0))
print('pressed')
If the LIS3DH detects a shake, then one of the audio files from the shake_wavs is opened and played. The NeoPixels light up with a rainbow effect.
if lis3dh.shake(shake_threshold=12):
wave, wave_name = open_audio(random.randint(0, num_shakes - 1), shake_wavs)
audio.play(wave)
for i in range(num_pixels):
pixels[i] = colorwheel(hue)
hue = (hue + 30) % 256
print(hue)
time.sleep(.7)
pixels.fill((0, 0, 0))
print('shake')
Page last edited January 22, 2025
Text editor powered by tinymce.