RavensPi - A Raspberry Pi-based car radio system.
09/02/14 09:23 Filed in: Raspberry Pi
Whilst my last Raspberry Pi “recipe” was fairly easy to achieve with an out-of-the-box installation of Raspbian, this time I wanted to do something very different with my Model-A Pi. It crossed my mind that the Model-A should be very good for any form of embedded system - an appliance you could just power up, use and switch-off without ever having to think of logins, commands, buttons or having a keyboard attached to make sure it enters a controlled shutdown. So, I embarked on a new project and this is the fruit of about a weeks worth of my work, which seems to be working pretty well so far. Want to know what it is? Of course you do!
I’ve created a car jukebox that continuously plays John Peel radio shows. I’ve filled it to capacity and it’ll play continuously for ten days without repeating itself. It’s powered by the USB port in one of my car lighter-sockets and the audio is fed into the AUX socket of my car stereo. Each time I start up the engine, something different is played - and if I’m on a long drive, it just keeps playing. The operating system is extremely lightweight, allowing it to start up quickly and start playing audio in under twenty seconds.
Here’s what I used for this project.
- A Model-A Pi - although there’s nothing to stop you using a Model-B.
- A keyboard for the setup.
- A case. (I used Pimoroni’s “Modela” case, because it looks funky)
- A low-profile SDHC card adaptor - so that nothing’s sticking out of the box.
- A one-metre “Noodle” micro-USB lead to power the Pi. You can get these for 99p from eBay.
- An audio lead to go from the headphone socket on the Pi into the car stereo. They’re also available from eBay for a nugget.
...and here’s how I created it.
1) Download an image and write it to the SD card.
As you might have gathered, you’re not going to get very far unless you have an operating system to start with. You want something small, as it’s going to be pretty pants if you’re waiting for over a minute for the Pi to boot up onto an XFCE desktop. For that reason, don’t go for the default Raspbian image. Remember that the smaller the OS you put on the card, the more space it affords you for music.
I decided to go for Minibian, which is a nicely cut down version of Raspbian. GUIs, games and general guff have been removed and it’s less than 1GB in size, which should provide you with an ideal starting point.
Instructions are all over the interpipes about how to write an OS image to an SD card - so forgive me if I skip over that bit.
2) Boot up and set up auto-login.
Your first job is to set up auto-login. When it’s in your car, you’re not going to be able to login or force a shutdown, as you won’t have a keyboard attached. To auto-login at startup, you’ll need to modify /etc/inittab - edit the file (using nano, vi, or whatever your editor of choice is). Scroll down to:
1:2345:respawn:/sbin/getty 115200 tty1
Comment out the line using the “#” (hash) sign and add this underneath instead:
1:2345:respawn:/bin/login -f root tty1 /dev/tty1 2>&1
That’ll let you auto-login as root. Obviously that gives you a lot of power, so be careful. It shouldn’t pose a security risk as you’re not going to have a working network connection.
Pruning is necessary. Pruning ensures the unit boots up quickly, doesn’t use much RAM and doesn’t waste its time doing stuff that isn’t necessary. I’m no expert, but I will say that I’ve been fairly aggressive and haven’t broken it (yet). I don’t care about internet connectivity, SSH, daemons doing stuff they shouldn’t be, or hot-plugging hardware. I’ve removed all the versions of Python that I can get away with, disabled swap and removed all but one version of GCC.
The list of what’s left is pretty short. As a starting guide, I disabled cron, removed udevd and dphys-swapfile, python (2.6 and 3.2) and GCC (I left 4.7 and removed the previous versions). If you use “deborphan --guess-all” as well, you can probably get lists of other libraries to remove.
Use “apt-get purge **packagename**” to remove whatever you want to get rid of. As a word of caution, I’d take regular backups, so that you can always restore them should things go belly up.
With swap gone, there’s still plenty of memory kicking around. Using “top”, I’m still have nearly 200MB of my 240MB of memory left - which is plenty for our music player to do its thing in.
4) Log files and RAMFS.
Log files are annoying. You’re not going to need them, you’re never going to see them and they’re going to take up space on your storage. A good way of ensuring your logs are automatically purged is by using a ramdisk to store them. With a ramdisk, they’ll disappear as soon as the machine is switched off - and that’s what you want. Additionally, when logs are created they’re in RAM and not on the SD card. This reduces the amount of writes to the card and means things should be a little quicker.
To move a filesystem into RAM, you’ll need to edit /etc/fstab (which is the file that specifies the details of your file systems). You’ll need to add the following entries to the end:
none /tmp tmpfs size=4M,noatime 0 0
none /var/log tmpfs size=4M,noatime 0 0
none /var/run tmpfs size=4M,noatime 0 0
I’ve only allocated 4MB for each directory - and I might shrink this a bit more. So little has been written to the folders after a few hours that it’s not worth wasting the memory.
5) Install MOC, create a home folder and copy in some audio.
There’s a whole variety of music players for Linux out there, but I settled on MOC. It’s command-line driven (which is perfect for a quick startup) and has plenty of the options that you’ve come to rely on in a GUI player. You can shuffle tracks, use a playlist and apply equaliser settings to the audio - and of course it’s free.
There’s two ways you could install it. You could download the package files and copy them to the SD card to install (the slightly awkward way), or you could do what I did - cheat slightly and bung it in a Model-B Pi (with an ethernet port) and install automatically using apt-get. If you’re unsure as to which packages to get, simply type “apt-get install moc” - and it’ll tell you which other packages you need too.
As a Mac user, my OS won’t automatically recognise the EXT-4 formatted partition that Raspbian lives on. However, if you can get your hands on a Linux distribution (I ran LUbuntu under Parallels), that problem goes away. Simply mount the SD card in your Linux OS and copy the MP3 files to your chosen folder (I put them in an “Audio” folder within root). If you want a free alternative to Parallels, VirtualBox will do the trick nicely.
6) Create a playlist, normalise the volume and configure auto-start of MOC.
Once you've got all the audio files you want to play in a folder, start up MOC. To start it up, you just need to type “mocp”. You'll need to cursor down to the folder concerned and use shift-A to auto add all the files to a playlist. Save the playlist using shift-V, quit MOC and use chmod to ensure the permissions on the file allow it to be easily read and that it's in an easily accessible location (I know we’re root, but let’s not leave it to chance). As this isn't a true multi-user system or connected to the internet, I had no problem with using chmod to allow anyone full access to root's folder (where I saved the playlist).
Volume is a bit of a concern. Bear in mind that when the Pi's connected to your stereo, it will only be outputting audio at one volume, 100% - so you'll always want the volume level of each MP3 to be the same. Unfortunately, MP3s are created at a whole variety of different volume levels - meaning that whilst one could play quite loudly, the next one might not. To counteract this, I normalised the volume levels on each MP3 file. There's plenty of tools out there to do it. I set mine to 94db, which seems to have done the trick. I used easyMP3Gain in my aforementioned LUbuntu environment, meaning that I could modify the MP3 files directly off the SD card and save myself some hassle.
Now we've set up auto-login, we now need to kick off a script to start our audio player. MOC Rather wonderfully allow me to specify options at startup. You need to edit /etc/rc.local, as that's the bad boy that'll be executed on auto-login. Here’s what I’ve added:
rm -f /.moc/pid
mocp -S -R ALSA
mocp -a /root/startup.m3u
mocp --on shuffle
mocp --on autonext
mocp --on repeat
mocp -p --volume 100
You'll see that I've put in a bit to delete a file. I have to do this to ensure that MOC starts up without problems every time. When it starts up, it fires up the server task and creates a "process-id" file to signify that it's started - that's great until the power is cut. Because it wasn't a controlled shutdown, the process file gets left behind afterwards.
The "-f" flag ensures that it's always removed and the system doesn't bitch about it when it's not there.
So, those commands starts up the MOC server, clears the playlist, adds our predefined playlist to the pending pile, starts shuffle off and plays at max volume.
8) Equalizer settings
For a command-prompt based music player, MOC is actually pretty funky. In fact, I'm pretty sure there's not many things it can't do. Once I'd got MOC playing as I wanted to, I'd noticed that the sound was a little flat and that it could do with a bit of a boost.
This is where the use of equalizer presets comes in. As luck would have it, someone's taken the trouble of grabbing WinAmp presents and converting them over so that you can import them into MOC. All you need to do is to download the file listed here, extract the folder from the archive and copy it into MOC's "eqsets" folder. With headphones connected, I cycled through the presets until I found one I liked. MOC Appears to keep the preset in place until you tell it otherwise, which is nice.
9) MOC Options and the system date.
Computers do not generate random numbers - they only pretend to. If you took two identical computers, switched them on at the same time and asked them for a random number at the same moment, they'd give you the same number.
This causes us a problem when we want our system to play random tracks, because it won't. It'll keep playing the same track repeatedly each time you switch it on - which will get annoying.
Computers tend to use their system clock as the "seed" to generating a random number. The problem is that the Pi doesn't have a real system clock, just a pretend one. The value of the clock is saved when you shut it down and reloaded when you start it back up. That's not usually a problem, because if it's connected to the internet, it'll use a network time server to synchronise itself.
But the machine will never be shut down and it won't have any network connectivity - we'll just cut the power when we're finished.
To get around this, I came up with a fairly simple solution. What if we saved the time two seconds after we booted up instead? We don't give a rats posterior as to whether the time is actually correct or not, we just need it to be different from last time so that a different random number is generated - and subsequently a different random track is played.
So, you'll see that I've added the following line to my /etc/local.rc file - this submits a daemon task to save the time of our pretend clock. Two seconds later, I use the "sync" command to ensure any pending unsaved data has been saved. Here’s what I added:
start-stop-daemon --start --exec /sbin/fake-hwclock
Reboot! Bingo! Success! We have shuffle play!
10) Boot options - cmdline.txt and config.txt
Both of these files specify the configuration of the system when it boots up. Here’s my cmdline.txt:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait loglevel=1
...and here’s my config.txt
I edited the files using TextEdit on my Mac.
As you’re never going to see what’s on the screen when the unit is running, you’ll never need any more than 16MB of memory for the GPU. Don’t bother changing it. This is also why I’ve set “loglevel=1”. The machine will probably boot up about a second quicker if it doesn’t have to output every single action it takes during boot up.
11) Changing the /boot partition to read-only.
If you change /boot (the boot partition of your SD card) to read-only, it means that it can’t get corrupted when you cut the power. You’ve now changed all you need to, so to ensure there are no further changes or complaints about corruption on the volume, you’ll need to make a small change to protect it. The change takes just a minute. Simply do the following:
Go the the line that mentions your boot device and change
/dev/mmcblk0p1 /boot vfat defaults
/dev/mmcblk0p1 /boot vfat defaults,ro
Press CTRL-X to save it - and you’re done!
12) Back it up!
Hopefully, you’ve backed it up well before you’ve got to this stage as you’ve done a whole pile of configuration that would be a massive pain to have to do again. When I was working on this project, I took six different backups at varying stages along the way. It took just five minutes and in the long run, saved me hours when I cocked things up and had to fall back to the previous stage. So, if you haven’t got the message already, YOU NEED TO BACK UP - and back up often. If anything ever goes wrong, you can reflash the card in just ten minutes and save a lot of tears.
13) Optional - unsoldering.
The yellow video output socket is an annoyance, mainly because it sticks out and has no real purpose. If you want to reduce the form-factor a bit more (and also the power consumption, if that’s important), you can go ahead and unsolder it. Bear in mind, though, that the three legs of the connector have been very well soldered to the board and you’ll have to apply a lot of heat to get it removed. Be careful!
This project is what I’d call a high-tech way of reproducing something that’s pretty low-tech (i.e. the radio). When I’m in the car, I leave it on constantly. I hop between stations and “Peel FM” as though it’s just another station. I’ve checked things out a couple of times and the SD card doesn’t appear to have suffered from any corruption, mainly due to me not using swap, booting of a read-only partition and putting all log files into RAM. In the event of any problems, I’ll simply reflash it with my backup.
The card is largely filled with MP3s that have been sourced from The Perfumed Garden. My thanks go to Kris for providing such a wonderful resource.
And of course, if you have any questions feel free to drop me an e-mail.