Record Player! a Real Player That Plays Fake Records.
by lennyomg in Circuits > Raspberry Pi
433 Views, 4 Favorites, 0 Comments
Record Player! a Real Player That Plays Fake Records.


This is Owntone media server in retro-style body. It plays local files and streams Spotify to local speakers or Apple HomePods. Disks are NFC tags. A Python application connects the NFC reader, LED lights, input controls, and controls Owntone using its RESTful API. Everything is running on a headless Raspberry Pi with a little help from a CircuitPython development board. And a small motor inside spins a disk.
Source code and all supporting files are available on GitHub.
Raspberry Pi
The shell has mounting holes for Pi Zero and Pi Model 3 A+. Pi Zero has a longer booting time, but takes up less space. Pi 3 generates more heat, but is more responsive and Wi-Fi is better. I choose Pi Zero W 2 for now. It hiccups sometimes, but I can live with that.
Get an SD card and flash it with Raspberry Pi OS Bookworm Lite 64-bit. I had mixed results with Bullseye. Add these two lines in config.txt to enable SPI and UART.
Audio


The Pi Model 3 A+ has a 3.5mm headphone jack, but it is no good. Audio I2S HAT is the way to go. I've got Adafruit I2S 3W Stereo Speaker Bonnet. This guide should work for all I2S HATs.
As for speakers - any 3W or 5W will do. I salvaged mine from an Amazon Basic Speaker, which I had from one of my previous projects. Sound quality is... good enough. Glue the speakers into the side walls with a hot glue gun.
Motor


Take an N20 DC motor that works from 6V and has a speed of 10-30 RPM. Optionally, solder a ceramic capacitor between the motor terminals to reduce noise and smooth spinning at low speeds. Do not lube the motor with liquid oil; it makes the noise worse.
To control the motor, I use L9110H H-Bridge Motor Driver (pay attention to the pinout in the datasheet). It protects the Pi from back EMF and spins the motor forward and backward.
CAUTION: Never connect a DC motor directly to Pi GPIOs. It might work, but you can fry your Pi because of back EMF and high current usage.
The spinning part of the shell is connected to the panel with a 30x42x7mm bearing.
In case you need to print a custom gear:
- Pitch circle diameter: 60mm and 12mm
- Number of teeth: 60 and 12
- Module: 1mm
The motor mount is designed to be detachable, so you can design and print your own mount and then screw it to the body with two M2 screws. Add some anti-vibration material like rubber or foam between the mount and the shell to reduce noise.
Disks




This is where the magic happens. Each printed disk has a small NFC sticker tag under the cover. An NFC reader is located inside the spinning part, but the reader doesn't spin! Each tag id is associated with an album or playlist in Owntone.
PN532 is a common choice for an NFC reader, but most of them are too big for this project. I recommend this board from HiLetgo; it is small and fits nicely into the spinning part.
You must use the SPI interface with PN532. The I2C interface on this chip doesn't work reliably with Raspberry Pi because of I2C clock stretching. Configure the NFC module to use SPI by physically flipping an SMB header on the PCB.
Print covers on sticky paper with a size of 70x70mm, stick them to a disk, and cut them with a razor knife.
Controls

Three knobs on the control panel are:
A rotary switch, ideally 1P3T. I have 2P6T with a limiter, so it has only 3 positions:
- Enable "turn off" for PowerBoost.
- Select local speakers.
- Select remote speakers.
A generic potentiometer with an internal switch, like this one. The potentiometer controls volume, the switch acts like mute.
A generic rotary encoder for skipping tracks and play/pause.
To add some light, I cut 10 LEDs from this WS2812B 144-LED 3.3-foot strip. I think any NeoPixel strip will work. Adafruit has an excellent guide about it.
Power


CAUTION: Always check battery polarity with a voltmeter before connecting it.
I have a 10000 mAh Li-Po battery, but if I were you, I'd go with 5000 mAh. PowerBoost 1000 Charger provides stable 5V and charges the battery fast. There are much more affordable options, but again, it is what I had already. The PowerBoost is connected to a USB-C breakout with CC resistors. The mount for the USB breakout is a separate part, so you can design your own and print it without re-printing the whole shell.
Skip the PowerBoost if you don't need a battery. Just connect VS and GND from your USB-C connector to the Pi power pins.
Wiring



Perma-Proto is amazing. Do yourself a favor and use JST connectors on the protoboard. It is much easier to assemble and disassemble the project this way. Carefully follow the schematic and solder everything together. Pay attention to component orientation.
Here is a list of materials I used:
- 26 AWG wires for power lines and audio
- 30 AWG wires for data lines
- 2.54mm JST connectors
- Jumper wires for the protoboard
- Standoff screws
Do not use pins #18, #19, #21 - they are reserved for I2S audio.
Printing and Assembling


Main body is Basic PLA. Side panels are Bambu PLA Wood. LED defuser is translucent PETG. I printed everything in 0.16 High Quality profile with Bambu A1 Mini. Depending on body color, you may want to increase infill up to 75% (grid) to avoid light-bleeding from LEDs. Top parts must snap into place. Side walls or any other loose parts can be secured with thin double-sided tape. Bottom panel is fixed with six M2 screws.
Owntone
Follow Owntone documentation on how to build and configure it. It is actually not that difficult.
Install dependencies.
Clone repository.
Instead of building from the master branch, switch to a release using tags.
Build.
Go through the config file and update settings according to your needs.
I only changed Spotify settings.
Create music folder.
Enable Owntone service.
Now Owntone should be available at http://<pi-host-name>:3689.
Spotify
In Owntone interface, you should log in to Spotify, as it is described in the official guide. Every time OwnTone is started (every time you turn on Pi), it loads all saved playlists from Spotify; it surely takes time. I use a dedicated account in the family plan with only playlists I listen to.
Satellite Board
Take one of Seeed XIAO or Adafruit QT Py boards just because they are small. RP2040-based boards usually cost less. I use XIAO nRF52840 in this project. The board does two things: controls NeoPixel LED strip and reads analog input. Also, as the board starts instantly, I can now play a LED animation while the Pi is booting.
Flash your board with CircuitPython firmware, find the right one on circuitpython.org. It should be detected as a thumb drive when connected to a computer. Learn more on Adafruit.
Install libraries to the board (run on your computer, not on the Pi).
Now copy Python files from src/board to the board, and it is done.
CAUTION: Do not connect the board to your computer while it is powered by another power source. You may back-power the USB controller inside your computer and burn it.
Control App
Copy everything from src to ~/recordplayer on the Pi.
Activate environment.
Find available speakers and outputs.
Insert IDs of remote speakers that you want to use into OUTPUTS in playback.py. Keep "0" - it is for local speakers.
Test it.
Library


In library.py, you find a list of NFC tag IDs with associated playlists and albums.
Place NFC tag on the reader, run the command below, and you will see the tag ID. Copy it and use it in library.py.
Spotify URIs are regular Spotify URIs; you can find them in Owntone UI. Owntone doesn't show URIs for albums; you need to extract it from the URL. Open an album in a browser, copy the URL, and change it from http://recordplayer:3689/#/music/albums/8249546791409011466 to library:album:8249546791409011466.
Restart Pi after making changes in library.py.