Yes, I know this has been done before, but I wanted to build my own, using as few parts as possible. I built this as a table top or wall mount model, but it can be scaled up to make a coffee table. I built it as a study for a more ambitious project, which will be an 8×8 RGB coffee table. In designing this project, I wanted to keep the part count and cost as low as possible, and also to design the software for speed and minimal memory usage.
The code I used in the Arduino sketch demonstrates direct port manipulation, which is a fast and powerful alternative to digitalWrite().
Update 3/10/2011 : Finished adding the Music Synchronization section of this Instructable.
Update 3/20/2011: I decided to build Lampduino instead of the coffee table.
Note that the flickering in the video below was caused by my video camera. When viewed with the naked eye, no scanning is perceived, and the lights do not flicker.
Step 1: Acquire the Parts
25 LED’s – I used warm white 5mm LED’s purchased on eBay
5 resistors – I used 100 ohm, but the exact value will depend on what LED’s you use. I will explain how to calculate in the Wiring step.
NOTE: You may need also need 10 diodes and different resistors, especially if you are using white LED’s… please the Troubleshooting section in step 3 for details.
Arduino – I used a Duemilanove clone – in Step 7, I switch to a much cheaper alternative.
white foam board
.005″ thick matte drafting film – I bought a sheet from a local artist’s supply store. The smallest sheet they had was way more than I needed – 24×36″
If you want to implement music synchronization capabilities, you will also need some more parts, as discussed in the Music Synchronization step.
hot glue gun
The LED’s I used were point source water clear. If you don’t want to deal with hotspots in your display, diffused would be better. I had to put blobs of hot glue on mine to diffuse them. The photo below only shows bits of the foam board, because I forgot to photograph the parts before I started. The piece I used was about 16×20″ to start with.
Step 2: Build the Display
I used foam board, which was recycled from one of my kids’ science fair projects. It is a sandwich of white paper with a foam core, 3/16″ thick. The overall size is approximately of our project is approximately 10x10x2″. I cut the parts with a mat knife, and hot glued it together.
To make the grid, cut 8 identical 2×10″ pieces. Then cut 4 equally spaced slits into each one. The slits should be 1″ deep, the same width as the foam board. Interlock the pieces to create the 5×5 grid.
Next, cut a 10×10″ piece of foam for the back. Hot glue it to the 5×5 grid.
Cut 2 more 2×10″ pieces to form the sides, and glue them on.
Finally, cut the 2 (10 3/8)x2″ pieces for the top and bottom. My foam was 3/16″ thick, so I had to add 3/8″ to the length to make them long enough to cover the sides. Hot glue them on.
Note that in the photo below which includes the top & bottom & sides, the LED’s are already installed and wired up. This is because I didn’t attach the top/bottom/sides until I was in the testing phase, but it’s easier to deal with if you glue them on earlier in the process.
Step 3: Wire it up
Cut small diagonal slits in the center of each cell, and insert one LED in each cell. Make sure to orient them the same way in each cell. This will make it less confusing when wiring it up. I laid mine out w/ the flat side (cathode) facing the bottom right corner. Using diagonal slits for the pins makes it easier to wire it up without shorting the wires, since we are going to wire
it as a crossbar.
While one can use any of the I/O pins on the Arduino, I chose the pins specifically to allow me to use very compact code to turn on the columns. This will be explained in detail later.
To drive our 5×5 LED matrix, we directly drive the LED’s using 10 digital I/O pins on the Arduino.
The anodes are connected to pins. Some existing designs, such as the one in the Arduino Playground don’t bother to use current limiting resistors. This is not a good design practice, and can result in burned out LED’s, or worse yet, a burned out Arduino. Each I/O pin on the Arduino can source or sink up to 40mA of current. The LED’s which I used have the following electrical characteristics:
Forward Voltage = 3.2 ~ 3.4V
Max Continuous Forward Current = 20mA
So if we want to drive the LED’s for maximum brightness, we need to target 20mA of current.
To calculate the proper resistor value, we use Ohm’s Law:
R = (Vcc – Vf) / If
R = resistor value in ohms
Vcc = supply voltage = 5V for the Arduino Duemilanove
Vf = LED forward voltage. I used the average, 3.3V
If = LED current in amperes = .020A
Plugging in the values, we get R = (5 – 3.3) / .02 = 85 ohms. The nearest available standard resistor value is 100 ohms. Always round up instead of down, because if you round down, you will exceed the maximum allowable current.
Notice that we only use 5 resistors. We don’t have to put one at each LED, because we will only be driving one row, a maximum of 5 LED’s at a time. I said above that each I/O pin can drive 40mA of continuous current, so why can’t we drive the whole LED array at once? It’s because another constraint is that the total drive current summed up across all the pins can’t exceed 200mA. If we turn on all 25 LED’s at once, then 25*20mA = 500mA flow, which is way over spec.
So maybe we can turn on 1 row at a time, and scan the rows, like the way a CRT works? If we turn on a whole row of LED’s at once, the current is 20mA * 5 = 100mA. This, at first, appears to be OK, because each column (anode) pin is only sourcing 20mA, and we’re below the Atmega368P’s total 200mA current limit. However, upon more analysis, we can’t even drive 5 LED’s at once. Why? Because the cathodes of all 5 LED’s in a row are connected together into a single I/O pin, and we’re not allowed to sink more than 40mA per pin. Therefore, we will write our software so that no more than 2 LED’s are turned on at a time, so the row (cathode) pins will sink a maximum of 40mA each. Now, even though we’re at the allowable continuous current limit, it’s generally not good practice to run a device at its maximum limits. However, since we’re going to pulse each LED briefly, and let persistence of vision create the illusion that they’re all on at once, it’s OK.
Note: I tried running mine w/ 5 LED’s lit per row for several hours, and it worked fine, but it’s always best to design your circuits within specifications, to ensure long term reliability.
The circuit diagram is below. To summarize the connections:
LED Columns (anodes)
col 0 connects to digital pin 12 (via a 100 ohm resistor)
col 1 connects to digital pin 11 (via a 100 ohm resistor)
col 2 connects to digital pin 10 (via a 100 ohm resistor)
col 3 connects to digital pin 9 (via a 100 ohm resistor)
col 4 connects to digital pin 8 (via a 100 ohm resistor)
LED Rows (cathodes)
row 0 connects to digital pin 7
row 1 connects to digital pin 6
row 2 connects to digital pin 5
row 3 connects to digital pin 4
row 4 connects to digital pin 3
I used simple point to point wiring, fastened with hot melt glue to the back of the display. I know it’s messy looking, but it won’t be seen, anyway.
If your matrix doesn’t function properly, first, you should double check your wiring. The sketch also has a testing mode, which cycles through the LED’s one by one slowly enough that you can see it. You can enable it by uncommenting the following line in the sketch:
//#define TESTMODE // continuously sequence thru the LED’s
by removing the leading //.
One potential mistake is accidentally swapping the columns and rows. If your matrix looks like this video http://www.youtube.com/watch?v=JpLgLbWMrWo in TESTMODE, then you’ve made this error, and need to swap the row and column connections to your Arduino. Thanks to Instructables user 303_addict for posting the video.
If your wiring is correct, and you are getting more than one LED at a time lighting up, you might be one of the unlucky ones who has LED’s that have a high leakage current when reverse biased. White LED’s are particulary susceptible to this problem. If this is the case, you will need to add series blocking diodes on the inputs to all the columns, as well as on all the row outputs. So you will need 10 diodes. Any small signal diode will work, such as 1N4001, 1N914, 1N4148, etc. You will also need to adjust the resistor values, because two series diodes will add ~1.4V voltage drop. So in my equation above, use 3.6 for VCC. For my 3.3V LED’s you end up with R = (5-1.4-3.3V)/20mA = 15 ohms. I didn’t have any 15 ohm resistors handy, so I substituted 10 ohms instead, and using an ammeter, measured 19.5mA .. still within spec. See the last attached image.
Step 4: Diffusing the LED’s
I used point source LED’s, because that’s what I had in my parts bin. This caused hot spots in the display. If you like it that way, you don’t have modify them. I wanted more even lighting. The two most common ways of converting point source LED’s to diffused is to either sand them or just encase them in hot melt glue. I decided to use hot melt glue. Just put a big blob of hot glue on each LED. I found that it looks more even if you can keep the glue blob smooth. The shape doesn’t have to be perfectly round, but if you apply it in layers, the edges between the layers tend to cause variations in the brightness. In the photo below, the LED in the top right cell has hot glue on it, while the rest are bare. Note that it does a decent job of evening out the light.
At first, I used white copier paper to cover the LED’s. It darkened the display to bit too much, and looked grainy. Then I went to an art store, and found .005″ thick matte drafting film. It looks a lot better. I cut a 10 3/8 x 10 3/8″ piece and glued it to the front.
Step 5: Code
The display code is interrupt driven, and uses the Timer1 library . Timer1 isn’t bundled in the Arduino software installation. Therefore, to install it, you must download TimerOne.zip , and unzip its contents into your sketchbook/libraries/TimerOne.