Some months ago, I got a Raspberry Pi in the mail and proceeded to install MPD on it. After a few days playing with an embedded MPD server and figuring out what I liked and didn’t like about the arrangement, I decided on a significantly more elaborate project to build on it. I wanted to be able to control the player, even if all of the computers in the house were off. I also wanted to run player while using my desktop, which I couldn’t really do because they shared the same desktop speakers. I ended up with a list of features for an embedded music system:
- MPD installed on a Raspberry Pi with a music library stored on a USB attached hard drive
- A Pulseaudio server installed on the Pi with computers in my apartment configured to stream sound to it
- A physical control panel attached to the Pi, which displayed player information and let me start/stop, mute/unmute, select songs, and change the volume on the device
The first of the features was already done and had taken all of thirty minutes. The second was not done and would take longer, but was still easy. The last item on this list however, required a bit of physical hacking to do. I ended up using all of the GPIO pins to do it. Anyway, here’s a picture of the final product:
I think it turned out well. That’s a 16x2 LCD display, two RGB LEDs, two rotary encoders, some wires and a circuit board, embedded into a homemade Plexiglas and aluminum frame. Together, they use up all of the GPIO pins on the Raspberry Pi. 1 Putting that together took quite a while and was a bit of trial and error. The original plan was to whittle a case out of wood but that turned out to be more labor-intensive that I desired while I don’t think that an ‘international-style’ case is as attractive, it still works for my project.
I wrote the initial code in Python, but found out that the current Python GPIO libraries were unsuited to reading rotary encoders. So I rewrote the project in C using the excellent WiringPi library. It actually constitutes my first return to C in a long while. I had to learn both MPD client library and the ALSA library by reading the code.2 In retrospect, I should have written it against Pulseaudio rather than ALSA, but I hadn’t decided initially that that was the direction I wanted to go. In the end it didn’t matter because I only change the master volume.
One thing I did learn and had to code for, is that the human ear does not perceive volume change linearly, so I had to convert it logarithmically between display and reading. This is apparently a common practice and is why potentiometers are commonly sold which change logarithmically. I was using a rotary encoder to adjust volume, so I had to do it in software.
The code for all this is, if you want it, on github.
Making the physical control panel was harder in the end than writing the code for it. I started with a prototype on a breadboard against which I wrote the code:
This worked of course and I could have left it at that, but it was unfinished and I had to reach through all the wires to use it. Making the finished device however, turned out harder than I thought it would. I initially started carving wood to make the case but changed my mind after I realized that the finished product would probably be pretty ugly. (My whittling skills are not where I’d like them to be.) So instead I bought some acrylic sheets, broke them into smaller sheets and cut out room for the components to fit using a Dremel tool. It took me three tries to get right.3 I then replicated the circuit on the breadboard on a protoboard which I could connect to the Pi with a 13pin ribbon cable. I was going to put the whole thing, Raspberry Pi and all, together into one bit clear acrylic box, but changed my mind to make the control panel separate and connect it using rivets rather than glue. I wish I could say I did this because it looked better (it does) but I really did it because it was easier.
I now have the mostly finished product. I think it’s pretty neat. Here’s a quick demonstration:
- The rotary encoders have built-in press switches. ↩
- The ALSA library was by far the easier to figure out because the amixer program was so simple. If you want to write code for ALSA, read the amixer code. ↩
- In retrospect, I could have gotten away with just drilling holes for the rotary encoders and just attaches the LCD and LEDs behind the clear screen. I didn’t think of that at the time. ↩