Step 3: Wire it up
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 5x5 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.