Skip to main content

Columbus Radio

Geoffrey Hunter Author

The Idea...

To bring a old, broken valve-based antique radio into the digital age with the ability to stream audio from the internet, plugged in USB stick, or a networked computer. All while keeping the classic retro radio look.

The Original Radio

My partner brought this lovely vintage, but worn valve-based radio an auction many years ago for NZ$5. Bargain!

The original front-panel of the Columbus radio.

Even though it was worn and torn, you could tell it had been beautifully made and with attention to detail. Different veneers were expertly crafted into each wooden face of the cabinet. The rear showed you the inner-workings, large valves, plate capacitors and pully systems!

The original rear of the cabinet. Valves, air capacitors and pulley systems!

The original electronics!

The original electronics of the Columbus radio, housed in the underside of the metal case which sat in the radio cabinet.

Woah! I had seen nothing like it before. I had heard of the style of board-less circuit design in where the components themselves supported one another, but only ever seen "new age" artistic examples of it (for instance a digital audio amplifier). And the component density was crazy! There were bare wires running past each over in free space with only mm's of clearance. Tabs had been added to the metal enclosure at frequent intervals around the outside to serve both as a grounding point and a mechanical support.

Oh and don't forget the classic speaker...

The original Columbus radio speaker.

UPDATE 2015-01-12: I found this webpage which describes the Columbus radio brand and it's origins. Based on this information, the radio was made in New Zealand sometime between 1937 and 1961.


Stripping The Cabinet

The radio's enclosure was in a pretty sad state when I first laid hands on it. The wood had a faded, mottled and cracked look to it. The knobs and their pulley systems (yes, it had pulley systems) had jammed. The glass panel with the screen printed radio bands on it had bits of text missing.

I tried a few different paint strippers (because my father had all of these lying around).

The Maxistrip paint stripper.
The 'Dad's Easy Spray' paint stripper.
The Cooper's stripper.

Here is me applying the stripper to the cabinet:

Testing out the Maxistrip stripper.
Applying the stripper.

This is left for about 20 minutes, and then the stripper removed with a combination of scraping, iron wool and water/washer.

Removing the stripper goop after about 20mins of soaking.

Yay, it works! You can see the bare wood (on the side) coming up nicely in the photo below:

Comparison between the stripped and non-stripped wooden surfaces of the cabinet.

I did a bit of a comparison between them, and the differences were pretty amazing! The Cooper's seemed to produce a much nicer finish than the other two...

A wooden surface stripped using Maxistrip.
A wooden surface stripped using Cooper's.

Sadly, I also had to remove the "Columbus" logo, as there was no way of protecting it while at the same time stripping of all of the varnish surrounding it.

Sadly removing the 'Columbus' logo.

I had to mask of the speaker port while stripping the front panel.

Masking of the speaker port while stripping the front face of the cabinet.

Don't forget the strip the dials! These had intricate carvings of the Columbus ship on them.

Stripping back the intricate dials of the Columbus radio.

All stripped! The wood had come up really nice, and since all of the glossy, cracked varnish had gone, I realised there were far more veneer patterns that I first thought.

All stripped and already looking better than the before!

Moisturising The Cabinet

The Cooper's "wood restoration" product line also includes some moisturiser that you are meant to add after you have stripped it.

Moisturising the cabinet.

The moisturiser does not give it a hard surface, nor does it stain the wood, but rather soaks into it and brings out the original colour.

The cabinet looking swag after moisturising!

No More Borer

The existing cabinet had quite a few appearance-degrading borer holes on the front face. To prevent any more of these, I gave the cabinet a good coat of "no borer".

Giving the inside of the cabinet a good coat of 'no borer'.

Cleaning The Glass

The glass panel had to be handled carefully, the radio frequencies and other text printed on it I wanted to keep for retro reasons, yet it looked like it would flake of and the gentlest touch.


The Smarts

I decided on using a RaspberryPi with the Volumio distribution. I already has some Raspberry Pi experience after the Auto-Electric Blanket project and just general tinkering, and Volumio software looked like a pretty powerful and open-source music streaming application that would work on the Raspberry Pi.

The RaspberryPi B+ I used as for the smarts inside Columbus radio.

The RaspberryPi B+ was preferable over the older A or B solely because of the improved audio output. The first versions of the Pi shared a single regulator between the audio output DAC and a few other peripherals. These peripherals, when in use, caused some significant distortion/noise of the audio output. They have fixed this in the B+ and given the DAC it's own dedicated voltage regulator.


I was initially looking at a 100W amplifier from DealExtreme like the TA2024 or the FX502A, for about US4040-60. However, I eventually decided to use the car stereo amplifier I pulled out of my old Ford Laser since it was lying around and doing nothing. It is a JVC KD-G396 50W(max)x4 MOSFET-based car head unit.


I could of kept this speaker and gone for a "classic sound" as well as a "classic look", but I really preferred something with a bit more clarity and punch, so I decided to replace the speaker with two 40W RMS 6x9 speakers I had lying around after my Ford Laser got wrecked.

Removing the existing Columbus radio speaker.

Unfortunately, these didn't quite fit side-by-side when facing forwards in the enclosure! So for better or worse, I decided to face one backwards (goodbye stereo). Here is the front speaker being installed:

Installing the 6x9 mount for the front speaker.
Installing the front 6x9 speaker.

Installing the rear speaker:

Installing the rear 6x9 speaker.

EDIT (post completion): One backwards facing speaker didn't seem to be that detrimental (apart from no having proper stereo)! I tested various speaker configurations and there seemed to be no difference between the rear speaker facing backwards or forwards.


This was an easy design choice, I needed both +5V @ 500mA and +12V @ whatever speakers take (approx. 1A continuous, 5A peak per speaker, based on the speakers power ratings). I had some old computer ATX PSUs lying around, so choose a suitably sized one (this wasn't hard either, there was plenty of space in the back of the Columbus radio).

Chiseling away some small bits of wood in the cabinet to make room for the PSU.

LEDs Are Not Retro, Woops

There used to be some sort of valve-based indicator which poked out onto the front glass panel.

Removing the existing valve-based indicator.
I now had to find something to fit into the gap...

I got the great idea to use LEDs to indicate two things, when the power was on, and when the radio had internet connectivity. I busily spent many hours buying the high-power LEDs, working out how to diffuse their light, making a reflective backing for them to push more light forwards, and installing them into the radio. I was just glueing up the little housing I made for them with epoxy when I realised, crap, LEDs are not retro at all!

Heartbreakingly I decided to rip them out right then and there before the epoxy set, and start anew. This time I used a tungsten based bulb instead, wrapping it in black cardboard to make up a mount that would fit the original hole.

Making up a mount for a 12V, 100mA bulb to replace the valve-based indicator.
Hot-gluing the bulb into the front glass face from the back.

User Interface Inputs

Even though the unit is designed to be controlled by the Volumio web interface, I thought it would be nice to be able to turn it on/off, control the volume and skip to the next track without having to use a computer/phone.

There are 5 dials on the Columbus radio, The central one is a SPST switch for controlling the power. Then there are two potentiometers, which I'm guessing one would of been for volume, not sure on the other. Then there was one dial which controlled a pulley system that moved the plate capacitor and another dial which switched between the different radio-frequency bands.

I decided to use the two existing potentiometers to control the volume and to switch to the next track. The volume one is self-explanatory, for the "next track" functionality I had the idea to make it so you just twiddle it in any direction by at least a small threshold amount to get it to go to the next track in the playlist.

Wiring up from the RaspberryPi daughter board to an existing potentiometer on the Columbus radio. This one was used for volume control.

RaspberryPi Daughter Board

The RaspberryPi was not enough on it's own to provide all of the I/O functionality to drive the speakers, control the lights, and read in the inputs from the volume and track change potentiometers.

For this reason, I had to craft a daughter board. I used a piece of strip-board, shaped to that it would directly solder onto the RaspberryPi's GPIO header, and still allow the Pi to fit inside an enclosure.

Cutting out a RaspberryPi daughter board from strip-board prototyping PCB.
Fitting the daughter board directly onto the RaspberryPi's GPIO header. This was designed so the entire thing could still fit inside a standard Pi B+ enclosure.

The layout of the GPIO on the RaspberryPi is shown below.

The GPIO header layout of the RaspberryPi B+. Image from

The following table shows what GPIO header pins I decided to use and what they are connected up to on the daughter board (the circuit was so simple I didn't think it warranted actual schematics been drawn up):

GPIO Header Pin NumberGPIO Function(s)/NameWhat I Used It For**
11GPIO17 To drive the gate of MOSFET to control the +12V, 100mA status bulb.
17 3V3 The MCP3008 (ADC) VCC.
24 GPIO8, SPI0_CE0_N The MCP3008 (ADC) CS.
25GNDGround for the entire daughter board.

The RaspberryPi doesn't have any ADCs, so I had to use the popular MCP3008 ADC IC as an interface to the analogue potentiometer signals.

Here is a photo of the completed daughter board:

The completed daughter board.

The Software


All software for the Columbus radio project can be found on GitHub at

Volumio was easy to install. The Volumio v1.51 (the most recent as of 2014-12-29) image was downloaded and then written to a SD card. When the RaspberryPi is booted with this SD card and plugged into a router with an ethernet cable, you should be able to visit the Volumio WebUI by navigating to volumio.local/ on your computer's web browser. At this point I changed the name of the

You can SSH into the volumio platform with the network name columbus (or whatever you changed it to), and both the username and password as volumio (type ssh columbus -l volumio, and then enter in the password volumio when prompted). If you need root access (as I did, to enable the SPI controller), you can use the same credentials as above, except replace the username with root.

The wireless was easy to setup and was working as soon as the SSID and password was entered via LAN connection. I could even change WiFi dongles and not have to re-enter this information.

Getting SPI working was more difficult. When running lsmod on the default volumio install it listed spi-bcm2708 but no spi-dev (this didn't turn out to be an issue in the end, even though online tutorials suggest that spi-dev has to be present before the SPI will work).

I ran apt-get update and apt-get -y upgrade.

Part-way through the sudo -y upgrade process on the volumio.

modprobe spidev seemed to run o.k. with no errors. It wasn't listed under lsmod, but I could see the two SPI devices in /dev (run ls /dev).

Installing the spidev python module with python install. It gave me the error:

spidev_module.c:20:20: fatal error: Python.h: No such file or directory

So I installed the python development software with the command

$ sudo apt-get install python-dev

This took a decent amount of time to install, primarily because the download speed was a mere 50kB/s. I think this was because the RaspberryPi was connected via WiFi and was out in the garage, with low reception back to the router in the house. The fact that I even got reception was pretty impressive considering I was only using a tiny chip-antenna based USB WiFi dongle on the RaspberryPi!

This fixed the Python.h error! Now an attempt to read the ADC value.

Even though the potentiometer wasn't moving, the read back ADC values kept varying as shown in the below image.

Screenshot a python script reading back the ADC value from the old potentiometer and converting it into the volume. Even though the potentiometer was not moving, the volume value was varying wildly.

I had a feeling this was due to the high resistance of the volume potentiometer, it's full scale value is 870kΩR. The input impedance of the ADC channel upon measuring must of been low enough compared to the potentiometer resistance to cause the ADC voltage to fluctuate during measurement. I fixed this jitter by adding a 470nF, 50V electrolytic capacitor on the ADC channel 0 input as close to the ADC IC as possible. My first attempt with a large 47uF capacitor didn't work because it took to long to charge (time constant RC is too big)!

The potentiometer for the "next track" functionality also had this issue, except mush worse, because it's full-scale resistance was 8MR. I had to add a smaller 10nF capacitor otherwise again, it would take too long to charge. However, because I was using this pot to implement a binary "next track" or "not next track" command, I could easily increase the thresholding in software to get rid of false triggering.

Sending MPC Commands

My first attempt at writing mpc on the command-line gave me this error:

root@volumio:/etc# mpc
error: Connection refused

And then I discovered that the web interface had stopped working. Oh oh. I tried a number of things like restarting the MPD server and trying the following shell commands:

sudo /etc/init.d/mpd stop
cd /var/lib/mpd
ls /var/lib/mpd
rm -i state
sudo reboot

However, nothing seemed to fix it. I ended up having to reflash the SD card and start again.

Maybe the apt-get -y upgrade command is screwing things over, I noticed this as part of it's long, long output.

Checking init scripts...
WARNING: init script for nginx not found.

There is also this message, in where I choose "N" (keep currently-installed version).

Configuration file '/etc/monit/monitrc'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer\'s version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : start a shell to examine the situation
The default action is to keep your current version.

So I had to reflash again. At which point the OS wouldn't even boot. Some issue with the SD card image?

Fixed! Had to clone all the files from the Volumio git repository back into /var/www. Volumio then prompted that there were updated available, and would you like to upgrade. After clicking yes, we were back to normal!

Also tried sudo rpi-update (and then a reboot). This also didn't work.

The Way That Worked

So I gave up on sudo apt-get update, and apt-get -y upgrade as they seemed to break the Volumio Web UI. Given I couldn't run the proper SPI code without running that command, I luckily discovered a bit-banged python code module ( that can talk to the MCP3008.

I also found instruction on how to install the python RPi.GPIO module without having to use sudo apt-get install python (which required the sudo apt-get update call first).


And the to install it:

sudo dpkg -i python-rpi.gpio_0.5.8-1_armhf.deb

I copied all of the custom code to the RaspberryPi using the command (note this is after changing the "name" of the Volumio platform from volumio to columbus:

rsync -avz /home/gbmhunter/GoogleDrive/Projects/ColumbusRadio/repo root@columbus:~/ColumbusRadio
Copying the repository to the RaspberryPi using rsync, and then loading the code through SSH.

The Python Hardware UI Script

Volumio took care of the web interface, but I still needed some code to control the dials and bulb. I decided to use Python as there was no compiling needed and it's allows for pretty quick development.

I originally went for a basic mega main-loop code architecture. The basic tasks I had to perform were:

  • Read the ADC values from the MCP3008 to find out where the two potentiometer's are. Implement filtering and thresholding for these values to prevent false triggering and jitter. Based on these readings, send the appropriate commands to Volumio to change the volume and skip to the next track.
  • Regularly check for an internet connection, and start flashing the UI bulb if no internet connectivity is found.
Screenshot of part of the Python 'hardware UI' script.

Note that the complete hardware UI code can be found in the GitHub ColumbusRadio repo at hardware-ui/

I was discovering that the main loop lag introduced when checking for an internet connection was disrupting and causing errors in my potentiometer control code. As much as I didn't want the extra complexity/bugs/troubleshooting time, I decided at this point that I would have to implement threading (it was a good excuse for me to learn more about python's threading abilities).

Although getting a thread to start running was pretty trivial, getting multiple threads to exit gracefully when Ctrl-C was pressed (or the script exits in any other way for that matter), was a little more difficult.

I followed this tutorial on for the most part, but discovered the example code was buggy, and Ctrl-C was not causing all the threads to exit! I had to modify the code example by replacing:

threads = [t.join(1) for t in threads if t is not None and t.isAlive()]


for i in range(len(threads)):
# Make sure thread still exists
if threads[i] is not None:
print 'Attempting to join()...'
if threads[i].isAlive() is False:
print 'isAlive() is False, removing thread from list...'

After I did that, the threads started working correctly! I had one thread for controlling the two potentiometers and sending commands to volumio, and one thread for monitoring internet connectivity and controlling the bulb (the bulb flashes slowly with a period of 4s if there is no internet connectivity).

Getting The Hardware UI Script To Run On Startup

I needed the hardware UI script to run automatically whenever the RaspberryPi booted up. To do this I created another small bash script called that ran the python hardware UI script.

sudo python ~/ColumbusRadio/hardware-ui/ 

This script was added to the root user's crontab with the command:

# Write out current crontab
crontab -l > mycron
# Echo new cron into cron file
echo "@reboot sh ~/ColumbusRadio/hardware-ui/ ~/ColumbusRadio/hardware-ui/cronlog 2>&1" >> mycron
# Install new cron file
crontab mycron
# Remove temp cron file
rm mycron

crontab would start the script on startup of the RaspberryPi, and it would run under the user root (which is good, because we have got all privileges, and means we don't have to use sudo all the time).

Power Supply Woes

During prototyping/testing, the red power LED on the RaspberryPi kept flashing. I discovered that this was mainly due to a large dropout between the USB wall-charger and the RaspberryPi's +5V lines! And this was when the device was only drawing about 300mA max.

I fixed this by powering the device through the USB port from a bench-top power supply, and shortening the USB lead. I had to turn up the benchtop power supply voltage to +5.3V (ouch, not a good practise people!) to bring the RaspberryPi's +5V line up to 5V.

This didn't turn out to be an issue in the final product, as the RaspberryPi was powered directly from the PSU's +5V. It was also powered directly to +5V on the GPIO header, meaning it bypassed the low but still significant resistance between the USB VBUS and the +5V rail. This came at the expense of bypassing protection circuitry. Hopefully the PSU doesn't inject any voltage spikes onto the rail!

The End Result

Here is a photo of the finished media-streaming, internet aware radio!

The finished Columbus radio, streaming music from the internet using Volumio and Spotify!


Everyone loves statistics, right?

At A Glance

Project Start Date2014-12-06
Project End Date2015-01-02
Total Hours68.5
Total CostNZ$401
Lines of Code564

Time Statistics

Below are the time logs for this project:

The time logs for the Columbus Radio project.

The time spent (in hours) by date:

The time spend on the Columbus Radio project by date.

The time spent on the Columbus Radio project (as a percentage) by category:

Time spent by category on the Columbus Radio project.

Material Cost Statistics

The individual material costs of each item used to build the Columbus Radio.

The material costs of each component used to build the Columbus Radio.

And now as a pretty pie chart (as a percentage of the total cost):

The material costs (as a percentage) of the components used to build the Columbus Radio.

Things To Improve On

  1. The volume control dial is very sensitive, and the volume only changes a distinguishable amount over a small segment of the potentiometers full range of motion. I believe this a compounded problem due to the potentiometer itself being logarithmic, but the code treating it like a linear pot, and the volumio volume control being quite sensitive in the upper volume regions to start of with.
  2. If you pull the radio's power cord out from the wall (or turn it off at the wall), you have to go around the back and set up the head unit to the correct volume and sound source (aux). The head unit is designed to have the continuous power source from the battery when in a vehicle, a battery that the radio does not have. Turning the radio on/off by it's front on/off switch does not cause this problem as I leave a residual power feed on that goes to the head unit. Unfortunately this means that the PSU and RaspberryPi also continuously run, which may shorten their life and definitely consumes more mains power than necessary!
  3. Simultaneous playback. It would be really neat to have other devices around the house that can be set up to play the same song at the same time. I'm guessing this feature would be best built into the Volumio player that I am using.
  4. The software does not turn itself off when the power switch of the radio is turned off (the power switch just turns of the amplifier). This is a good thing in terms of start-up speed, as music is pretty much instantly available as soon as you turn it back on. However, it does mean that volumio keeps streaming music from the internet, which can chew up bandwidth if you have a long playlist and/or set it into repeat mode. A better way would be for the power switch to also pause the music, and then start it again when it turns back on, starting off from where you left it.