Adding an audio amplifier to your @Raspberry_Pi

We have a treadmill setup in our house which has always faced some sort of media centre setup. It’s the only way I don’t lose my mind with boredom when running during Irish bad weather (August to June). Originally it was an XBOX-1 with XBMC on a 14″ Philips portable CRT. Then it became a Patriot PBO connected with a HDMI-VGA adapter to an LCD monitor and now it’s a Raspberry Pi running Raspbmc connected to the same monitor.

The problem in all these setups has been audio volume. When I’m pounding my featherlight torso on the treadmill deck, I need lots and lots of volume to hear anything. I bought a 2.1 Speaker thingy from Lidl a good while back and that helped but it still wasn’t loud enough on some media.

Then I got a Fiio E3 battery-powered headphone amp and that worked well with the PBO. The big downside was that it chewed through the single AAA battery in no time at all and was unusable with rechargeables.

I came up with a really cool solution to the battery problem. I got one of these adjustable voltage regulators from DX, cut the head off an old Nokia charger and wired it in. Then I used a multimeter on the output and twisted the potentiometer until I got 1.5V out. I used crocodile clips to then connect to the Fiio.

DSCF2592

I can’t recommend that voltage regulator highly enough. If you, like me, have tons of old power supplies from long dead electronics, it can scale down anything to the voltage you need. I’m getting another one to power the Raspberry Pi from an old Linksys 12V wall-wart as most of my phone chargers simply don’t have enough juice. At €2.90, it’s super value.

The problem with the PBO as a media player is that its UI is garbage. It feels like something from the 90s. In particular, it’s missing a simple but crucial feature we love in XBMC – a tick mark to show you’ve already finished watching something or you are mid-watch. The PBO is also terribly crashy and struggles regularly with SMB network shares.

So we finally moved to Raspbmc and it works really well. Well almost. The only big problem is the analogue audio, it has no amplification on it at all. So even with the Fiio and the Lidl speakers up full, it is very hard to hear on the treadmill.

I had a go with using a USB audio adapter but that was a disaster. Audio out of sync and the GUI mis-behaved the whole time. It was louder tho!

Then I went looking for something with more welly than the Fiio. That company has other devices but they are even more expensive than the RPi itself.

I then built this:

IMG_20130302_190848

But after much gnashing of teeth with no output and then mono output, I realised that a loudspeaker amp is totally different to an inline headphone amp and just cannot work in that configuration. So much for 6 years of Electronics in UCD ;-)

Weirdly I could only find loudspeaker amps on DX, eBay and Amazon. A bunch more googling and reading on audio/hifi/hobbyist sites and fiiiiiinally I found a headphone amp design called the CMoy which (a) looked easy to make (b) looked cheap to make and (c) had very detailed instructions for idiots like me.

I ordered the various bits online from the usual suspects (eBay, DX, Farnell) and put it together last week on a mini-breadboard. Shockingly for me, it worked first time! The only difficulty in the instructions is that they are customised for a very specific Radioshack board and I had to translate that to my simple breadboard.

IMG_20130407_203620

Then yesterday I sat down to build the final circuit on some stripboard I got yonks ago in Maplin. I’ll be honest, it took a while. Particularly translating the layout to a very small bit of board. But yet again, magically, it worked first time. I have it powered with another old Netgear 12V wall-wart. It’ll take anything from around 9V to around 30V which is really handy.

DSCF2590

A bit of glue-gunning on to the unused lid of a Raspberry Pi case and I have a finished product. And boy is it loud! We’ll need to be careful we don’t blow the amp inside the Lidl speakers or damage the speakers themselves. Mrs D’Wife, who ran 10 miles on the treadmill today (10 miles!), approves of the improved volume level too.

DSCF2596

I highly recommend the CMoy kit if you are struggling with audio volume levels on anything, not just the RPi. At some point I’ll draw out my layout to save others the hassle of figuring out the original layout. Hit me with any questions below.

UPDATE 1: I completely forgot to do a costing on this. Whilst the overall spend for me was  €32.45 (incl P&P), this includes some giant packs of resistors, capacitors and LEDs that I have been using on multiple projects. If you can manage to get exactly the amount of each thing you need, then the entire amplifier only costs €6.59. That’s obviously excluding the power supply, solder, tools and the glue from the glue gun. You will find it difficult to just buy 1′s and 2′s of things. You can do it in Maplin but it’ll cost you a lot more. You can also do it on sites like Farnell but they have a minimum order of €20.

So either buy the bigger packs on the basis that you’ll be making other things or do it as part of something like a Coder Dojo where lots of you pitch in together to make lots of these.

The @RaspberryPi Doorbell of Dooooooooommmmmmmm

We had some good fun last night with the neighbourhood kids making use of our Doorbell of Dooooooooommmmmmmm.

I’ve had a bigger doorbell project planned for quite a while but 2 weeks ago decided we should do a simpler Halloween one. Using various bits bought from Sparkfun and Maplin along with a great tutorial from Adafruit (more below), I finally got something we were happy with, working late last week. Then yesterday evening I put it in place on the door. Unfortunately, with all the pulling, taping and general movement, one of the five buttons stopped working. But the other 4 were fine.

The sounds used were pulled from various online sources. Sibéal came up with the Mr Burns idea and Oisín thought of the Home Alone one. I used Audacity to clip some of them and ffmpeg to convert some of the YouTube videos to audio. The cheques are in the post :-)

Originally I was going to use Arduino for this but considering a Waveshield for playing audio costs more than a Raspberry Pi, I changed direction. I then thought I’d use the Arduino for the button detection and communicate over USB to the RPi but I finally realised I should just use the GPIO pins directly on the RPi itself. My worry about killing it accidentally were unfounded.

The first version was done on a breadboard to make sure I made no mistakes. It worked well. But it was never going to work stuck to a doorframe so I moved to a strip of veroboard and soldered it together. This had a few, ahem, glitches, which took a while to sort out due to my soldering incompetence.

The final setup was really simple:

  1. One button per sound
  2. Each button connected to a GPIO pin on the RPi along with connection to 3.3V and GND on the RPi (pull up resistors there too but apparently not necessary?)
  3. An old 40-core IDE cable from a dead PC used to safely connect the wires from the buttons to the pins on the RPi.
  4. Extremely simple Python code running in a loop on the RPi which checked to see if any of the connected pins were pulled low by the button being pressed.
  5. If so, it made an external call to mplayer to play one of our selected audio clips

The only real change from the Adafruit tutorial was to use mplayer instead of mpg123. This allowed me to use any audio format including WAV, rather than just MP3s. Also some of the instructions are a little redundant with the latest version of Debian on RPi, but they do no harm.

This is the trivial script to set the volume and call the Python script:

#!/bin/bash
amixer cset numid=3 1
nohup ./raspi-audio-button.py > /dev/null 2>&1 &

This is the code, it uses the RPi.GPIO library (the latest version works fine):

#!/usr/bin/env python
from time import sleep
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
    if ( GPIO.input(22) == False ):
        os.system('mplayer /home/pi/haunted_sounds/Howl.mp3 &')
        sleep(3);
#    if ( GPIO.input(17) == False ):
#        os.system('mplayer /home/pi/haunted_sounds/HomeAloneCountOf10.mp3 &')
#        sleep(3);
    if ( GPIO.input(23) == False ):
        os.system('mplayer /home/pi/haunted_sounds/ReleaseTheHounds.wav &')
        sleep(3);
    if ( GPIO.input(24) == False ):
        os.system('mplayer /home/pi/haunted_sounds/Scream.wav &')
        sleep(3);
    if ( GPIO.input(25) == False ):
        os.system('mplayer /home/pi/haunted_sounds/CastleThunder.wav &')
        sleep(4);

This diagram of the RPi pin-out was invaluable:

Once everything was setup at the door yesterday, we then found that the volume on the Lidl iPod Dock was far too low. I had to put a tiny battery powered speaker outside, taped to the postbox. But even that wasn’t great so I added a Fiio amplifier. Of course then we couldn’t hear it inside, so I split the audio and used one audio device inside and one outside.

I didn’t have time to setup wireless on the RPi so I used a wired network connection. This enabled me to SSH to the RPi from my PC and start the Python program. It also allowed me to remotely change the Home Alone clip to the howl from An American Werewolf in London after it got a bit tiresome, 2 hours later.

I made a video of it all in action but the bloody version of CM10 on my phone corrupted it. To give you a taste of what it was like, I extracted the audio from it. Enjoy:

Changes? Instead of externally calling mplayer, it’d be better to use some sort of audio library that would allow a follow-on button-press to interrupt whatever is playing. Also, approx 75% of kids pressed the top button so the next time we’ll randomise what is played.

Next steps? Well that’d be our Social-Enabled Doorbell. It’ll probably be Christmas before I finish it tho.