Overview
Audio Recorder
Build a whismical audio recording device that features built-in effects. You can record an audio sample (20-second max) and play it back as a loop. During playback, you can change the pitch of the recording using a slider, and apply two effects: a reverb and a delay/echo using rotary potentiometers. This fun project demonstrates the audio capabilities of CircuitPython!
Portable Device
The 3D printed enclosure houses an Adafruit Feather RP2350, I2S microphone, I2S amplifier, NeoPixels, and a built-in speaker. The device is portable, powered by a recharagable 2200mAh battery.
Featuring three-colors, the enclosre is made on a 3D printer with multi-color capability to create elements like text, icons, and colored segments.
Page last edited July 28, 2026
Text editor powered by tinymce.
Circuit Diagram
The diagram below provides a general visual reference for wiring of the components once you get to the Assembly page. This diagram was created using the software package Fritzing.
Adafruit Library for Fritzing
Adafruit uses the Adafruit Fritzing parts library to create circuit diagrams for projects. You can download the library or just grab individual parts. Get the library and parts from GitHub - Adafruit Fritzing Parts.
Wired Connections
The Feather RP2350 is powered by a 3.7v 2200mAh lithium ion polymer battery. Wires connecting various components:
Feather RP2350 to ICS 43434
3V to VDDÂ
GND to GND
D9 to DOUT
D5 to BCLK
D6 to LRCL
Feather RP2350 to MAX98357A
3V to VIN
GND to GND
D11 to LRC
D10 to BCLK
SCL to DIN
Feather RP2350 to NeoPixel
Bat to 5VDC
GND to GND
D12 (GPIO4) to DATAIN
Feather RP2350 to Slide Potentiometer
3V to Pin 1 (VCC)
A0 to Pin 2 (Signal)
GND to Pin 3 (GND)
Feather RP2350 to Rotary Potentiometer A
GND to Pin 1
A1 to Pin 2
3V to Pin 3
Feather RP2350 to Rotary Potentiometer B
GND to Pin 1
A2 to Pin 2
3V to Pin 3
Feather RP2350 to Button A
A3 to Pin 1
GND to Pin 2
Feather RP2350 to Button B
D24 to Pin 1
GND to Pin 2
Feather RP2350 to Toggle Switch
D25 to Pin 1
GND to Pin 2
Feather RP2350 to Slide Switch
GND to Pin 1
EN to Pin 2
Page last edited July 28, 2026
Text editor powered by tinymce.
CAD Files
CAD Parts
Individual 3MF files for 3D printing are oriented and ready to print on FDM machines using PLA filament. Original design source files may be downloaded using the links below.
CAD Assembly
The Feather, I2S amplifier, I2S microphone, battery, NeoPixel stick, toggle switch, slide switch and wago block connectors are secured to the bottom half of the case.
The two rotary potentiometers, slide potentiometer, key switches and speaker are secured to the top half of the case.
Build Volume
The parts require a 3D printer with a minimum build volume of 80 (X) x 130 (Y) x 16mm (Z).
Multi-color Part
The top half of the enclosure uses an AMS multi-color capable 3D printer and features three different colors. The LED diffuser should be printed using a white or clear colored PLA filament.
The rotary knob and keycaps use two different colors. Single color (blank) version of these parts are available in the ZIP file.
3D Models of Adafruit Parts
Electronic components like Adafruit's boards and more can be downloaded from the Adafruit CAD parts GitHub Repo.
Page last edited July 28, 2026
Text editor powered by tinymce.
Install CircuitPython
CircuitPython is a derivative of MicroPython designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the CIRCUITPY drive to iterate.
CircuitPython Quickstart
Follow this step-by-step to quickly get CircuitPython running on your board.
audioi2sin, audiofilewriter, and GranularPitchShift modules used by this project are brand new. Running this project requires using the development release of CircuitPython 10.3.0.alpha-4 or newer until there is a 10.3.0 stable release. On the downloads page scroll down to the latest development release panel.
Click the link above to download the latest CircuitPython UF2 file.
Save it wherever is convenient for you.
To enter the bootloader, hold down the BOOT/BOOTSEL button (highlighted in red above), and while continuing to hold it (don't let go!), press and release the reset button (highlighted in red or blue above). Continue to hold the BOOT/BOOTSEL button until the RP2350 drive appears!
If the drive does not appear, release all the buttons, and then repeat the process above.
You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.
A lot of people end up using charge-only USB cables and it is very frustrating! Make sure you have a USB cable you know is good for data sync.
You will see a new disk drive appear called RP2350.
Â
Drag the adafruit-circuitpython-boardname-language-version.uf2 file to RP2350.
The RP2350 drive will disappear and a new disk drive called CIRCUITPY will appear.
That's it, you're done! :)
Safe Mode
You want to edit your code.py or modify the files on your CIRCUITPY drive, but find that you can't. Perhaps your board has gotten into a state where CIRCUITPY is read-only. You may have turned off the CIRCUITPY drive altogether. Whatever the reason, safe mode can help.
Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode bypasses any code in boot.py (where you can set CIRCUITPY read-only or turn it off completely). Second, it does not run the code in code.py. And finally, it does not automatically soft-reload when data is written to the CIRCUITPY drive.
Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the CIRCUITPY drive.
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)
In Safe Mode
If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.
If you connect to the serial console, you'll find the following message.
Auto-reload is off. Running in safe mode! Not running saved code. CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode. Press any key to enter the REPL. Use CTRL-D to reload.
You can now edit the contents of the CIRCUITPY drive. Remember, your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode.
Flash Resetting UF2
If your board ever gets into a really weird state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RP2350. which will do a 'deep clean' on your Flash Memory. You will lose all the files on the board, but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.
Page last edited July 28, 2026
Text editor powered by tinymce.
Code the Voicebox
Once you've finished setting up your RP2350 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: 2026 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Voice Box FX Changer
I2S Mic in -> .WAV file -> I2S DAC out
Effects controlled with analog inputs during looped playback
"""
import io
import time
import audiobusio
import board
import audioi2sin
import simpleio
import audiodelays
import audiofreeverb
import audiofilewriter
import audiofilters
import audiocore
import audiomixer
import keypad
from analogio import AnalogIn
import neopixel
pitch_slide = AnalogIn(board.A0)
reverb_slide = AnalogIn(board.A1)
dist_slide = AnalogIn(board.A2)
# record button on D24, play button on A3
keys = keypad.Keys((board.D24, board.A3), value_when_pressed=False, pull=True)
pixels = neopixel.NeoPixel(board.D12, 8, brightness=0.6, auto_write=True)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
PURPLE = (50, 0, 255)
OFF = (0, 0, 0)
# recording config
SAMPLE_RATE = 16000
OUTPUT_PATH = "/recording.wav"
MAX_RECORD_SECONDS = 20
# mono 16-bit = 2 bytes/sample + room for the 44-byte WAV header
CAPTURE_ALLOC = SAMPLE_RATE * 2 * MAX_RECORD_SECONDS + 64
capture = None
# Mic
mic = audioi2sin.I2SIn(
bit_clock=board.D5,
word_select=board.D6,
data=board.D9,
sample_rate=SAMPLE_RATE,
bit_depth=32,
output_bit_depth=16,
mono=True,
left_justified=False, # using ICS43434
)
i2s = audiobusio.I2SOut(board.D10, board.D11, board.SCL)
mixer = audiomixer.Mixer(
voice_count=1,
sample_rate=SAMPLE_RATE,
channel_count=1,
bits_per_sample=16, # matches output_bit_depth
samples_signed=True,
)
i2s.play(mixer)
mixer.voice[0].level = 0.5
pitch_shift = audiodelays.PitchShift(
semitones=0.0,
mix=1.0,
window=2048,
overlap=256,
buffer_size=1024,
channel_count=1,
sample_rate=SAMPLE_RATE,
)
reverb = audiofreeverb.Freeverb(
roomsize=0.35,
damp=0.25,
buffer_size=1024,
channel_count=1,
sample_rate=SAMPLE_RATE,
mix=0.0,
)
echo = audiodelays.Echo(
max_delay_ms=1000,
delay_ms=850,
decay=0.0,
buffer_size=1024,
channel_count=1,
sample_rate=SAMPLE_RATE,
mix=1.0,
freq_shift=False
)
amp = audiofilters.Distortion(
pre_gain=15,
drive=0.00,
mode=audiofilters.DistortionMode.LOFI,
soft_clip=True,
mix=1.0,
buffer_size=1024,
sample_rate=SAMPLE_RATE,
bits_per_sample=16,
samples_signed=True,
channel_count=1,
)
loop = False
recording = False
file = open("/bootbeeps.wav", "rb")
wav = audiocore.WaveFile(file)
mixer.voice[0].play(wav, loop=False)
# start-up purple marquee
for i in range(8):
pixels[i] = PURPLE
time.sleep(0.2)
time.sleep(0.5)
mixer.voice[0].level = 1.0
pixels.fill(OFF)
while True:
event = keys.events.get()
if event:
key_number = event.key_number
if event.pressed and key_number == 0: # record button
if not recording: # press to record
i2s.stop() # stopping i2s out mutes DAC
pixels.fill(RED) # red means recording
capture = io.BytesIO(CAPTURE_ALLOC) # write into memory
writer = audiofilewriter.AudioFileWriter(capture)
writer.play(mic)
recording = True
else: # press to stop
writer.stop()
pixels.fill(YELLOW) # yellow while writing
print("captured", capture.tell(), "bytes")
try:
capture.seek(0) # write from memory to wav on file system
with open(OUTPUT_PATH, "wb") as f:
while True:
chunk = capture.read(4096)
if not chunk:
break
f.write(chunk)
capture.seek(0)
recording = False
pixels.fill(OFF)
except OSError as e:
pixels.fill(BLUE) # error = blue, but continues running
print(f"Read-only mode, can't save the file, flip the switch and reboot!: {e}")
time.sleep(2)
pixels.fill(OFF)
continue
if event.pressed and key_number == 1: # play button
if not loop: # press to play, looping
i2s.play(mixer)
try:
# opens wav file that was just written from memory
file = open("recording.wav", "rb")
wav = audiocore.WaveFile(file)
print("got file")
pixels.fill(GREEN) # playback is green
except AttributeError as e:
pixels.fill(BLUE)
print(f"Missing recording.wav: {e}")
time.sleep(2)
pixels.fill(OFF)
continue
loop = True
pitch_shift.play(wav, loop=True) # effect chain, all have to loop
reverb.play(pitch_shift, loop=True)
echo.play(reverb, loop=True)
amp.play(echo, loop=True) # gain boost
mixer.voice[0].play(amp, loop=True)
else: # press to stop
mixer.voice[0].stop()
loop = False
pixels.fill(OFF)
# controlling % of reverb in the mix
verb = simpleio.map_range(reverb_slide.value, 100, 65536, 0.0, 1.0)
reverb.mix = verb
# controlling amount of echo decay
echo_range = simpleio.map_range(dist_slide.value, 100, 65536, 0.0, 1.0)
echo.decay = echo_range
# an octave has 12 semitones, -13 and +13 gives full octave up and down
pitch = simpleio.map_range(pitch_slide.value, 100, 65536, -13.0, 13.0)
pitch_shift.semitones = int(pitch)
Upload the Code and Libraries to the RP2350 Feather
After downloading the Project Bundle, plug your RP2350 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 RP2350 Feather's CIRCUITPY drive.
- lib folder
- bootbeep.wav
- boot.py
- code.py
Your RP2350 Feather CIRCUITPY drive should look like this after copying the lib folder, bootbeep.wav file, boot.py file and code.py file:
boot.py
This project makes use of a boot.py file. This file runs before code.py and sets the state for readonly mode for the CIRCUITPY drive. If pin D25 is connected to ground with the toggle switch, then CIRCUITPY is set to read/write mode. This allows for the recordings to be saved to the CIRCUITPY drive.Â
If you need to edit code.py, or any other files on the CIRCUITPY drive, then you'll want D25 to not be connected to ground to have CIRCUITPY be in read only mode.
import board
import digitalio
import storage
switch = digitalio.DigitalInOut(board.D25)
switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP
# If the switch pin is connected to ground CircuitPython can write to the drive
storage.remount("/", readonly=switch.value)
For more information on using boot.py and the storage module, check out this page in the CircuitPython Essentials guide.
How the CircuitPython Code Works
The code begins by initializing the pins for the three analog inputs and two button inputs. The two buttons are passed to a keypad object. Then the NeoPixel stick and the colors used are defined.
pitch_slide = AnalogIn(board.A0) reverb_slide = AnalogIn(board.A1) dist_slide = AnalogIn(board.A2) # record button on D24, play button on A3 keys = keypad.Keys((board.D24, board.A3), value_when_pressed=False, pull=True) pixels = neopixel.NeoPixel(board.D12, 8, brightness=0.6, auto_write=True) RED = (255, 0, 0) YELLOW = (255, 255, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) PURPLE = (50, 0, 255) OFF = (0, 0, 0)
I2S Settings
There are a few recording configuration variables that are set. The SAMPLE_RATE has to match across all of the audio settings. In this case, it is 16000. The OUTPUT_PATH is where the recording from the I2S microphone will be saved. Then, the I2S input and I2S output are instantiated. The I2S output is passed to a Mixer object.
# recording config
SAMPLE_RATE = 16000
OUTPUT_PATH = "/recording.wav"
MAX_RECORD_SECONDS = 20
# mono 16-bit = 2 bytes/sample + room for the 44-byte WAV header
CAPTURE_ALLOC = SAMPLE_RATE * 2 * MAX_RECORD_SECONDS + 64
capture = None
# Mic
mic = audioi2sin.I2SIn(
bit_clock=board.D5,
word_select=board.D6,
data=board.D9,
sample_rate=SAMPLE_RATE,
bit_depth=32,
output_bit_depth=16,
mono=True,
left_justified=False, # using ICS43434
)
i2s = audiobusio.I2SOut(board.D10, board.D11, board.SCL)
mixer = audiomixer.Mixer(
voice_count=1,
sample_rate=SAMPLE_RATE,
channel_count=1,
bits_per_sample=16, # matches output_bit_depth
samples_signed=True,
)
i2s.play(mixer)
mixer.voice[0].level = 0.5
Effects Chain
Four effects are used for the voice changer:Â PitchShift, Freeverb (reverb), Echo and Distortion. The three analog inputs control the semitones for PitchShift, mix amount for Freeverb and decay amount for Echo. The Distortion effect is used as an amplifier to give a gain boost to the I2S output.
pitch_shift = audiodelays.PitchShift(
semitones=0.0,
mix=1.0,
window=2048,
overlap=256,
buffer_size=1024,
channel_count=1,
sample_rate=SAMPLE_RATE,
)
reverb = audiofreeverb.Freeverb(
roomsize=0.35,
damp=0.25,
buffer_size=1024,
channel_count=1,
sample_rate=SAMPLE_RATE,
mix=0.0,
)
echo = audiodelays.Echo(
max_delay_ms=1000,
delay_ms=850,
decay=0.0,
buffer_size=1024,
channel_count=1,
sample_rate=SAMPLE_RATE,
mix=1.0,
freq_shift=False
)
amp = audiofilters.Distortion(
pre_gain=15,
drive=0.00,
mode=audiofilters.DistortionMode.LOFI,
soft_clip=True,
mix=1.0,
buffer_size=1024,
sample_rate=SAMPLE_RATE,
bits_per_sample=16,
samples_signed=True,
channel_count=1,
)
Boot Up Beeps
Before the loop, there are two variables that are defined. loop will determine if the audio file is playing back and recording will determine if a recording is in progress. Then, the boot up sound effect is loaded and passed to the mixer to play once. While it plays, the NeoPixels light up purple one by one.
loop = False
recording = False
file = open("/bootbeeps.wav", "rb")
wav = audiocore.WaveFile(file)
mixer.voice[0].play(wav, loop=False)
# start-up purple marquee
for i in range(8):
pixels[i] = PURPLE
time.sleep(0.2)
time.sleep(0.5)
mixer.voice[0].level = 1.0
pixels.fill(OFF)
The Loop
keypad events are used to monitor the two button inputs. If key_number 0, the record button, is pressed, it will either start a recording or stop a recording through the I2S microphone. The recordings are saved in memory using the audiofilewriter module and you'll see the NeoPixels turn red. When a recording is stopped, the recording stored in memory is converted to a .WAV file that is written to the CIRCUITPY drive and the NeoPixels will turn yellow. If the voice changer is in read-only mode, then the NeoPixels will light up blue to let you know that you need to flip the switch and reboot.
while True:
event = keys.events.get()
if event:
key_number = event.key_number
if event.pressed and key_number == 0: # record button
if not recording: # press to record
i2s.stop() # stopping i2s out mutes DAC
pixels.fill(RED) # red means recording
capture = io.BytesIO(CAPTURE_ALLOC) # write into memory
writer = audiofilewriter.AudioFileWriter(capture)
writer.play(mic)
recording = True
else: # press to stop
writer.stop()
pixels.fill(YELLOW) # yellow while writing
print("captured", capture.tell(), "bytes")
try:
capture.seek(0) # write from memory to wav on file system
with open(OUTPUT_PATH, "wb") as f:
while True:
chunk = capture.read(4096)
if not chunk:
break
f.write(chunk)
capture.seek(0)
recording = False
pixels.fill(OFF)
except OSError as e:
pixels.fill(BLUE) # error = blue, but continues running
print(f"Read-only mode, can't save the file, flip the switch and reboot!: {e}")
time.sleep(2)
pixels.fill(OFF)
continue
If key_number 1, the playback button, is pressed, it will either start playing the recording.wav file on a loop or stop playback through the I2S DAC. If the recording.wav file is missing, then the NeoPixels will light up blue to let you know. Otherwise, the NeoPixels will be green while the file is playing. The file is passed through the effects chain (pitch shift to reverb to echo to amp) to the mixer that outputs over I2S. When playback is stopped, the NeoPixels turn off.
if event.pressed and key_number == 1: # play button
if not loop: # press to play, looping
i2s.play(mixer)
try:
# opens wav file that was just written from memory
file = open("recording.wav", "rb")
wav = audiocore.WaveFile(file)
print("got file")
pixels.fill(GREEN) # playback is green
except AttributeError as e:
pixels.fill(BLUE)
print(f"Missing recording.wav: {e}")
time.sleep(2)
pixels.fill(OFF)
continue
loop = True
pitch_shift.play(wav, loop=True) # effect chain, all have to loop
reverb.play(pitch_shift, loop=True)
echo.play(reverb, loop=True)
amp.play(echo, loop=True) # gain boost
mixer.voice[0].play(amp, loop=True)
else: # press to stop
mixer.voice[0].stop()
loop = False
pixels.fill(OFF)
Effect Controls
Outside of the keypad event listener, the three analog values are mapped to effect parameters. The reverb mix amount and echo decay amount are mapped to the two potentiometers. The pitch shift semitone value is mapped to the slide potentiometer. The value is scaled to an integer so that it corresponds with 12 semitones above or below the beginning pitch of the recording. This gives a full octave up and down for the range.
# controlling % of reverb in the mix
verb = simpleio.map_range(reverb_slide.value, 100, 65536, 0.0, 1.0)
reverb.mix = verb
# controlling amount of echo decay
echo_range = simpleio.map_range(dist_slide.value, 100, 65536, 0.0, 1.0)
echo.decay = echo_range
# an octave has 12 semitones, -13 and +13 gives full octave up and down
pitch = simpleio.map_range(pitch_slide.value, 100, 65536, -13.0, 13.0)
pitch_shift.semitones = int(pitch)
Page last edited July 28, 2026
Text editor powered by tinymce.
Wiring
Slide Switch Wires
Prepare a set of three wires about 4.5 inches (11.4cm) in length.
Using wire strippers, remove a bit of insulation from the tips of each wire.
Tin the exposed wire by applying a bit of solder to them.
Snip off one of the leads on the slide switch, either the far left or right but not the middle. Then trim the two remaining leads short, about half their length.
Solder two of the wires to each of the leads on the slide switch.
A pair of helping hands can assist while soldering wires in place.
Connect Slide Switch to Feather
Solder the wire from the middle pin of the slide switch to the EN pin on the bottom of the Feather.
Solder the two remaining wires from the slide switch to the GND pin on the Feather.
I2S Amplifier Wires
Prepare a set of five colored wires (green, blue, yellow, red and black) about 3in (7.6cm) in length.
Using wire strippers, remove a bit of insulation from the tips of each wire.
Tin the exposed wire by applying a bit of solder to them.
Make the following solder connections.
- Yellow wire to LRC
- Blue wire to BCLK
- Green wire to DIN
- Black wire to GND
- Red wire to VIN
Connect I2S Amplifier to Feather
Solder the wires from the I2S amplifier to the Feather.
- Yellow Wire to Pin #11
- Blue wire to Pin #10
- Green wire to Pin SCL
NeoPixel Stick Wires
Prepare a set of three colored wires (black, red and green) about 5in (12.7cm) in length.
Make the following solder connections.
- Green wire to DIN
- Red wire to 5VDC
- Black wire to GND
Connect NeoPixel to Feather
Solder the wires from the NeoPixel stick to the Feather.
- Red wire to BAT pin
- Green wire to Pin #4
Toggle Switch Wires
Prepare a set of two colored wires (white and black) about 5in (12.7cm) in length.
Solder the black wire to the middle pin.
Solder the white wire to either the far left or right pin.
Connect Toggle Switch to Feather
Solder the wires from the toggle switch to the Feather.
- White wire to pin #25
I2S Mic Wires
Prepare a set of five colored wires (black, green, blue, yellow, and red) to about 5in (12.7cm) in length.
Solder the wires to the pins on the I2S mic.
- Yellow wire to LRCL
- Green wire to DOUT
- Blue wire to BCLK
- Black wire to GND
- Red wire to 3V
Connect I2S Mic to Feather
Solder the wires from the I2S mic to the Feather.
- Blue wire to Pin #5
- Yellow wire to Pin #6
- Green wire to Pin #9
Potentiometer Wires
Prepare a set of seven colored wires (two red, two white, three black) about 6in (15cm) in length.
Solder a red wire to the left pin on one of the potentiometers.
Solder a white wire to the middle pin on the potentiometer.
Solder a black wire to the right pin on the potentiomter.
Connect Potentiometers
On the second potentiometer, solder a black wire and the black wire from the first potentiometer to the matching pin on the right.
Solder the remaining white wire to the middle pin on the second potentiometer.
Solder the remaining red wire to the left pin on the second potentiometer.
Assemble Button to Plate
Get the two choc key switches and the 3D printed button plate ready.
Firmly press the chock key switches into the cutouts in the button plate.
Make sure the key switches are install in the correct orientation.
Button Wires
Prepare a set of four colored wires (two blue, two black) about 5in (12.7cm) in length and one of the black wires shorter about 2.5 inches (6.3cm).
Wire Potentiometers and Buttons
Solder the free hanging black wire from the potentiometer to the middle pin of one of the key switches along with the new shorter black wire.
Solder the shorter black wire and the longer black wire to the middle pin on the second key switch.
Solder one of the blue wires to the remaining pin on the key switch.
Solder the remaining blue wire to the last open pin on the other key switch.
Slide Potentiometer Wires
Prepare a set of three colored wires (red, yellow and black) about 5 inches (12.7cm) in length.
Solder the red wire to pin #1 on the slide potentiometer.
Solder the yellow wire to pin #2 on the slide potentiometer.
Solder the black wire to pin #3 on the slide potentiometer.
Connect Slide Pot to Feather
Solder the yellow wire from the slide potentiometer to pin A0 on the Feather.
Connect Rotary Pots to Feather
Solder the white wire from the first potentiometer to pin A1 on the Feather.
Solder the white wire from the second potentiometer to pin A2 on the Feather.
Connect Buttons to Feather
Solder the blue wire from the first key swich to pin A3 on the Feather.
Solder the blue with from the second key switch to pin #24 on the Feather.
3V Wire
Prepare a single red wire, about 5 inches (12.7 cm) in length.
This wire will connect from Feather 3V pin to the Wago block connector.
Speaker Wires
Cut off the connector from the mini oval speaker.
Use a pair of wire strippers to remove a bit of insulation from both wires.
Apply a bit of solder to tin the exposed wire.
Page last edited July 28, 2026
Text editor powered by tinymce.
Assembly
Install NeoPixel Mount
Get the bottom half of the case and NeoPixel mount ready to secure together.
Place the NeoPixel mount over the matching mounting holes inside the bottom half of the case.
Use two M3x6mm long steel machine screws to secure the parts together.
Install Battery to Case
Firmly press the 2200mAh battery into the clip on the bottom half of the case to install it in place.
Install Slide Switch to Case
Insert the slide switch into the matching holder in the bottom half of the case.
Install Feather to Case
Place the Feather over the matching set of standoffs inside the bottom half of the case.
Insert and fasten two M2.5x4mm long steel machine screws to secure the Feather to the case.
Install I2S Amplifier to Case
Place the I2S amplifier over the matching standoffs inside the bottom half of the case.
Insert and fasten two M2.5x4mm long steel machine screws to secure the I2S amplifier to the case.
Install Toggle Switch to Case
Remove the hardware nut and washers from the toggle switch.
Insert the toggle switch through the matching hole inside the bottom half of the case.
Secure the toggle switch to the case using the hardware hex nut.
Install NeoPixel to Case
Place the NeoPixel stick over the matching standoffs on the NeoPixel mount.
Insert and fasten two M2x6mm long steel machine screws to secure the NeoPixel to the case.
Install Speaker to Case
Orient the mini over speaker to match the assembly photo.
Press the speaker into the matching recess on the top half of the case.
The speaker holder in the case should have a snug fit. Optionally, remove the oval sticker backing to adhere the speaker to the case.
Connect Speaker to Amplifier
Use a flat head screwdriver to loosen the screw-block terminals on the I2S amplifier.
Insert the red wire from the speaker to the (+) positive screw-block.
Insert the black wire from the speaker to the (–) negative screw-block.
Fasten the screw-block to secure the wires from the speaker in place.
Install I2S Mic to Case
Orient the I2S microphone to match the assembly photo.
Place the I2S microphone over the matching standoffs on the top half of the case.
Insert and fasten two M2.5x4mm long machine screws to secure the I2S microphone to the top half of the case.
Install Button Plate to Case
Place the button plate over the matching standoffs on the top half of the case.
Insert and fasten four M2.5x6mm long machine screws to secure the button plate to the top half of the case.
Install Rotary Pots to Case
Remove the hex nuts and washers from the two rotary potentiometers.
Insert the two rotary potentiometers into the matching holes on the top half of the case.
Install Slide Pot to Case
Insert the slide potentiometer into matching slot and mounting holes on the top half of the case.
Insert and fasten two M2x8mm steel long machine screws to secure the slide potentiometer to the case.
Connect Shared Grounds
Lift the center block tab on the Wago connector to open the connection block.
Insert the spare ground wire from the slide switch into the block.
Press down on the block tab to secure the ground wire.
Repeat the installation process for all of the ground wire connections to tie them together (NeoPixel, I2S microphone, I2S amplifier, potentiometer A, potentiometer B, slide potentiometer, toggle switch, key switch).
Install Ground Block to Case
The Wago block connector can slide into the designated holder in the bottom half of the case.
Connect Shared Voltage Wires
Lift one of the tabs on the second Wago block connector and insert the single 3V wire from the Feather.
Press down on the tab to secure the 3V wire.
Repeat the installation process for all of the red voltage wires (I2S microphone, I2S amplifier, potentiometer A, potentiometer B, slide potentiometer).
Install Voltage Block to Case
The second Wago block connector can slide into the remaining holder in the bottom half of the case.
Secure Pots to Case
Insert and fasten the hex nuts onto the rotary potentiometers to secure them to the case.
Secure Case Halves
Carefully join the two halves together making sure all of the wires stay inside.
Insert and fasten four M3x6mm long steel machine screws to secure the halves together.
Install Knobs and Keycaps
Get the two rotary knobs, slider knob, and keycaps ready to install.
Insert the rotary knobs over the shafts of the potentiometers.
Insert the keycaps onto the key switches.
Insert the fader knob over the nub of the slide potentiometers.
Page last edited July 28, 2026
Text editor powered by tinymce.
Use
Power
Use the slide switch on the right side of the case to power the device on and off.
The NeoPixels light up incrementally while a power-on tune plays to indicate the device is ready to record.
Record Audio
Press the record button to start a recording. The NeoPixels turn red indicating recording is active.
Press the record button again to stop the recording.
The NeoPixel will turn yellow while the audio .WAV file is being written to the CIRCUITPY file system.
Play Audio
Press the play button to playback the recording. The NeoPixels turn green while audio is playing.
The audio will continuously loop.
Press the play button again to stop the audio.
Pitch Shift
Use the slide potentiometer to shift the pitch of the audio.
Move the fader to the left to shift the pitch down.
Move the fader to the right to shift the pitch up.
Move the fader to the center to shift to the original pitch.
Reverb
Turn the potentiometer on the left side to apply a reverb effect to the playing audio.
Turn the potentiometer to the right to increase the amount of reverb.
Turn the potentiometer to the left to decrease the reverb amount.
Page last edited July 28, 2026
Text editor powered by tinymce.