Building a Wifi Radio – Part 7, Building an LCD Display

This is the seventh part of an ongoing series about building a low cost, open source streaming internet radio.  If you haven’t already, check out the previous parts (see the links at the end of this article) for some background about the project.

In part six, we used OpenWrt’s UNIX-style shell commands to interface with mpd, the music player daemon, and redirect song and stream information to our ASUS WL-520gU wireless router’s serial port.  In this part, we’ll use a Sparkfun 16×2 LCD display and a handful of other components to build an LCD status display for the radio.

The Atmel AVR Microcontroller:

After much thought, I decided to use an Atmel ATmega168 AVR microcontroller to drive the display.  I realize that this raises the technical level of this project significantly, but I have been wanting to feature an AVR project on the site and this is a great opportunity.  The truth is that an Arduino would work just as well and it shouldn’t be too difficult to port this program to an Arduino sketch.  (The Arduino is built with the same ATmega168 microcontroller, after all.)  If anyone does this, let me know and I’ll post a link to your version of the display.

If you’re an AVR veteran, you can skip over this part and straight to the bill of materials below.

If you are new to the AVR, don’t be intimidated.  There are a number of tutorials online to help you learn how to use this inexpensive and powerful microcontroller.  I recommend starting with this one or maybe this one, but see my note about AVR MacPack below if you’re using a Mac.  If you’ve never programmed in C before, you’ll have an additional hurdle to get over, although for this project you won’t need any actual knowledge of programming or C to burn the code to the AVR and get things working.

You will need to install some software to work with the AVR, I recommend:

  • AVR MacPack for OS X (the Adafruit tutorial recommends OSX-AVR, use this instead)
  • WinAVR for Windows

I recommend following a tutorial or two and getting a simple blinking LED example working on your AVR before building the LCD display.  That way you can be sure your programmer, development environment, breadboard, etc are working first.

Building the display:

Bill of Materials:

You will need:

also nice, but not required:

  • a Sparkfun ISP breakout board to simplify connecting the programmer to the breadboard
  • a normally-open pushbutton switch to reset the circuit


Here is the schematic of the LCD display (click to enlarge):

Wifi Radio LCD Display Schematic


You can download the source code and compiled .hex file here.

Special thanks to Peter Fleury for his excellent LCD library, which saved me from reinventing the wheel!  He also has another page about interfacing LCD displays to an AVR.

Assembling the circuit:

Assembling the circuit on the breadboard is pretty straightforward.  Here’s a photo showing all components of the setup.  The router is shown above with the serial port wired to the breadboard (the RX line is floating as we’re not using it yet).  The USB AVR programmer is on the right, where it is also functioning as a 5V power supply for the circuit. Make sure the 2-pin jumper on the USBTinyISP is installed, this enables the +5V supply.  The LCD is shown displaying the current stream name (

Wifi Radio LCD Display

Here is a closeup of the components installed on the breadboard to show how I did things, feel free to experiment with the placement of components.  As long as you follow the schematic the circuit should still work.

Wifi Radio LCD Display

Here is a closeup of the serial port connection to the router, including the 4-pin female 0.1″ header.  I soldered wires to the pins of the female header (not the pins on the board).

Wifi Radio LCD Display

Here is a closeup of the AVR, crystal, and the Sparkfun ISP breakout board showing the pinout:

Wifi Radio LCD Display

Flashing the AVR:

Once the circuit is assembled on the breadboard, we need to flash the AVR microcontroller with the main.hex file included with the firmware above.

If you’re using AVR MacPack and OS X, this should be easy (since that’s what I’m using).  PC guys will need to figure this out for themselves but hopefully the process is similar (please let me know if the Makefile works).

Connect the USBTinyISP to your computer with the USB cable and to the breadboard with the ISP cable.  The green light on the programmer should be on, indicating it is ready, and the backlight of the LCD should be lit, indicating that the breadboard is getting power.

Open a terminal window and create a new directory, I used ~/temp.  Unzip the firmware into a directory somewhere, and execute ‘make flash’, as shown:

macbook:temp jkeyzer$ unzip ./
Archive:  ./
  inflating: lcd.c
  inflating: lcd.h
  inflating: main.c
  inflating: main.hex
  inflating: Makefile
macbook:temp jkeyzer$ make flash
avr-gcc -Wall -Os -DF_CPU=16000000 -mmcu=atmega168  -c main.c -o main.o

a few warnings later …

avr-gcc -Wall -Os -DF_CPU=16000000 -mmcu=atmega168  -c lcd.c -o lcd.o
avr-gcc -Wall -Os -DF_CPU=16000000 -mmcu=atmega168  -o main.elf main.o lcd.o
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avrdude -c usbtiny -p atmega168 -U flash:w:main.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e9406
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: writing flash (1326 bytes):
Writing | ################################################## | 100% 3.32s
avrdude: 1326 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 1326 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.68s
avrdude: verifying ...
avrdude: 1326 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done.  Thank you.

If everything went well, the LCD display firmware is now loaded into the ATmega168 and the circuit is ready to go.  If not, double check your connections and take a look at the help! page for the USBTinyISP.

Testing the display:

Telnet or ssh into the router.  Start mpd and connect to a stream using mpc (we covered this in part five).

Once the stream starts playing, execute the script we created in part six.  Within a few seconds, if everything is working, you should see the stream name on the display, followed by the artist and name of the current song.  Congratulations!

Here is a video of the LCD display in action, including the horizontal scrolling feature to show information that is too wide to fit within the visible area of the display:

That’s it for part seven!  In part eight, we’ll start working on the input side of the user interface.

Like what you’re seeing?  Have suggestions about what could be improved?  Leave a comment or contact me directly.

Update: Part eight, in which I add a tuning control to the radio, is now available.

Update 2: There is a new Wifi Radio Discussion Forum, hop over there to ask questions about the project or see what other people are working on!  (4/12/09)

28 thoughts on “Building a Wifi Radio – Part 7, Building an LCD Display”

  1. Hey Jeff

    I almost asked this in the forum, but thought it maybe easier to ask here as other maybe thinking the same thing in relation to the circuit diagram.

    I see that you have RX -> TX connected from the 520 to the ATmega, but aren’t they running at different voltages? I realize the Voltage line out on the serial port on the 520 isn’t connected to anything, and I’m assuming the ATmega is running at 5V. Is that the case?

    I’m currently connecting my 520 to an Arduino, via the USB port on the Arduino to a USB Serial on the 520, but that’s not looking like it’ll work reliably, so I’m back to using the internal on board serial on the 520, or maybe moving over to a 500GP.


    1. Chris,

      The WL-520gU has a 3.3V serial port. I am running the AVR at 5V. The AVR can handle a 3.3V serial input with no problem so I connected that directly. On the TX side, however, you need to limit the voltage to avoid going above 3.3V and potentially damaging the router. In part 8 I used a resistor divider made of two 1k resistors to do this – ideally it will limit the voltage to 2.5V. It may also slow down the serial pulse edges but I haven’t seen any problems in my testing.


  2. Hey Foo,

    First of all, I created a new forum for this project over at

    to help facilitate discussions like these. I know using the blog comment area exclusively for support was starting to get on some people’s nerves!

    Ok, on to your problems:
    If you burn the new AVR code (from part 8) to the ATmega, it should show some startup text on the LCD screen without you even having to run Get this working first before you mess with the software on the router. You don’t even need a serial connection.

    One thing that might be wrong is that your AVR might not have the right fuses programmed. Try running “make fuse” after you flash the firmware. I omitted this from the instructions in the post and that alone might fix your problem.

    Doublecheck your LCD wiring to the AVR. One wrong wire and the display will do what you describe. The dark first line is a sign that the LCD is not initialized. Either the AVR is not sending the right instructions or they aren’t actually getting to the LCD.

    Are you using a Sparkfun LCD module? Some LCDs might not work with my code. Not all LCDs are created equal, some have different driver ICs on them. Admittedly I have never run across an LCD that I was not able to get some output from, so this is most likely not your problem. But checking another LCD woudln’t be a bad idea if everything else fails…

    By the way, I have noticed the router rebooting issue also. To avoid this, I don’t mess with the serial connections while the router is powered up. I just connect the AVR and leave it connected the whole time the router is on. I’m not sure why this happens.


  3. I hate there isn’t an edit or remove button for the posts…..
    Anyway, me, yet again. I have the radio working, I have the LCD working, but I still can’t get it to display what is playing….Right now all I have on the LCD display is a repeating message about our kind host and project owner, MightyOhm.

    At one point I just gave up on and skipped to part 8, loaded and, and flashed with the new code, I think that is when I started getting the message on the lcd. I don’t understand the whole deal with setting the router to, once I did that, no more connectivity, therefor, nothing to display since I couldn’t get to any of the radio stations.
    I took out the static ip, and rebooted, and now when I run, it just hangs…no output, and that is even after downloading it a second time.
    Is there somewhere else I can ask for help, has anyone gotten this working according to the instructions, or has everyone taken off in different directions?
    Not much help in the comments on hackaday either. I feel like I am close, but Jeff may be skipping something he feels is so basic it doesn’t bear repeating…trust me, there is nothing too basic to tell me on this. Thanks for anyone that can comment.

    PS, in all the code examples, it says “changes in bold”. Nothing is in bold for me.

  4. OK, thanks. I just got my crystal and some other parts from sparkfun. Bad news is, still no display on the LCD.
    Is there anyway to use my multimeter to monitor the output of the Atmega pins? I don’t believe it is the problem, as I have successfully flashed the code on it a few times from blinky led to the code I DL from you, Connecting the serial port of the router to a hyperterminal shows the output I am expecting.
    The LCD lights up (backlights) and the contrast pot makes it brighter and dimmer (though only the top line). Seeing if the signal I should be getting from the controller is actually coming out of the pin I expect would help. Thanks!

  5. OK….after reading through the site and comments a few more times, I find that I need some sort of Crystal….

    I find no specifications for this crystal other that it appears to be 16Mhz, can you give a part number or source please?

  6. Hey all….
    I have the router playing, but running into 2 significant problems.
    1) Half the time I attach to the serial header soldered onto the router, every light on the router lights up and it reboots.
    2) I have succesfully flashed the controller with a LED Blinky program, and get success codes back when I flash the LCD code to it, but I have yet to see any character on the LCD. I am afraid most of the problem is that I somehow ended up with a 3+- volt lcd as opposed to the 5 volt. What modifications would be neccessary to make this work…the pin outs look exactly the same, but nothing shows up on the lcd (the backlight and contrast pot work).

  7. It should be fine. I don’t know how much overhead the power supply circuit has, but I would imagine that 50mA should be within the design limits. Make sure your LCD works on 3.3V, many are 5V only (like mine).

  8. Hi Jeff! Nice project, I’m working on a similar project, but I’m using the Asus WL-500G Premium, om mine there is a 3.3v Out pin on the pcb, and im not sure if i can draw current from that to support the avr circuit, i have a 40×2 char lcd and basically the same curcuit that you have, it should not draw anymore than 50mA, any ideas ?

  9. Too many distractions have been keeping me away from part 8. Unfortunately it’s going to be a while longer. My plan is to use the A/D input of the AVR to read the position of a tuning knob, then transmit that position back to the router over the serial port. Some shell script magic will use that reading to change stations – if I can get it all working!

  10. This is a great series! Please keep up the good work! As soon as I scrounge together some of the parts, I’m going to try making one for myself…

  11. Would it be possible for you to show the underside of the LCD, just to see how you soldered the female pins on the LCD?, assuming you just soldered some female headers to the bottom and plugged the LCD directly into the breadboard.

  12. great project Jeff
    two points

    You added a avr to the io port on the router, you can now expand this to do amazing other things, like switch lighting / heating monitoring/controlling, of your workspace /shed from anywhere within your network and further if you desire
    great work!

  13. My WL520GU’s (plural, one for this project and another for something else) should be arriving tomorrow. I’m skipping the display though and will see how possible it will be to get espeak running on this to have a talking web radio. I have my USB hub, numeric keypad, and will have the router soon; I just need the USB sound adapter and a flash drive (to put extra software on, like espeak) and I’ll be ready to see how much I can break stuff 🙂 This is pretty exciting.

  14. This is a great project – following it with great interest. Seems the ASUS WL-520gU is a tricky one to get hold of here in the UK – do any other commenters have a good source for this item in UK / Europe? Keep up the good work Jeff.

  15. From their site:

    Does ship internationally? does not currently ship internationally; we only deliver to locations within the United States and to Puerto Rico.

    Sorry. 🙁

  16. TheDonkey –

    My original goal was to release 1 part a week. Obviously this hasn’t worked out (too many other things going on) so the truth is I release a new part when I can get around to it.

    My intent is that each post contains enough detail that the reader could actually use my project as a springboard to take the project in a different direction or even finish it before I do. I lay everything out so that you can see what my thought process was and why I made certain decisions along the way.

    I know a lot of people are happy with the result of part five alone, which can very easily be turned into a remotely controlled music player by using one of the many mpd client programs out there. Just connect it to your entertainment system and you have a pretty nice remotely controlled streaming radio player. The truth is, you can bail out at any step beyond part five and still have a pretty cool result.

    I’ve seen people do some really cool things that I never would have thought of, including a network share mp3 player and a twitter lights status indicator (awesome!).

    My advice is, instead of waiting for this to be done, buy the router and start playing with it. There is a lot you can learn and do for very little initial investment and there is plenty of support available if you get stuck. Don’t wait until I’m done to get started, get in there and start hacking around. Who knows, maybe you’ll find a better way of doing things than I did and you can tell us about it!


Leave a Reply