# Walkmp3rson: Personal MP3 'Tape' Player

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/115/097/medium800/projects_walk-8896.jpg?1663126498)

https://youtu.be/fgalBx2QSJ0

https://youtu.be/E4JosIB-JaE

Look the part while you walk around town listening to your favorite mixes. CircuitPython powers this personal music player, with a stylish 3D printed case, TFT display, mech keyswitch controls and more.

Pop in a different "mix tape" SD card when you're in the mood for some different tunes.

https://youtu.be/MNdvsneKSYI?t=1619

## Parts
### Adafruit Feather RP2040

[Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
A new chip means a new Feather, and the Raspberry Pi RP2040 is no exception. When we saw this chip we thought "this chip is going to be awesome when we give it the Feather Treatment" and so we did! This Feather features the&nbsp; **RP2040** , and all niceties you know and...

In Stock
[Buy Now](https://www.adafruit.com/product/4884)
[Related Guides to the Product](https://learn.adafruit.com/products/4884/guides)
![Angled shot of black rectangular microcontroller "Feather RP2040"](https://cdn-shop.adafruit.com/640x480/4884-04.jpg)

### 2.0" 320x240 Color IPS TFT Display with microSD Card Breakout

[2.0" 320x240 Color IPS TFT Display with microSD Card Breakout](https://www.adafruit.com/product/4311)
This gorgeous IPS display breakout is the best way to add a small, colorful, and bright display to any project, with excellent visibility from any angle. Since the display uses 4-wire SPI to communicate and has its own pixel-addressable frame buffer, it can be used with every kind of...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4311)
[Related Guides to the Product](https://learn.adafruit.com/products/4311/guides)
![Overhead video of TFT display running boot-up animation.](https://cdn-shop.adafruit.com/product-videos/640x480/4311-06.jpg)

### NeoKey 1x4 QT I2C - Four Mechanical Key Switches with NeoPixels

[NeoKey 1x4 QT I2C - Four Mechanical Key Switches with NeoPixels](https://www.adafruit.com/product/4980)
The only thing better than a nice mechanical key is, perhaps, FOUR mechanical keys&nbsp;that also can glow any color of the rainbow - and that's what the&nbsp; **Adafruit NeoKey 1x4 QT I2C Breakout** &nbsp;will let you do! This longgg 3" x 0.8" PCB fits...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4980)
[Related Guides to the Product](https://learn.adafruit.com/products/4980/guides)
![Top view video of a fully assembled NeoKey 1x4 QT I2C with switches and smoke gray keycaps powered by a QT Py on a breadboard. A hand reaches down to press the keys, which emit rainbow colors. ](https://cdn-shop.adafruit.com/product-videos/640x480/4980-05.jpg)

### Kailh Mechanical Key Switches - Clicky White - 10 pack

[Kailh Mechanical Key Switches - Clicky White - 10 pack](https://www.adafruit.com/product/4955)
For crafting your very own custom keyboard, these **&nbsp;Kailh&nbsp;White Linear mechanical key switches** &nbsp;are deeee-luxe! With smooth actuation and Cherry MX compatibility, they're lovely when you want a **clicky tactile** keystroke with a snappy feel and an...

In Stock
[Buy Now](https://www.adafruit.com/product/4955)
[Related Guides to the Product](https://learn.adafruit.com/products/4955/guides)
![Angled shot of ten white Kailh key switches.](https://cdn-shop.adafruit.com/640x480/4955-00.jpg)

### Cyan MA Keycaps for MX Compatible Switches - 5 pack

[Cyan MA Keycaps for MX Compatible Switches - 5 pack](https://www.adafruit.com/product/5174)
Dress up your mechanical keys in your favorite colors&nbsp;with a wide selection of gumdrop-like, retro, curvy, and stylish MA profile keycaps. Here is a 5 pack of **Cyan MA Keycaps** for your next mechanical keyboard or&nbsp;<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5174)
[Related Guides to the Product](https://learn.adafruit.com/products/5174/guides)
![Angled shot of five cyan keycaps.](https://cdn-shop.adafruit.com/640x480/5174-02.jpg)

### Adafruit I2C Stemma QT Rotary Encoder Breakout with NeoPixel

[Adafruit I2C Stemma QT Rotary Encoder Breakout with NeoPixel](https://www.adafruit.com/product/4991)
Rotary encoders are soooo much fun! Twist em this way, then twist them that way. Unlike potentiometers, they go all the way around and often have little detents for tactile feedback. But, if you've ever tried to add encoders to your project you know that they're a real challenge to...

In Stock
[Buy Now](https://www.adafruit.com/product/4991)
[Related Guides to the Product](https://learn.adafruit.com/products/4991/guides)
![Top view video of a hand turning the rotary encoder knobs on three PCBs. The NeoPixel LEDs on each PCB change color. The OLED display changes its readout data with each twisty-turn.](https://cdn-shop.adafruit.com/product-videos/640x480/4991-08.jpg)

### FeatherWing Doubler - Prototyping Add-on For All Feather Boards

[FeatherWing Doubler - Prototyping Add-on For All Feather Boards](https://www.adafruit.com/product/2890)
This is the **FeatherWing Doubler** - a prototyping add-on and more for all Feather boards. This is similar to our [FeatherWing Proto](https://www.adafruit.com/products/2884) except there are two! The magic of the Doubler comes when stacking a Feather and another...

In Stock
[Buy Now](https://www.adafruit.com/product/2890)
[Related Guides to the Product](https://learn.adafruit.com/products/2890/guides)
![Double prototyping feather wing PCB with socket headers installed](https://cdn-shop.adafruit.com/640x480/2890-01.jpg)

### Lithium Ion Polymer Battery - 3.7v 1200mAh

[Lithium Ion Polymer Battery - 3.7v 1200mAh](https://www.adafruit.com/product/258)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 1200mAh for a total of about 4.5 Wh. If you need a larger battery, <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/258)
[Related Guides to the Product](https://learn.adafruit.com/products/258/guides)
![Lithium Ion Polymer Battery 3.7v 1200mAh with JST 2-PH connector](https://cdn-shop.adafruit.com/640x480/258-02.jpg)

### Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A

[Adafruit I2S 3W Class D Amplifier Breakout - MAX98357A](https://www.adafruit.com/product/3006)
Listen to this good news - we now have an all in one digital audio amp breakout board that works incredibly well with the&nbsp;[Raspberry Pi](https://www.adafruit.com/category/105)! If you're looking for an easy and low cost way to get your digital sound files...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3006)
[Related Guides to the Product](https://learn.adafruit.com/products/3006/guides)
![Angled shot of blue, square-shaped, amplifier breakout with a pre-soldered terminal block.](https://cdn-shop.adafruit.com/640x480/3006-04.jpg)

### Part: STEMMA QT / Qwiic JST SH 4-pin Cable
quantity: 2
100mm Long
[STEMMA QT / Qwiic JST SH 4-pin Cable](https://www.adafruit.com/product/4210)

### Part: Micro SD Card PCB Extender
quantity: 1
Short
[Micro SD Card PCB Extender](https://www.adafruit.com/product/4395)

### Part: Short Headers Kit for Feather
quantity: 1
12-pin + 16-pin Female Headers
[Short Headers Kit for Feather](https://www.adafruit.com/product/2940)

### Part: Short Feather Male Headers
quantity: 1
12-pin and 16-pin Male Header Set
[Short Feather Male Headers](https://www.adafruit.com/product/3002)

### Part: Panel Mount 1/8" / 3.5mm TRS Audio Jack
quantity: 1
Connector
[Panel Mount 1/8" / 3.5mm TRS Audio Jack](https://www.adafruit.com/product/3692)

Optional:

### Part: Micro Potentiometer Knob
quantity: 1
4 pack, orange
[Micro Potentiometer Knob](https://www.adafruit.com/product/5533)

### Part: Micro SD Memory Card
quantity: 1
128MB
[Micro SD Memory Card](https://www.adafruit.com/product/5250)

### Part: 100K Ohm Resistor
quantity: 1
5% 1/4W - Pack of 25 - Through Hole
[100K Ohm Resistor](https://www.adafruit.com/product/2787)

### Part: SPDT Slide Switch
quantity: 1
Breadboard-friendly
[SPDT Slide Switch](https://www.adafruit.com/product/805)

### Silicone Cover Stranded-Core Wire - 26AWG in Various Colors

[Silicone Cover Stranded-Core Wire - 26AWG in Various Colors](https://www.adafruit.com/product/1970)
Silicone-sheathing wire is super-flexible and soft, and it's also strong! Able to handle up to 200°C and up to 600V, it will do when PVC covered wire wimps out. We like this wire for being extremely supple and flexible, so it is great for wearables or projects where the wire-harness...

Out of Stock
[Buy Now](https://www.adafruit.com/product/1970)
[Related Guides to the Product](https://learn.adafruit.com/products/1970/guides)
![Stranded-core wires in white, gray, black, blue, green, red, orange, and yellow.](https://cdn-shop.adafruit.com/640x480/1970-00.jpg)

### Part: USB Type A to Type C Cable
quantity: 1
Approx. 1 meter / 3 ft long
[USB Type A to Type C Cable](https://www.adafruit.com/product/4474)

### Small Single Row Wire Housing Pack for DIY Jumper Cables

[Small Single Row Wire Housing Pack for DIY Jumper Cables](https://www.adafruit.com/product/3145)
Are you frustrated by the lack of customization options for your jumper wires? Look no further!

Compatible with both male and female wires, these fully customizable wire housings bring DIY to a new level, giving you...

In Stock
[Buy Now](https://www.adafruit.com/product/3145)
[Related Guides to the Product](https://learn.adafruit.com/products/3145/guides)
![Collection of many Small Single Row Wire Housing Packs](https://cdn-shop.adafruit.com/640x480/3145-00.jpg)

### Black Nylon Machine Screw and Stand-off Set – M2.5 Thread

[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)
Totaling 380 pieces, this **M2.5 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M2.5 size screws fit almost all of the Adafruit breakout/dev board mounting holes...

In Stock
[Buy Now](https://www.adafruit.com/product/3299)
[Related Guides to the Product](https://learn.adafruit.com/products/3299/guides)
![Black Nylon Screw and Stand-off Set with M2.5 Threads, kit box](https://cdn-shop.adafruit.com/640x480/3299-00.jpg)

### Multi-Colored Heat Shrink Pack - 3/32" + 1/8" + 3/16" Diameters

[Multi-Colored Heat Shrink Pack - 3/32" + 1/8" + 3/16" Diameters](https://www.adafruit.com/product/1649)
Heat shrink is the duct tape of electronics which I guess makes this heat shrink the colorful and exciting duct tape they sell&nbsp;at craft stores. &nbsp;This heat shrink comes in six different colors - red, blue, green, yellow, white and the traditional black.

Each pack contains ten...

In Stock
[Buy Now](https://www.adafruit.com/product/1649)
[Related Guides to the Product](https://learn.adafruit.com/products/1649/guides)
![Array of many colorful heatshrink tubes.](https://cdn-shop.adafruit.com/640x480/1649-00.jpg)

### Rainbow "Wire Wrap" Thin 30 AWG Prototyping & Repair Wire

[Rainbow "Wire Wrap" Thin 30 AWG Prototyping & Repair Wire](https://www.adafruit.com/product/4730)
This stuff is called "wire-wrap wire" because it used to be used for wire-wrapping high-speed digital circuits on a special kind of contact board. It's pretty rare to see wire-wrapping in these days of low-cost PCB fabrication, but the wire is still really handy for prototyping...

In Stock
[Buy Now](https://www.adafruit.com/product/4730)
[Related Guides to the Product](https://learn.adafruit.com/products/4730/guides)
![Large spool of Rainbow Wire Wrap Thin Prototyping & Repair Wire](https://cdn-shop.adafruit.com/640x480/4730-00.jpg)

### Break-away 0.1" 36-pin strip right-angle male header (10 pack)

[Break-away 0.1" 36-pin strip right-angle male header (10 pack)](https://www.adafruit.com/product/1540)
Breakaway header is like the duct tape of electronics. Its great for connecting things together, soldering to perf-boards, fits into any breadboard, etc. We go through these guys real fast, and thought that given how handy they are, we'd offer them in a pack of ten!  
  
Each pack...

In Stock
[Buy Now](https://www.adafruit.com/product/1540)
[Related Guides to the Product](https://learn.adafruit.com/products/1540/guides)
![Break-away 0.1 inch 36-pin strip right-angle male header](https://cdn-shop.adafruit.com/640x480/1540-00.jpg)

# Walkmp3rson: Personal MP3 'Tape' Player

## CAD Files

## CAD Parts List

STL files for 3D printing are oriented to print "as-is" on FDM style machines. Parts are designed to 3D print without any support material. Original design source may be downloaded using the links below:

- wp-back-cover
- wp-button-case
- wp-button-cover
- wp-front-case
- wp-keyswitch-plate
- wp-switch-holder
- wp-trs-rotary

![projects_cad-explode-2.gif](https://cdn-learn.adafruit.com/assets/assets/000/115/114/medium640thumb/projects_cad-explode-2.jpg?1663180492)

Info: 

[STLs.zip](https://cdn-learn.adafruit.com/assets/assets/000/115/103/original/STLs.zip?1663166447)
[Download CAD Source](https://cdn-learn.adafruit.com/assets/assets/000/115/104/original/cad-source.zip?1663166930)
## Build Volume

The parts require a 3D printer with a minimum build volume.

- 110mm (X) x 70mm (Y) x 30mm (Z)

![projects_slicer-cura.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/111/medium640/projects_slicer-cura.jpg?1663177619)

## Design Source Files

The project assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, STL and more. Electronic components like Adafruit's boards, displays, connectors and more can be downloaded from the&nbsp;[Adafruit CAD parts GitHub Repo](https://github.com/adafruit/Adafruit_CAD_Parts).

![projects_4311-2in-TFT-IPS-Display.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/112/medium640/projects_4311-2in-TFT-IPS-Display.jpg?1663177722)

# Walkmp3rson: Personal MP3 'Tape' Player

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) 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.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_feather_rp2040/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/102/705/medium800/adafruit_products_FeatherRP_buttons_highlighted.jpg?1623167565)

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).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 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 **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## 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.

### Entering Safe Mode
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.

```terminal
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 RPI-RP2. 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.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/101/659/original/flash_nuke.uf2?1618945856)
# Walkmp3rson: Personal MP3 'Tape' Player

## Code the Walkmp3rson

Warning: 

[Follow these steps to create the /sd directory](https://learn.adafruit.com/adafruit-memento-camera-board/circuitpython-memento-starter-projects)
## Text Editor

Adafruit recommends using the **Mu** editor for editing your CircuitPython code. You can get more info in [this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves simple text files.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, sample .mp3s, graphic .bmp, and the&nbsp; **code.py** &nbsp;file. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;link below, and uncompress the .zip file.

Drag the contents of the uncompressed bundle directory onto your board's **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

## Audio Files

Copy the .mp3 files from the bundle onto your SD card using a USB SD card reader.

To make your own files, follow the info in [this guide](https://learn.adafruit.com/mp3-playback-rp2040/pico-i2s-mp3#i2s-mp3-file-playback-3102163) on converting audio files to mono .mp3 files.

Danger: 

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Walkmp3rson/code.py

## How it Works

First, there are a dozen or so libraries to install! These help us use the SD card, TFT display, audio mixer and mp3 decoder, NeoKeys, rotary encoder, and more.

```python
import time
import os
import board
import busio
import sdcardio
import storage
import audiomixer
import audiobusio
import audiomp3
from adafruit_neokey.neokey1x4 import NeoKey1x4
from adafruit_seesaw import seesaw, rotaryio
import displayio
import fourwire
import terminalio
from adafruit_display_text import label
from adafruit_st7789 import ST7789
from adafruit_progressbar.progressbar import HorizontalProgressBar
from adafruit_progressbar.verticalprogressbar import VerticalProgressBar
```

## Setup

Next, the TFT display is set up on the SPI bus.

```auto
displayio.release_displays()

# SPI for TFT display, and SD Card reader on TFT display
spi = board.SPI()
# display setup
tft_cs = board.D6
tft_dc = board.D9
tft_reset = board.D12
display_bus = fourwire.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_reset)
display = ST7789(display_bus, width=320, height=240, rotation=90)
```

Then, the SD card reader is set up, also on SPI.

```auto
# SD Card setup
sd_cs = board.D13
sdcard = sdcardio.SDCard(spi, sd_cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")
```

### NeoKey

The NeoKey is set up on the I2C bus next, including color definitions and key states.

```auto
# I2C NeoKey setup
i2c = busio.I2C(board.SCL, board.SDA)
neokey = NeoKey1x4(i2c, addr=0x30)
amber = 0x300800
red = 0x900000
green = 0x009000

neokey.pixels.fill(amber)
keys = [
    (neokey, 0, green),
    (neokey, 1, red),
    (neokey, 2, green),
    (neokey, 3, green),
]
#  states for key presses
key_states = [False, False, False, False]
```

### Rotary Encoder

The rotary encoder is set up as a seesaw device.

```auto
# STEMMA QT Rotary encoder setup
rotary_seesaw = seesaw.Seesaw(i2c, addr=0x36)  # default address is 0x36
encoder = rotaryio.IncrementalEncoder(rotary_seesaw)
last_encoder_pos = 0
```

### SD Card Filesystem

To read the .mp3 files from the SD card, the filesystem is defined and listed.

```auto
# file system setup
mp3s = []
for filename in os.listdir('/sd'):
    if filename.lower().endswith('.mp3') and not filename.startswith('.'):
        mp3s.append("/sd/"+filename)

mp3s.sort()  # sort alphanumerically for mixtape  order, e.g., "1_King_of_Rock.mp3"
for mp3 in mp3s:
    print(mp3)
    
track_number = 0
mp3_filename = mp3s[track_number]
mp3_bytes = os.stat(mp3_filename)[6]  # size in bytes is position 6
mp3_file = open(mp3_filename, "rb")
mp3stream = audiomp3.MP3Decoder(mp3_file)
```

### Tracktext Function

This function is used to parse the track names for display, removing the track number from the beginning, and returning the Artist Name and Song Name for display. This is the naming convention:

`number_artist_song.mp3`

For example:

**03\_Bartlebeats\_Daisy.mp3** &nbsp;

That will be the third song on the "mix tape" SD card, with the artist name **Bartlebeats** and song name **Daisy**.

```auto
def tracktext(full_path_name, position):
    return full_path_name.split('_')[position].split('.')[0]
```

### Audio

The audio is set up as an I2S audio output on the audiobus with pins defined for word select, bit clock, and data.

```auto
# LRC is word_select, BCLK is bit_clock, DIN is data_pin.
# Feather RP2040
audio = audiobusio.I2SOut(bit_clock=board.D24, word_select=board.D25, data=board.A3)
# Feather M4
# audio = audiobusio.I2SOut(bit_clock=board.D1, word_select=board.D10, data=board.D11)
```

### Mixer

The mixer object is created, with the specific settings we're using for the .mp3 files and an initial volume level.

```auto
mixer = audiomixer.Mixer(voice_count=1, sample_rate=22050, channel_count=1,
                         bits_per_sample=16, samples_signed=True)
mixer.voice[0].level = 0.15
```

### Screen Colors

Colors are defined for screen text and graphics.

```auto
# Colors
blue_bright = 0x17afcf
blue_mid = 0x0d6173
blue_dark = 0x041f24

orange_bright = 0xda8c57
orange_mid = 0xa46032
orange_dark = 0x472a16
```

### Displayio

The displayio group and on disk bitmap are defined next.

```auto
display
main_display_group = displayio.Group()  # everything goes in main group
display.root_group = main_display_group  # show main group (clears screen, too)

# background bitmap w OnDiskBitmap
tape_bitmap = displayio.OnDiskBitmap(open("mp3_tape.bmp", "rb"))
tape_tilegrid = displayio.TileGrid(tape_bitmap, pixel_shader=tape_bitmap.pixel_shader)
main_display_group.append(tape_tilegrid)
```

### Text Labels

The text for song and artist are set up here.

```auto
# song name label
song_name_text_group = displayio.Group(scale=3, x=90, y=44)  # text label goes in this Group
song_name_text = tracktext(mp3_filename, 2)
song_name_label = label.Label(terminalio.FONT, text=song_name_text, color=orange_bright)
song_name_text_group.append(song_name_label)  # add the label to the group
main_display_group.append(song_name_text_group)  # add to the parent group

# artist name label
artist_name_text_group = displayio.Group(scale=2, x=92, y=186)
artist_name_text = tracktext(mp3_filename, 1)
artist_name_label = label.Label(terminalio.FONT, text=artist_name_text, color=orange_bright)
artist_name_text_group.append(artist_name_label)
main_display_group.append(artist_name_text_group)
```

### Progress Bars

We're using the horizontal progress bar to visualize song length and a vertical progress bar for volume.

```auto
# song progress bar
progress_bar = HorizontalProgressBar(
    (72, 144),
    (174, 12),
    bar_color=blue_bright,
    outline_color=blue_mid,
    fill_color=blue_dark,
)
main_display_group.append(progress_bar)

# volume level bar
volume_bar = VerticalProgressBar(
    (304, 40),
    (8, 170),
    bar_color=orange_bright,
    outline_color=orange_mid,
    fill_color=orange_dark,
)
main_display_group.append(volume_bar)
volume_bar.value = mixer.voice[0].level * 100
```

### `change_track()` Function

This function is called whenever a track change happens. This can be when the previous or next song buttons are pressed, or when one song ends and the next needs to begin.

```auto
def change_track(tracknum):

    global mp3_filename
    mp3_filename = mp3s[tracknum]
    song_name_fc = tracktext(mp3_filename, 2)
    artist_name_fc = tracktext(mp3_filename, 1)
    mp3_file_fc = open(mp3_filename, "rb")
    mp3stream_fc = audiomp3.MP3Decoder(mp3_file_fc)
    mp3_bytes_fc = os.stat(mp3_filename)[6]  # size in bytes is position 6
    return (mp3_file_fc, mp3stream_fc, song_name_fc, artist_name_fc, mp3_bytes_fc)
```

### States

State variables are set, and then the audio mixer is turned on.

```auto
play_state = False  # so we know if we're auto advancing when mixer finishes a song
last_debug_time = 0  # for timing track position
last_percent_done = 0.01

audio.play(mixer)
```

## Main Loop

The main loop of the program does the following:

- Checks for encoder input to change volume
- Checks the NeoKeys for input
- Plays the current song until it is paused, finishes, is restarted, or next/previous buttons are pressed

```auto
while True:
    encoder_pos = -encoder.position
    if encoder_pos != last_encoder_pos:
        encoder_delta = encoder_pos - last_encoder_pos
        volume_adjust = min(max((mixer.voice[0].level + (encoder_delta*0.005)), 0.0), 1.0)
        mixer.voice[0].level = volume_adjust

        last_encoder_pos = encoder_pos
        volume_bar.value = mixer.voice[0].level * 100

    if play_state is True:  # if not stopped, auto play next song
        if time.monotonic() - last_debug_time &gt; 0.2:  # so we can check track progress
            last_debug_time = time.monotonic()
            bytes_played = mp3_file.tell()
            percent_done = (bytes_played / mp3_bytes)
            progress_bar.value = min(max(percent_done * 100, 0), 100)

        if not mixer.playing:
            print("next song")
            audio.pause()
            track_number = ((track_number + 1) % len(mp3s))
            mp3_file, mp3stream, song_name, artist_name, mp3_bytes = change_track(track_number)
            song_name_label.text = song_name
            artist_name_label.text = artist_name
            mixer.voice[0].play(mp3stream, loop=False)
            time.sleep(.1)
            audio.resume()

    # Use the NeoKeys as transport controls
    for k in range(len(keys)):
        neokey, key_number, color = keys[k]
        if neokey[key_number] and not key_states[key_number]:
            key_states[key_number] = True
            neokey.pixels[key_number] = color

            if key_number == 0:  # previous track
                audio.pause()
                track_number = ((track_number - 1) % len(mp3s) )
                mp3_file, mp3stream, song_name, artist_name, mp3_bytes = change_track(track_number)
                song_name_label.text = song_name
                artist_name_label.text = artist_name
                mixer.voice[0].play(mp3stream, loop=False)
                play_state = True
                time.sleep(.1)
                audio.resume()

            if key_number == 1:  # Play/pause
                if play_state:
                    audio.pause()
                    play_state = False
                else:
                    audio.resume()
                    play_state = True

            if key_number == 2:  # Play track from beginning
                audio.pause()
                mixer.voice[0].play(mp3stream, loop=False)
                song_name_label.text = tracktext(mp3_filename, 2)
                artist_name_label.text = tracktext(mp3_filename, 1)
                play_state = True
                time.sleep(.1)
                audio.resume()

            if key_number == 3:  # next track
                audio.pause()
                track_number = ((track_number + 1) % len(mp3s))
                mp3_file, mp3stream, song_name, artist_name, mp3_bytes = change_track(track_number)
                song_name_label.text = song_name
                artist_name_label.text = artist_name
                mixer.voice[0].play(mp3stream, loop=False)
                play_state = True
                time.sleep(.1)
                audio.resume()

        if not neokey[key_number] and key_states[key_number]:
            neokey.pixels[key_number] = amber
            key_states[key_number] = False
```

# Walkmp3rson: Personal MP3 'Tape' Player

## Build the Walkmp3rson Circuit

![](https://cdn-learn.adafruit.com/assets/assets/000/115/099/medium800/projects_walkmp3rson_breadboard.jpg?1663128562)

![](https://cdn-learn.adafruit.com/assets/assets/000/114/934/medium800/projects_walkmp3an_06_fritz.jpg?1663025689)

## Display Connection

First, solder in the short Feather headers as shown in the picture here. Be sure to use the short headers or the case will not fit!

Wire the display as shown in the Fritzing diagram and the photos here to the FeatherWing Doubler.&nbsp;&nbsp;

Note: the photos can be confusing, always double check against the circuit diagram!

There are many ways to do this -- I soldered on right angled headers and Dupont connector silicone jumper wires.

![projects_walk-8843.jpg](https://cdn-learn.adafruit.com/assets/assets/000/114/993/medium640/projects_walk-8843.jpg?1663120778)

![projects_walk-8844.jpg](https://cdn-learn.adafruit.com/assets/assets/000/114/994/medium640/projects_walk-8844.jpg?1663120784)

## Amp Prep

Solder on header pins to the amp board so you can mount it to the Doubler.

I chose to solder a small socket header to connect the amp breakout to the headphone jack using jumper cables later.

![projects_walk-8846.jpg](https://cdn-learn.adafruit.com/assets/assets/000/114/997/medium640/projects_walk-8846.jpg?1663123332)

## Amp Connections

Solder the amp breakout to the long free row of the doubler as shown.

Then, use short wires (such as wire scavenged from an old CAT5 cable or solid core hook up wire with the insulation scraped off at the ends) to connect the legs to their respective pins on the Feather via the Doubler connections.

![projects_walk-8847.jpg](https://cdn-learn.adafruit.com/assets/assets/000/114/998/medium640/projects_walk-8847.jpg?1663123447)

![projects_walk-8850.jpg](https://cdn-learn.adafruit.com/assets/assets/000/114/999/medium640/projects_walk-8850.jpg?1663123548)

## Amp Gain Resistor

Solder a 100KΩ resistor from the Gain pin to the Vin pin. This sets the amplifier gain to 3dB, which works well for the headphone output.

![projects_walk-8851.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/000/medium640/projects_walk-8851.jpg?1663123591)

## Headphone Out

To keep the project simple we're using a single mono amplifier. Since most headphones have a stereo TRS 3.5mm plug, you'll run the audio signal to both the tip and ring connectors.

Run a single wire to the ground connector.

I used Dupont connector cables for this and dressed them with heat shrink tubing.

![projects_walk-8852.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/001/medium640/projects_walk-8852.jpg?1663123807)

![projects_walk-8854.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/002/medium640/projects_walk-8854.jpg?1663123829)

![](https://cdn-learn.adafruit.com/assets/assets/000/115/007/medium800/projects_walk-8856.jpg?1663123999)

## On/Off Switch

Solder a wire from the Doubler/Feather **Enable** pin to one side of a SPDT switch, and another wire from GND to the center position of the switch.

![projects_walk-8858.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/014/medium640/projects_walk-8858.jpg?1663124009)

![projects_walk-8857.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/015/medium640/projects_walk-8857.jpg?1663124025)

![](https://cdn-learn.adafruit.com/assets/assets/000/115/022/medium800/projects_walk-8859.jpg?1663124158)

## NeoKey 1x4 and QT Rotary Encoder

Use STEMMA QT cables to connect the Feather to the NeoKeys and rotary encoder breakout.

Plug in the battery as well -- since the amp Vin is connected to the Feather's Bat output you'll need the battery connected even when plugged into USB for coding.

![projects_walk-8860.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/029/medium640/projects_walk-8860.jpg?1663124267)

![projects_walk-8861.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/030/medium640/projects_walk-8861.jpg?1663124284)

![](https://cdn-learn.adafruit.com/assets/assets/000/115/037/medium800/projects_walk-8862.jpg?1663124391)

# Walkmp3rson: Personal MP3 'Tape' Player

## Assemble the Walkmp3rson

![](https://cdn-learn.adafruit.com/assets/assets/000/115/046/medium800/projects_walk-8867b.jpg?1663124916)

## Case Parts

Print the case parts in 80s-tastic colors (or any colors you like). The files and notes for printing can be found on the **CAD Files** page.

Then, screw in the nylon standoffs for the Doubler mounting.

## Display Mount

Mount the display as shown, using M2.5 hardware.

![projects_walk-8870.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/047/medium640/projects_walk-8870.jpg?1663125034)

## Feather Doubler Mount

Connect the Doubler to the standoffs as shown.

![projects_walk-8871.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/048/medium640/projects_walk-8871.jpg?1663125084)

![](https://cdn-learn.adafruit.com/assets/assets/000/115/051/medium800/projects_walk-8872.jpg?1663125118)

## Switch Mount

Mount the switch into the switch housing thingamajob.

![projects_walk-8873.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/052/medium640/projects_walk-8873.jpg?1663125139)

## Button Mount

Insert the keyswitches into the mounting plate.

Then, insert the assembly into the case top.

Carefully press the switches into the NeoKey PCB.

Once assembled, add your keycaps.

![projects_walk-8875.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/053/medium640/projects_walk-8875.jpg?1663125190)

![projects_walk-8876.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/054/medium640/projects_walk-8876.jpg?1663125218)

![projects_walk-8877.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/055/medium640/projects_walk-8877.jpg?1663125226)

![projects_walk-8878.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/056/medium640/projects_walk-8878.jpg?1663125234)

![](https://cdn-learn.adafruit.com/assets/assets/000/115/063/medium800/projects_walk-8879.jpg?1663125345)

## Rotary Mount

Fit the rotary encoder breakout into the case side, then place the washer over the shaft. Screw on the nut to secure it in place.

Add a knob to the shaft as shown.

![projects_walk-8880.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/065/medium640/projects_walk-8880.jpg?1663125383)

![projects_walk-8882.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/066/medium640/projects_walk-8882.jpg?1663125395)

![projects_walk-8881.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/067/medium640/projects_walk-8881.jpg?1663125416)

## SD Card Extender

Insert the prepared SD card mix tape into the SD card extender, then insert it all into the display as shown.

![projects_walk-8883.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/068/medium640/projects_walk-8883.jpg?1663125853)

![projects_walk-8884.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/069/medium640/projects_walk-8884.jpg?1663125859)

## On/Off Mount

Use M2.5 hardware to fasten the switch mount to the case as shown.

![projects_walk-8885.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/073/medium640/projects_walk-8885.jpg?1663126084)

![projects_walk-8886.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/074/medium640/projects_walk-8886.jpg?1663126090)

## STEMMA QT Connections

Use 100mm STEMMA QT cables to connect the Feather RP2040 to the rotary encoder and NeoKey breakout.

Insert the panel mount headphone jack and screw on the retaining nut.

![projects_walk-8887.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/071/medium640/projects_walk-8887.jpg?1663125972)

![projects_walk-8888.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/072/medium640/projects_walk-8888.jpg?1663126038)

## Final Assembly

Press fit the front and back together and use the side piece to hold them together.

Then, press the top piece into place.

![projects_walk-8889.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/075/medium640/projects_walk-8889.jpg?1663126145)

![projects_walk-8890.jpg](https://cdn-learn.adafruit.com/assets/assets/000/115/076/medium640/projects_walk-8890.jpg?1663126209)

![](https://cdn-learn.adafruit.com/assets/assets/000/115/082/medium800/projects_walk-8892.jpg?1663126283)


## Featured Products

### Adafruit Feather RP2040

[Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
A new chip means a new Feather, and the Raspberry Pi RP2040 is no exception. When we saw this chip we thought "this chip is going to be awesome when we give it the Feather Treatment" and so we did! This Feather features the&nbsp; **RP2040** , and all niceties you know and...

In Stock
[Buy Now](https://www.adafruit.com/product/4884)
[Related Guides to the Product](https://learn.adafruit.com/products/4884/guides)
### 2.0" 320x240 Color IPS TFT Display with microSD Card Breakout

[2.0" 320x240 Color IPS TFT Display with microSD Card Breakout](https://www.adafruit.com/product/4311)
This gorgeous IPS display breakout is the best way to add a small, colorful, and bright display to any project, with excellent visibility from any angle. Since the display uses 4-wire SPI to communicate and has its own pixel-addressable frame buffer, it can be used with every kind of...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4311)
[Related Guides to the Product](https://learn.adafruit.com/products/4311/guides)
### NeoKey 1x4 QT I2C - Four Mechanical Key Switches with NeoPixels

[NeoKey 1x4 QT I2C - Four Mechanical Key Switches with NeoPixels](https://www.adafruit.com/product/4980)
The only thing better than a nice mechanical key is, perhaps, FOUR mechanical keys&nbsp;that also can glow any color of the rainbow - and that's what the&nbsp; **Adafruit NeoKey 1x4 QT I2C Breakout** &nbsp;will let you do! This longgg 3" x 0.8" PCB fits...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4980)
[Related Guides to the Product](https://learn.adafruit.com/products/4980/guides)
### Kailh Mechanical Key Switches - Clicky White - 10 pack

[Kailh Mechanical Key Switches - Clicky White - 10 pack](https://www.adafruit.com/product/4955)
For crafting your very own custom keyboard, these **&nbsp;Kailh&nbsp;White Linear mechanical key switches** &nbsp;are deeee-luxe! With smooth actuation and Cherry MX compatibility, they're lovely when you want a **clicky tactile** keystroke with a snappy feel and an...

In Stock
[Buy Now](https://www.adafruit.com/product/4955)
[Related Guides to the Product](https://learn.adafruit.com/products/4955/guides)
### Cyan MA Keycaps for MX Compatible Switches - 5 pack

[Cyan MA Keycaps for MX Compatible Switches - 5 pack](https://www.adafruit.com/product/5174)
Dress up your mechanical keys in your favorite colors&nbsp;with a wide selection of gumdrop-like, retro, curvy, and stylish MA profile keycaps. Here is a 5 pack of **Cyan MA Keycaps** for your next mechanical keyboard or&nbsp;<a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/5174)
[Related Guides to the Product](https://learn.adafruit.com/products/5174/guides)
### Adafruit I2C Stemma QT Rotary Encoder Breakout with NeoPixel

[Adafruit I2C Stemma QT Rotary Encoder Breakout with NeoPixel](https://www.adafruit.com/product/4991)
Rotary encoders are soooo much fun! Twist em this way, then twist them that way. Unlike potentiometers, they go all the way around and often have little detents for tactile feedback. But, if you've ever tried to add encoders to your project you know that they're a real challenge to...

In Stock
[Buy Now](https://www.adafruit.com/product/4991)
[Related Guides to the Product](https://learn.adafruit.com/products/4991/guides)
### FeatherWing Doubler - Prototyping Add-on For All Feather Boards

[FeatherWing Doubler - Prototyping Add-on For All Feather Boards](https://www.adafruit.com/product/2890)
This is the **FeatherWing Doubler** - a prototyping add-on and more for all Feather boards. This is similar to our [FeatherWing Proto](https://www.adafruit.com/products/2884) except there are two! The magic of the Doubler comes when stacking a Feather and another...

In Stock
[Buy Now](https://www.adafruit.com/product/2890)
[Related Guides to the Product](https://learn.adafruit.com/products/2890/guides)
### Lithium Ion Polymer Battery - 3.7v 1200mAh

[Lithium Ion Polymer Battery - 3.7v 1200mAh](https://www.adafruit.com/product/258)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 1200mAh for a total of about 4.5 Wh. If you need a larger battery, <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/258)
[Related Guides to the Product](https://learn.adafruit.com/products/258/guides)

## Related Guides

- [Adafruit MAX98357 I2S Class-D Mono Amp](https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp.md)
- [Adafruit 2.0" 320x240 Color IPS TFT Display](https://learn.adafruit.com/2-0-inch-320-x-240-color-ips-tft-display.md)
- [Introducing Adafruit Feather RP2040](https://learn.adafruit.com/adafruit-feather-rp2040-pico.md)
- [Adafruit I2C QT Rotary Encoder](https://learn.adafruit.com/adafruit-i2c-qt-rotary-encoder.md)
- [Adafruit NeoKey 1x4 QT I2C Breakout](https://learn.adafruit.com/neokey-1x4-qt-i2c.md)
- [Neocontroller Color Grading Input Box](https://learn.adafruit.com/neocontroller-color-grading-input-box.md)
- [LED Matrix Wall Arcade for Pico-8](https://learn.adafruit.com/led-matrix-wall-arcade.md)
- [Introducing Adafruit Feather](https://learn.adafruit.com/adafruit-feather.md)
- [Square NeoPixel Display with Black LED Acrylic](https://learn.adafruit.com/sqaure-neopixel-display-with-black-led-acrylic.md)
- [MIDI Laser Harp with Time of Flight Distance Sensors](https://learn.adafruit.com/midi-laser-harp-time-of-flight-sensors.md)
- [CircuitPython OctoPrint Controller and Monitor](https://learn.adafruit.com/circuitpython-octoprint-controller-and-monitor.md)
- [ItsyBitsy ESP32 wFL case](https://learn.adafruit.com/itsybitsy-esp32-wfl-case.md)
- [4x4 Rotary Encoder MIDI Messenger](https://learn.adafruit.com/4x4-rotary-encoder-midi-messenger.md)
- [NeoPixel Menorah](https://learn.adafruit.com/neopixel-menorah.md)
- [reef-pi Guide 2: Power Controller](https://learn.adafruit.com/reef-pi-power-controller.md)
- [MIDI for Makers](https://learn.adafruit.com/midi-for-makers.md)
- [Blahaj Alarm and Lamp](https://learn.adafruit.com/blahaj-alarm.md)
- [Adafruit Floppy FeatherWing with 34-Pin IDC Connector](https://learn.adafruit.com/adafruit-floppy-featherwing-with-34-pin-idc-connector.md)
- [RGB & HSV NeoPixel Dialer](https://learn.adafruit.com/rgb-hsv-neopixel-dialer.md)
- [Sketch Drawing Toy with CircuitPython](https://learn.adafruit.com/sketch-drawing-toy.md)
