Introduction: Build Your Own Wifi Radio

Picture of Build Your Own Wifi Radio

The internet hosts lots and lots of online radiostreams, most of them with a certain theme, ranging from old time classics to Tibetian riverdancing. I must admit that I love to listen to them while I'm building stuff, as I can choose the music I like without listening to the same cd's over and over again.

The only problem is that I always needed to have a computer neaby to get an internet connection. So I looked around to buy one, but they are quite expensive and besides that, it is a lot more fun to make your own.

As I had no clue at all about how to do the wifi and internet part of the project, I searched the net for clues and I stumbled upon This site belongs to Jeff Keyzer and he has an excellent step by step tutorial on it for hacking a wifi router into a wifi radio. If you follow his instructions, you will end up with a working radio but I decided to build my own graphical interface for it and my own case.

I really wanted this project to look as nice as possible, so I invested a lot of time in designing and building the case. I hope that this build is awesome enough to have a chance in the lasercutter contest or the makerbot contest as I would love to have one of these machines. They would allow me to make even nicer looking and more intricate cases and parts and I wouldn't have to bother my friends to mill parts for me ;) ( in fact I might be able to help them out then).

I would like to thank Jeff Keyzer for helping me with setting up the router correctly, Izaak for helping me with out with the CNC part and my wife for helping me with the veneer.

Step 1: What Do We Need for This Project?

As you can imagine, we'll need a lot for this project.

First of all, we'll need an ASUS WL-520gu wireless router. This router will handle the internet connection and also play the music.

Secondly, we'll need a RS232 to usb converter (3,3V version). We will need that to hack the router. I used a couple of xbees to do this as they are 3,3V and a few wires less on my desk is always handy. If you don't have those you can buy converter cables all over the net (here for instance).

We'll also need a USB sounddevice. I used a creative SB0270 external soundcard that I had lying around for years but you can buy very cheap small thingies everywhere. If you're not sure whether the sounddevice you have will work, then you can go to the forum on There is a list there with working devices.


There are 2 options to make the sound audible. You can either use an external amplifier or you can use an internal one. I actually combined the 2 options. I used a kit (K-VOTI-003 on for the internal amplifier but I also added audio output (stereo cinch) on the back for an external amplifier. Ofcourse you can build you own amplifier too but I was a bit short in time
If you use an internal amplifier, then you will need some speakers too.

I also added a headphone connector to the front.


For the interface we'll need:
  • Agraphical LCD: I used a monochrome 240*128 LCD (LCD-21 on
  • An ATmega16 or 32: The size is depending on the amout of graphics you want to display. I used an smd version but ofcourse you can make your project with thru-hole components.
  • A DS1307 Real Time Clock
  • Battery holder + 3V battery: CR2032 in my case
  • A 32.768kHz quartz crystal
  • A rotary encoder: I used an alps encoder with pushbutton
  • A 10K potentiometer
  • A bunch of resistors: 3 x 1K5, 2 x 4K7, 4 x 10K
  • BSS138: 2 x for the level converter
  • Some male and female headerpins
  • A connector for your programmer
  • 3 double switches
  • 5 led's

The Case

For the case we'll need a lot of 18mm MDF and some real wood veneer.
The front and the backpannel are made of alucobond which is a sheet of poylethylene sandwitched between two 0.8mm layers of aluminium.

We'll also need 5 holders for the LED's and a powerconnector.

Step 2: Hacking the ASUS Router

Picture of Hacking the ASUS Router

I won't go into much detail on how to do the hacking of the Asus WL-520gu, as it is fully explained on the mightyohm-website. You only need to follow it until part 5 because after that we'll build a different interface and case. Jeff Keyzer deserves all the credits for this part an I also want to thank him for helping me out with the problems that occured.

I'll give a quick summary here of the 5 steps:

Steps 1 and 2 are a general introduction but it is nice to read them as they contain some interesting information.

The fun begins in step 3! Void the warranty (Yay!!) by opening the case of the ASUS. When it is opened you need to locate where you can solder a 4 pin male header. It is located near the silkscreen ASUS logo. Soldering the headerpins was a bit tricky. Best way to do it is to remove all the solder that is in the holes before you even try.

In step 4, you'll install OPENWRT on the router. Follow this step very closely as it is possible that you break your router forever when you do something wrong. If you succeed in installing OPENWRT, you can continue with setting up your internetconnection in the second part of step 4.

In step 5 you will install mpd (music player deamon) and configure it. If you have completed step five, you should hear some music!

After completing these 5 steps, you can carry on with this instructable.

Step 3: Add an External Mpd Client

Picture of Add an External Mpd Client

At this stage, you could close the router again and use an external mpd client to control your radio. In this instructable we will also build an interface but having a way to acces the player while testing is always good.

You can download a lot of mpd clients at, even for you Iphone. I downloaded and installed the Ario client. To do so, I needed to install GTK+ too (

When you have installed the program, you need to set up the connection.  By host you add the ip-address of your router and by port 6600. When done click the connect button and you should be able now to control your radio from your pc.


Step 4: Building the Interface (hardware)

Picture of Building the Interface (hardware)

Building up the interface is not very difficult. It can be done on a piece of veroboard or you can make your own PCB.

Connect the LCD to the microcontroller 

I would love to tell you what pins need to be connected to what but every LCD has it's own pinout. You can find the right way to do it in your datasheet.

When working with graphical LCD's, I'll always us port A for the data pins and the higher part of port C for the control pins. That leaves me portc.0 and portc.1 for I2C communications.

Don't forget to add the 10K potentiometer between Vee , V0 and Vss for brightness adjustment .

My LCD had an internal resistor for the LED so I just hooked it up to 5V and GND. You could ofcourse connect the LED with one of the PWM pins on your microcontroller to controle the brightness, but I didn't opt for that.

Connect the DS1307 to the microcontroller

Connect pin 5 of the DS1307 to portc.1 of the microcontroller ande pin 6 to portc.0. Don't forget to add the two 4K7 pullup-resistors to those lines. Add the crystal to pin 1 and pin 2 of the DS1307 and add the batteryholder between pin 3 (positive) and pin 4 (negative). Then hookup pin 8 to 5V and pin 4 to GND.

Connect the rotary encoder to the microcontroller

The pushbutton will have 2 pins on your rotary encoder and the encoder itself will have 3 pins. Connect one pin of the pushbutton to INT0 or portd.2 on the microcontroller and the other pin to GND. Then connect the middle of the 3 other pins to GND, one to INT1 or portd.3 and the last one to portd.4.
All the lines to the microcontroller need a 1K5 pullup-resistor.

Connect your microcontroller to the RS232 pins on the router

If you look at the pins on the router, you will notice that one of them is connected to a thick diagonal trace. That pin is 3,3V and lets call it pin 1. Pin 4 is GND, pin 2 is RX and pin3 is TX.

Connect RX to TDX on your microcontroller (portd.1) and TX to RDX (portd.0). But because our microcontroller needs 5V and the router 3,3V, We'll need a level converter. You can learn how to build one in one of my other instructables or you can buy one online.

Don't forget to add your programming link.

That is all we need to start programming the interface.

Step 5: Setting the Baudrate and Echo

Before we can start to communicate with our router, we need to change its baudrate. The routers baudrate is 115200 and we want it to be 9600 (I was told that 19200 works fine too). Another thing we should change is the echo. Now the router echos back every charater that we sent to it and that would make our Uart-buffer a mess, so we need to turn that off.

I tried to write a script for the router to change those 2 things and to make that script autostart when the router starts up. The script was working fine but it just wouldn't start by itself (most probably something caused by my inexperience). So I decided to look for a script that was running for sure at startup and add a few lines to that.

I found a script named in the etc/ folder. It drives the LED's in front of the router. So I added my code to that script and it worked like a charm.

To do that yourself, telnet or shh to router and type vi etc/ into your console. Now you should see the code. Press I to edit and add stty 9600 -echo < dev/tts/0 just below the header. Then press Esc and :x enter to save it and to close the editor. Then type reboot into your console to reboot the router.

When the router has rebooted, the baudrate should be correct and the echo off.

Step 6: Communications With the ASUS

Communication with the router may seem a bit daunting (well it did to me), especially when you are new to it. But it isn't as difficult as it seems.

Sending commands to the router

First we need to decide what we want the radio to do. We basically want it to:
  • play
  • pause
  • stop
  • change station
  • change volume

If we look into the list of commands for mpc we see that:

  • the command for play = mpc play
  • the command for pause = mpc pause
  • the command for stop = mpc stop
  • the command for volume = mpc volume [+/-] num (numeric value)

The changing of the station is a bit more difficult. To be able to change to another station, mpc needs to know it's address. Easiest way to do so is to preload all our favorite stations into a playlist on the player. So at the beginning of our code we will add the command:
mpc add address for each station we want to preload into the router.

Before we start to add stations, we could issue a mpc clear command. This will clear all previous lists, just in case we made any changes to our list.

 After all this is done, we can change the station with the mpc play num command, where num is the position of the station in our added playlist.

In Bascom, sending these commands to the router is very easy. Everything is done with PRINT:

PRINT "mpc play" or PRINT "mpc volume +5"

There is no need to add a Carridge Return (CR or ascii 013) to the command as the PRINT statement adds that by itself.

So as you can see, sending commands to the router isn't difficult at all!

Requesting and receiving info from the router

Requesting  and receiving info from the router is a bit more difficult. Again, we'll need to decide what info we want to receive from the router. When you read part 6 on, you'll see that there is lots of info that you can get, but we only want to know:

  • the name of the station
  • the title of the song
  • the volume

The request for receiving the station and title is done with the following command:

echo "currentsong" | nc localhost 6600 | grep -e "^Title: " -e "^Name: "  ( mind the capital T and N)

and for the volume:

echo "status" | nc localhost 6600 | grep -e "^volume: " (No capital here)

So in bascom that would give:

Print "echo " ; Chr(34) ; "currentsong" ; Chr(34) ; " | nc localhost 6600 | grep -e " ; Chr(34) ; "^Title: " ; Chr(34) ; " -e " ; Chr(34) ; "^Name: " ; Chr(34) ; " > /dev/tts/0" 


Print "echo " ; Chr(34) ; "status" ; Chr(34) ; " | nc localhost 6600 | grep -e " ; Chr(34) ; "^volume: " ; Chr(34) ; " > /dev/tts/0"

Again there is no need to add a CR.

When we send one of these requests, we'll receive something into our buffer immediately. Now we need to arrange all the data in our buffer into useful stuff.

Luckily for us the router labels its info. Before the stationname it adds Name: ,  before the title title , and before volume volume. So we'll let our code search for the appropriate label and read the buffer from that point until it encounters a CR or until the buffer is empty. After all the info is extracted from the bufffer, we simply empty the buffer so that it can be used for another request.
To do so we start with reading the buffer into a string. After that we can simply clean the buffer so that there are no unwanted characters left. We will look in our string for one of the labels with the var = INSTR( string , substr ) statement. This will return the position of our label in our main string.

position = Instr( Uart_in_string, "Name: ")

This will give us the position of the first character of the label. If you don't want to add the label onto your screen, then just add the amount you need to start reading behind the label. In this case:

position = position + 6

From here we need to determine how long the data is. So from the point position we'll start to read one character at a time until we find a CR or until we reached the last character of the string. We use the var = MID(var1 ,st [, l] ) statement where var1 = the source, st = starting point and I = the amount of characters to read. So in our case:

Length = 0
Incr Length
Position = Position + length
Temp = MID(Uart_in_string ,Position , 1 )

Loop Until Temp = Chr(13) or Temp = ""

So now we know the length of our data and the only thing that is left to do, is to extract the data from the source string. Again with the Mid statement:

Name = Mid(Uart_in_str, position length)

The same will work for the title and the volume.

Now we didn't discuss yet how to read from the buffer and how to empty it. Reading from the buffer is done with var = INKEY(). This will return the ascii value of the first byte in the buffer and then remove that character from the buffer. We just add every single received character together into a string containing the whole or part of the buffer.

Uart_buffer = Ischarwaiting()                                                 
Ischarwaiting() tells how many characters there are waiting in the buffer
If Uart_buffer > 0 Then
Uart_in = Inkey()
Uart_in_str = Uart_in_str + Chr(uart_in)                             
Chr transforms the ascii value into the real character
End If
Loop Until Uart_buffer = 0 Or Len(uart_in_str) = 255       
Len gives us the length of a string

To empty the buffer, just read everything into a string until Ischarwaiting() = 0

This was everything you needed know to communicate with your router.  All the rest of the code are mostly cosmetic: graphic stuff and so on.

Step 7: Using a Rotary Encoder

Picture of Using a Rotary Encoder

All input in this project is done by a rotary encoder. It is basically the same as your mousewheel including the push-function. However, where your mousewheel is most likely an optical encoder, I used a mechanical encoder for my project.

A rotary encoder on A and B channel (both a pin) with one common pin that can be either connected to GND or Vcc. As we use it with interrupts, we'll connect it to GND. The A and B channel open and close in a fixed patern and by reading this pattern, we know in what way the encoder is turning. By adding one channel to and interrupt, we are able to trigger the read subroutine automatically when the encoder is turned.

In bascom, that will give us:

A Alias Pind.3
B Alias Pind.4

Config A = Input
Config B = Input

Config Int0 = Falling

Dim Counter As Integer

Set B

On Int0 Getencoder

Counter = 0

Enable Interrupts
Enable Int0


Your code here


Waitms 1
If A = 0 Then
If B = 0 Then Incr Counter Else Decr Counter
End If


The pushbutton on the rotary encoder works just like a normal button, so nothing much to explain there.

Step 8: Graphics in Bascom

Picture of Graphics in Bascom
When having a graphical LCD, it's always nice to have some graphics on it. So you can either draw everything pixel by pixel (good luck!) or you can import premade graphics. The way to do it in Bascom is as follows:
  1. Draw an image in your favorite program. Don't forget the maximum dimensions (in my case 240*128)
  2. Save it as a monochrome bitmap.
  3. Run Bascom, goto Tools -> Graphic converter.
  4. A window opens, set the dimentions of your LCD, load your image and save it in the .bgf format. Don't forget to set the font to the type you are using.

Once you have converted the bitmap, can use it in your code. You need to include the bgf file to be able to use it.


Showpic X, Y, Image                   


$bgf "image.bgf"

The X and Y parameters specify where the picture must be displayed. X and Y must be 0 or a multiple of 8. The picture height and width must also be a multiple of 8.

Step 9: Code

Picture of Code

I'll just add the full code here. It is a bit messy as I didn't have any time left to clean it up. When I've cleaned it up (and improved it), I'll post the new code. I'll also add the pictures here that I used so that you can use them too.

When you program your Atmega, you should also disable JTAG in the fusebits and set the internal oscillator to 8MHz.

The code will fit into an Atmega16 but I used an Atmega32 as I want to add some extra features later.

$regfile = "m32def.dat"
$crystal = 8000000
$baud = 9600

Config Serialin = Buffered , Size = 255
Config Serialout = Buffered , Size = 100
Config Graphlcd = 240 * 128 , Dataport = Porta , Controlport = Portc , Ce = 5 , Cd = 4 , Wr = 7 , Rd = 6 , Reset = 2 , Fs = 3 , Mode = 8

Config Scl = Portc.0
Config Sda = Portc.1

Cha Alias Pind.3
Chb Alias Pind.4

Config Cha = Input
Config Chb = Input

Const Ds1307w = &HD0 'write DS1307
Const Ds1307r = &HD1 'read ds1307
Const Adsecs = &H00 'address seconds
Const Admins = &H01 'address minutes

Dim Count As Byte
Dim I As Byte
Dim J As Byte
Dim Pos As Byte
Dim Oldpos As Byte
Dim Maxpos As Byte
Dim State As Byte
Dim Volume As Byte
Dim Temp As Byte
Dim Uart_in As Byte
Dim Uart_buffer As Byte
Dim Hours As Byte
Dim Mins As Byte
Dim Secs As Byte
Dim Length As Byte
Dim Boxx As Byte
Dim Boxx2 As Byte
Dim Tube(4) As Byte
Dim X As Byte

Dim Uart_in_str As String * 255
Dim Stationname As String * 60
Dim Title As String * 60
Dim Station_pos As Byte
Dim Title_pos As Byte
Dim Pointer As Byte
Dim Station_length As Byte
Dim Title_length As Byte
Dim Temp_str As String * 4
Dim Volumestr As String * 3
Dim Station(20) As String * 30
On Int0 0int
Enable Int0
Enable Interrupts

'Set Chb

On Int1 1int ,
Enable Int1
Enable Interrupts

Wait 1

Showpic 0 , 0 , Intro
Box(115 , 90) -(200 , 104) , 255

For I = 118 To 194 Step 4

J = I + 3
Boxfill(i , 92) -(j , 102) , 255
Wait 3

Print Chr(13)
Wait 2
Print "mpc clear"
For I = 0 To 3
Stationname = Lookupstr(i , Tunerlist2)
Print "mpc add " ; Stationname
Print "mpc volume 50"
Print "mpc play"
Volume = 20
Gosub Empty_buffer
I = 1
Count = 1
State = I
If State = 1 Then Goto Radio
If State = 2 Then Goto Tuning
If State = 3 Then Goto Vol
If State = 4 Then Goto Setup


Maxpos = 6
Pos = 1
Oldpos = 1
Boxx = 0
Boxx2 = 40

Showpic 0 , 88 , Play
Showpic 40 , 88 , Pause
Showpic 80 , 88 , Stopp
Showpic 120 , 88 , Volume
Showpic 160 , 88 , Tuner
Showpic 200 , 88 , Clock
Box(0 , 88) -(40 , 127) , 255

If I <> State Then Goto Main
If Pos <> Oldpos Then
Box(boxx , 88) -(boxx2 , 127) , 0
Boxx = Pos - 1
Boxx = Boxx * 40
Boxx2 = Boxx + 40
Box(boxx , 88) -(boxx2 , 127) , 255
Oldpos = Pos
End If

Print "echo " ; Chr(34) ; "currentsong" ; Chr(34) ; " | nc localhost 6600 | grep -e " ; Chr(34) ; "^Title: " ; Chr(34) ; " -e " ; Chr(34) ; "^Name: " ; Chr(34) ; " > /dev/tts/0" ; Chr(13)
Waitms 500
Gosub Getuart
Gosub Parser
Cls Text
Locate 5 , 1
Lcd Stationname
Locate 8 , 1
Lcd Title

Gosub Readclock


Count = 1
Cls Text
If I <> State Then Goto Main
Gosub Readclock

For J = 1 To 4
Station(j) = Lookupstr(j , Tunerlist)
J = Count
Locate 5 , 5
Lcd Station(j)
J = Count + 1
Locate 6 , 5
Lcd Station(j)
J = Count + 2
Locate 7 , 5
Lcd Station(j)
Waitms 500

Gosub Readclock
If I <> State Then Goto Main
Print "echo " ; Chr(34) ; "status" ; Chr(34) ; " | nc localhost 6600 | grep -e " ; Chr(34) ; "^volume: " ; Chr(34) ; " > /dev/tts/0" ; Chr(13)
Waitms 100
Gosub Getuart
Gosub Volumeparser
Cls Text
Locate 6 , 10
Volume = Val(volumestr)
Lcd "Volume: " ; Volume


J = 1
If J = 1 Then Count = Hours Else Count = Mins
If I <> State Then Goto Main

'Gosub Readclock

If J = 1 Then Hours = Count Else Mins = Count

Tube(2) = Mins / 10 'splits the hours and minutes into
Temp = Tube(2) * 10 '4 digits so that it can be displayed
Tube(1) = Mins - Temp
Tube(4) = Hours / 10
Temp = Tube(4) * 10
Tube(3) = Hours - Temp

Temp = Tube(4)
X = 48
Gosub Clockpic
Temp = Tube(3)
X = 72
Gosub Clockpic
Temp = 11
X = 96
Gosub Clockpic
Temp = Tube(2)
X = 120
Gosub Clockpic
Temp = Tube(1)
X = 144
Gosub Clockpic

Locate 8 , 8
Lcd I
Waitms 100



If I = 1 And Pos = 1 Then Print "mpc play"
If I = 1 And Pos = 2 Then Print "mpc pause"
If I = 1 And Pos = 3 Then Print "mpc stop"
If I = 1 And Pos = 4 Then I = 3

If I = 1 And Pos = 6 Then I = 4
If State = 2 Then
Print "mpc play " ; Count
I = 1
End If
If I = 1 And Pos = 5 Then I = 2
Waitms 100
If State = 3 Then I = 1
If I = 4 And J = 2 Then
Gosub Setclock
I = 1
End If
If I = 4 And J = 1 Then
Gosub Setclock
J = 2
End If

Waitms 1
If Cha = 1 And I <> 3 Then
If Chb = 0 Then Incr Count Else Decr Count
End If
If Cha = 1 And I = 3 Then
If Chb = 0 Then Print "mpc volume +5" Else Print "mpc volume -5"
End If
Pos = Count
If Pos > Maxpos Then Pos = Maxpos
If Pos < 1 Then Pos = 1


Uart_in_str = ""
Uart_buffer = Ischarwaiting()
If Uart_buffer > 0 Then
Uart_in = Inkey()
If Len(uart_in_str) < 254 Then Uart_in_str = Uart_in_str + Chr(uart_in)
If Len(uart_in_str) = 254 Then Uart_in_str = Uart_in_str + Chr(13)
End If
Loop Until Uart_buffer = 0
Gosub Empty_buffer

Volumestr = ""
Temp = Instr(uart_in_str , "volume: ")
Temp = Temp + 8
Volumestr = Mid(uart_in_str , Temp , 3)


Stationname = ""
Title = ""
Station_pos = Instr(uart_in_str , "Name: ")
Title_pos = Instr(uart_in_str , "Title: ")

Station_pos = Station_pos + 6
Length = 0
Incr Length
Pointer = Station_pos + Length
Temp_str = Mid(uart_in_str , Pointer , 1)
Loop Until Temp_str = Chr(13) Or Temp_str = ""
If Length > 60 Then Length = 60
Stationname = Mid(uart_in_str , Station_pos , Length)

Title_pos = Title_pos + 7

Length = 0
Incr Length
Pointer = Title_pos + Length
Temp_str = Mid(uart_in_str , Pointer , 1)
Loop Until Temp_str = Chr(13) Or Temp_str = ""
If Length > 60 Then Length = 60
Title = Mid(uart_in_str , Title_pos , Length)

If Station_pos = 6 Then Stationname = "Name not found!"
If Title_pos = 7 Then Title = "Title not found!"



Uart_in = Inkey()
Uart_buffer = Ischarwaiting()
Loop Until Uart_buffer = 0


I2cwbyte Ds1307w
I2cwbyte Admins
I2cwbyte Ds1307r
I2crbyte Mins , Ack
I2crbyte Hours , Nack

Hours = Hours And &B00111111 'removes bit6 & bit7

Hours = Makedec(hours) 'converts BCD into Decimal
Mins = Makedec(mins)

Tube(2) = Mins / 10 'splits the hours and minutes into
Temp = Tube(2) * 10 '4 digits so that it can be displayed
Tube(1) = Mins - Temp
Tube(4) = Hours / 10
Temp = Tube(4) * 10
Tube(3) = Hours - Temp

Temp = Tube(4)
X = 48
Gosub Clockpic
Temp = Tube(3)
X = 72
Gosub Clockpic
Temp = 11
X = 96
Gosub Clockpic
Temp = Tube(2)
X = 120
Gosub Clockpic
Temp = Tube(1)
X = 144
Gosub Clockpic



Mins = Makebcd(mins)
Hours = Makebcd(hours)
Reset Hours.6
I2cwbyte Ds1307w
I2cwbyte Adsecs
I2cwbyte &B00000000
I2cwbyte Mins
I2cwbyte Hours

Hours = Hours And &B00111111 'removes bit6 & bit7

Hours = Makedec(hours) 'converts BCD into Decimal
Mins = Makedec(mins)


If Temp = 1 Then Showpic X , 0 , 1
If Temp = 2 Then Showpic X , 0 , 2
If Temp = 3 Then Showpic X , 0 , 3
If Temp = 4 Then Showpic X , 0 , 4
If Temp = 5 Then Showpic X , 0 , 5
If Temp = 6 Then Showpic X , 0 , 6
If Temp = 7 Then Showpic X , 0 , 7
If Temp = 8 Then Showpic X , 0 , 8
If Temp = 9 Then Showpic X , 0 , 9
If Temp = 0 Then Showpic X , 0 , 0
If Temp = 11 Then Showpic X , 0 , Dp

$bgf "wifiradio.bgf"
$bgf "play.bgf"
$bgf "pause.bgf"
$bgf "stop.bgf"
$bgf "volume.bgf"
$bgf "tuner.bgf"
$bgf "clock.bgf"
$bgf "0.bgf"
$bgf "1.bgf"
$bgf "2.bgf"
$bgf "3.bgf"
$bgf "4.bgf"
$bgf "5.bgf"
$bgf "6.bgf"
$bgf "7.bgf"
$bgf "8.bgf"
$bgf "9.bgf"
$bgf "dp.bgf"
$bgf "streep.bgf"

Data " " , "1920 Network" , "KCEA" , "FM Tango Junin Argentina" , "TANGOCLUB"


Data "" , "" , "" ,

Step 10: Building the Case: Wooden Body

Picture of Building the Case: Wooden Body

The case is build out of multiple layers of 18mm MDF and a 12mm layer of MDF for the front.

The layers where CNC-milled into their shape, but not entirely cut out (about 1mm remained). This way they were stronger and easier to glue and clamp. Three holes were milled through the plates to serve as guides: I could add dowels to make positioning the layes on top of each other easier.

When everything was dry the layers where cut out with a sharp knife and the front layer was glued on. When this layer was dry and cut out, everything was cleaned up and sanded to give it a smooth shape.

The case is finished in a white veneer.

Step 11: The Front and Back Panel

Picture of The Front and Back Panel
The front and back panels where CNC-milled out of alucobond.

Three switches and five LED's (in LED holders) were inserted into the frontpanel.

The switches are for:
  • Main power
  • Amplifier power
  • Toggle front or back output

The LED's are for:

  • Main power
  • Amplifier power
  • Air (wifi connected)
  • Router ready
  • Soundcard playing

There is also a headphone output in the front, which cuts all other outputs when a headphone is inserted.

After all these devices were added to the front panel, the panel was glued to the the body. After that the rotary encoder was added and finished off with a nice knob.

The back panel had an audio output and a programming connector inserted and glued to it, a powerconnector was screwed to it and the router was added. The panel is screwed to the body so that it can be removed easely.

Step 12: Bringing Everything Together

Picture of Bringing Everything Together

So now it is time to bring everything together.

First the speakers and the LCD (with on its back the PCB for the interface) are screwed into place.

Fitting the amplifier

As I said before, I used an amplifier that I bought as a kit, so I soldered that together. That is going in next but first of all we need to solder the wires that come from the Amplifier Power - LED to the place where the led should normally sit on the board. We also need to connect the audio coming from the soundcard to this amplifier. This is a bit more complicated as it runs from the soundcard to the headphone connector, then to a switch from where it goes either to the amplifier or to the connector in the back.
Once everything is connected and the speakers are also connected to the amplifier, then the amplifier is screwed into the case.

Fitting the router and soundcard

I removed the USB-connectors from both devices and soldered them together with wires instead of connecting them via a USB cable. I had to do that because otherwise the router would't fit in the back panel. So I also had to remove the power connector of the router and solder that directly to the powerboard too.

I removed the Air and Power LED from the router and wired the LED's in the front panel to those pads. I also removed the Play LED from the soundcard and wired that to an LED in the front. Then the soundcard was screwed into the case and the router was fitted into the back panel.

Wiring the last things up

The rotary encoder and the RS232 from the router are connected to the interface board via a flatcable and the last remaining LED is connected to the powerboard. Connect all the devices to the powerboard too.

The powerboard

The powerboard is a little piece of veroboard with two 78S05 (2A), and a bunch of capacitors soldered to it. One of the regulators is for the screen and interface and one for the router. You really need to cool the regulator of the router. The amplifier uses 12V directly from the main power.

I used an external 12V DC 6A powersupply for this project.

When everything is hooked up, you can screw the backpannel in place and enjoy the music!

Step 13: What Now?

Although the radio works and everything does what it should do, there are some improvements to make.

First of all I need to clean up the code a bit and I would like to make an even more graphical interface. I also have to look to the rotary encoder as it works to slow and has a to big deboucetime. 

Secondly, when you look at the schematics, you'll see that there is an I2C connector of optional devices. I intend to add a weatherstation to the radio with weather info gathered via sensors in the radio as well as info that comes from the internet.

It would also be nice to be able to show an RSS feed on the LCD.

So lots of things to do and to look at. And maybe you have some ideas too, so let me know....

Step 14: Why I Would Love to Win the Lasecutter

I really wanted this project to look as nice as possible, so I invested a lot of time in the overall design and building the case. I hope that this build is awesome enough to have a chance in the lasercutter contest as I would love to have one of these machines.

They would allow me to make even nicer looking and more intricate cases and parts. Also making gears would be a lot easier, so I would be able to make complex mechaninical movements. A lasercutter would be the ideal solution, as I work a lot with acrylate and other plastics. It would enable me to make designs that that a CNC-router can't make and I wouldn't have to bother my friends all the time to use theire machines.

It would ofcourse also be great for my friends, who also happen to build a lot of stuff, to have access to such a device. So it would surely boost the creativity of those people around me too ( they would surely pay me a lot more visits ;) ). I have no commercial intensions with the machine, just building stuff and helping people build theire projects and ofcourse sharing everything on Instructables.


ninja21 (author)2014-10-20

Everything went well until I plug the usb soundcard... just burn the sound card.

I try again and burn another soundcard.

Can anyone help me before the store run out of soundcards?

janw (author)ninja212014-10-21

Burning the soundcard means that somehow + and gnd might be swapped. Have you plugged it in toe the onboard usb connector or have you desoldered the connector and soldered wires directly to it?

Just a note on the side: these days, its easier to use a raspberry pi as basis for a wifi radio. It has an onboard soundcard and is quite easy to control via a pc or mobile device.

ninja21 (author)janw2015-08-23

Solved: wrong router power source (12v)

Machiuka. made it! (author)2015-01-25

I've made one from a salvaged satellite receiver (SSR). It has a web interface and a remote control. I've used the SSR's power supply and front panel to display current date and time and other informations such as currency, precious metal quotations etc. I've posted all the detail on my blog and on my youtube channel - machiuka.

Milen (author)2013-04-20

I would like to use your control board to drive Digole 128x64Dots Serial/Parallel LCD with ST7920 LCD controller/driver IC. Can you help me to connect it. I need an correspondence table: which pin from the ATMEGA control board to which pin of the LCD module must connect. I suppose that also some re-definitions for the controller pins must be done in the program code. Thank you for the support

P.S. A link to the datasheet :

janw (author)Milen2013-04-23

I am not shure whether those LCDs are compatible.
I am guessing that your display is more intented to display characters and not graphics. Also the amount of pixels is different so you will have to rewrite the code to design your own grafics which fit your display.

Anyhow: you have to drive your lcd in parallel mode.

D0 to D7 can be connected to the same pins
WR is RW in your case
Can't remeber what RS was
CE = E in your case

If you have an atmega with multiple serial connections you can also use 2 lines for the serial communication and them you don't have to mess wit all teh wires

Set271 (author)2011-04-10

Schematic is hard to read

janw (author)Set2712011-04-11

Even when you look at it full size?? Click the i in the upper left corner and then select the full size.

Milen (author)janw2012-09-05

Can you provide the Eagle files (schematics and board) for download?

janw (author)Milen2012-09-05

I added them to the appropriate step.

janur55 (author)2011-11-07

i want to build WIR too,,
but i have a question
to make WIR, should i build my own server?, or i can use server which built by anyone...maybe like directly access

janw (author)janur552011-11-08

You can use the radiostations from shoutcast. Or any other server if you like.

janur55 (author)janw2011-11-08

thx for fast respon
another question..hehe
i dont undertstand what the mpd is it?
the mpd is installed on wireless router or on pc?

janw (author)janur552011-11-10

it is installed on the wireless router.

Brother_P (author)2011-11-04

Fabulous project! I'm always looking for hobby projects to run in my high school, and this is way cool. Question: does the choice of router matter? I have a few discarded ones laying around that are doing nothing.

janw (author)Brother_P2011-11-04

The choice for the router is rather specific. It has to have a USB port and you have to be able to talk to it via a rs232 connection. The forum on has a list of all possible routers.

djjoec (author)2011-10-20

This might sound like a stupid question but can I make my powered speakers run on wifi. What I mean is transmit sound so I havn't got leads running every where as I run a wedding dj business in Melbourne. I don't know if this is possible.

zleebme (author)djjoec2011-10-20

They have bluetooth speakers you should look into, but seeing as your a dj note you will get diminished sound quality any way that you go on wireless sound transmission.

janw (author)zleebme2011-10-20

There are indeed a lot of off-the-shelf solutions but as you say, they are not always good for the sound quality.

qwerty156 (author)2011-05-15

You could also use the Nokia 6100 Graphic LCD, You would be able to acheive a better, higher resolution and a colorful UI!

Kudos on the build, well done

DerekMc525 (author)2011-04-08

Wow, Great Idea! And to think, I just use an old outdated laptop, Makes me want to try build some laptop component radio combo set? Once again, Great work, It looks very well done!

kinoremake (author)2011-04-04

this is a really cool stuff, never thought about wifi radio, but now I probably will try to build it

Rhamkota (author)2011-04-02

I know this sounds really dumb, but what's the quartz crystal for?

janw (author)Rhamkota2011-04-02

A quartz crystal pulses when you add electricity to it. The DS1307 counts the pulses and calculates time that way.

Andrew Pearce (author)2011-03-27

I'm wondering if instead of adding a usb or card reader like Ugifer said, wouldn't it be possible to stream music from your wifi phone or ipod through the router? Hate all those stink radio clocks and stereos you can buy that have the ipod plug!
This rocks.

chicopluma (author)2011-03-26

really cool and i relly like your conceptual speakers design

kc6qhp (author)2011-03-24

WOW! Very nicely done in all respects!

I'm the one who built the case for Jeff's radio and I can appreciate the amount of work that goes into building a case like what you built. Very very nicely done!


janw (author)kc6qhp2011-03-26

Thanks a lot Tony,

It is great to get positive feedback from the guy that build the original one!


Lindie (author)2011-03-26

I love the design! Great job!

gisdead (author)2011-03-24

Kinda random question: I'm about to buy a soldering iron and wondering what to buy. I know its a weird place to ask but I saw your orange handled one in the background and wondered what kind you prefer.

janw (author)gisdead2011-03-24

I have an old one from Weller and a new Velleman and I am pretty pleased with both of them.

gisdead (author)janw2011-03-25

Awesome. Thanks so much.

Ugifer (author)2011-03-25

This is the most incredible project - beautiful design, professional-looking execution, clever use of cheap materials, CNC!, all it needs is a jacob's ladder on top and to be able to bake cookies and you have achieved every instructable all rolled into one!

A thought regarding further expansion (as if it didn't do enough already); How about a USB port or SD card reader so that it could play music from an external source also? A SNTP sync-ed clock on the display is also handy on nearly anything and you might make that the display when it's on but not playing.

This really is a top project. Thanks.

gisdead (author)2011-03-24

Awesome Job btw!

xAxrules (author)2011-03-22

This is brilliant. I nicely designed case, a good interface and it sounds great, can't wait to make one of my own!

JesusFreke (author)2011-03-20

Wait a second! You can't mention something unique and interesting like "Tibetian Riverdancing" without giving us a link!

janw (author)JesusFreke2011-03-21


Try google?!


isacco (author)2011-03-21

Congratulations for this beautiful object.
The case is outstanding for its design, crafting and finishing quality.
The particular assembling imposes a large waste of MDF, but it is really worth!
The instructable is very well illustrated and explained.

janw (author)isacco2011-03-21

it is a waste of MDF indeed bt I got it for free (hehehe) and you sometimes have to be a bit wastefull to make something nicelooking.

Honus (author)2011-03-20

Beautiful job. I also follow Jeff's blog -it's awesome.

Reffner (author)2011-03-20

This is awesome. You did an excellent job on the whole thing, but the case is super slick. As far as I'm concerned, the contest can end win!!!

About This Instructable




Bio: I'm mainly interested in music, food and electronics but I like to read and learn about a lot more than that.
More by janw:Pickled ChilliesExtra hot sriracha sauce (Mme Jeanette)Build a Nest Box for Bumblebees
Add instructable to: