

Pico player pcb
Music player for Raspberry Pi Pico and a pair of SN76489s
- Size
- 57.9 × 65.5 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 23
- Nets
- 55
- Pads
- 169
- Tracks, vias
- 194, 0
- Pours
- 2
- Routed
- Yes
- KiCad
- KiCad 5 (file 20171130)
- Created
- 8 Feb 2021
- Updated
- 26 Apr 2021
Overview
Pico player pcb is an open-source printed circuit board by jstanley0, from the jstanley0/pico-player repository on GitHub, published under the MIT licence. It is a 2-layer board of 57.9 × 65.5 mm with 23 parts on 55 nets, routed with 194 tracks and 0 vias.
Its parts include 8 resistors, 8 diodes, 3 ICs, 2 capacitors and 1 connector. It belongs with the RP2040 boards of this library.
README
README.mdpico-player
Music player for Raspberry Pi Pico and a pair of SN76489s
Installation
- Copy the contents of
firmware(sound.pyandmusic_player.pyto your Pico), viarshell cp firmware/* /pyboardor pasting into Thonny, etc.
Playing songs from the Pico's file system
- On your computer, run
python3 util/convert_midi.py example.mid example.dat - Copy the output to the Pico via e.g.
rshell cp example.dat /pyboard. It is a binary file so pasting it via an IDE isn't going to work. - On the Pico, instantiate a MusicPlayer and play the song:
from music_player import MusicPlayer
mp = MusicPlayer()
mp.play_song('example.dat')Playing MIDI files from a connected computer
- run
python3 util/convert_midi.py example.mid -
How it works
- A (very) short PIO program clocks both sound chips. This could also be done with PWM, but the fractional multiplier on the Pico's PIO controller gives us a lot of flexibility on what frequency to clock the chips at, and since the chip has only a 10-bit frequency register, there are tradeoffs between clock rate and usable note range.
- Another short PIO program sends data to both chips. It just tosses 10 bits at the first ten GPIOs, where the first eight go to both chips' data lines, and the last two go to each chip's Write Enable line. By setting exactly one of those bits, I control which sound chip latches the value. The PIO program then waits the requisite 32 cycles for the SN76489 to complete the I/O, while the main Python program keeps running! It just tosses a value in the FIFO and forgets. It's magic.
- A timer callback fires every 50ms and manages the sound envelope for each playing note, and also updates the brightness of each LED.
- The LEDs are managed with PWM. The Pico has sixteen PWM channels and they work with any of the GPIOs. It's magic.
The hard part
Getting music data into a usable format is tricky. I wrote a script (util/convert_midi.py) that translates note-on and note-off events into a simple binary format that the microcontroller program can parse and play. The primary challenge is that we have only six notes of polyphony to work with, so it works best with simple MIDI files. I suggest opening files in e.g. MuseScore beforehand to identify channels to prioritize (with -p) or exclude (with -x). If no arguments are given, convert_midi.py will prioritize channels in tracks named "melody" or "vocals".
Bill of Materials
- one Raspberry Pi Pico
- two SN76489 sound chips
- two 10uF electrolytic capacitors (the value isn't critical)
- one stereo 3.5mm audio jack (CUI SJ1-3533NG)
- (optionally) one dual-gang 10k potentiometer for volume control (Alps RK09L)
Wiring (see KiCad schematic in hardware/pico-player-pcb)

- VBUS to both chips' VCC (pin 16)
- GND to both chips' GND (pin 8)
- GPIOs 0..7 to the data lines of both sound chips in parallel (GPIO 0 to pin 10)
- GPIO 8 to the left chip's /WE line (pin 5)
- GPIO 9 to the right chip's /WE line
- GPIO 10 to the left chip's /OE line (pin 6)
- GPIO 11 to the right chip's /OE line
- GPIO 12 to both chips' clock (pin 14)
- Both sound chips' READY disconnected (it's 5V logic anyway)
- GPIOs 15..22 to the blinkenlights!
Parts
23| Qty | Value | Footprint | References |
|---|---|---|---|
| 8 | LED | LED_THT:LED_D5.0mm_Clear | LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8 |
| 8 | R | Resistor_THT:R_Axial_DIN0309_L9.0mm_D3.2mm_P2.54mm_Vertical | R1, R2, R3, R4, R5, R6, R7, R8 |
| 2 | CP | Capacitor_THT:CP_Radial_D5.0mm_P2.50mm | C1, C2 |
| 2 | SN76489 | Package_DIP:DIP-16_W7.62mm | U2, U3 |
| 1 | AudioJack3 | Connector_Audio:Jack_3.5mm_CUI_SJ1-3533NG_Horizontal | J1 |
| 1 | Pico | RP:RPi_Pico_SMD_TH | U1 |
| 1 | R_POT_Dual | Potentiometer_THT:Potentiometer_Alps_RK09L_Double_Vertical | RV1 |
Questions
How big is the Pico player pcb PCB?
It measures 57.9 × 65.5 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Pico player pcb use?
23 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the Pico player pcb KiCad files?
From the jstanley0/pico-player repository on GitHub, at the commit this page was made from: the board is pico-player-pcb/pico-player-pcb.kicad_pcb. PCBKit opens the board in the browser, with nothing to install.
Can I use the Pico player pcb design in my own project?
Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).
Similar boards
- 2 layers65 × 56 mm

- 2 layers14 × 100 mm

Yunomi
google/mozc-devices
Circuit diagrams and firmware source code for Gboard DIY keyboards
23 parts3kApache-2.0 - 2 layers50.8 × 52.2 mm

- 2 layers138.8 × 89.8 mm

- 2 layers32.9 × 53.3 mm

- 2 layers35.5 × 50 mm

- 2 layers19 × 19 mm

- 2 layers88.5 × 28 mm

ExpBreakout
Duet3D/Duet-2-Hardware
The KiCAD source for the Duet 3d printer controller see www.duet3d.com
23 parts258