The objective of this post is to explain how to create a simple LED Matrix using PNP transistors and a ULN2803A integrated circuit. We will assume that only one LED (or none) needs to be connected at each time.
First of all, we need to take into account that, if we wanted to control a matrix with a total of X LEDs and to be able to control each one individually, we would need a total of X output pins (for example, from a microcontroller or a specialized integrated circuit). Of course that, when X is large, this becomes difficult.
In the simpler case proposed, only one LED needs to be on at a given time, so we will use a matrix configuration where the anodes of the LEDs are going to be connected in rows and the cathodes in columns. Check figure 1 to remember what is the anode and the cathode of a LED.
Naturally, anodes can only be connected to VCC and cathodes to GND. Also, remember that, for a LED to operate, its cathode needs to be connected to GND and not just floating.
With the approach proposed, in an N x M matrix (N columns and M rows) we will only need N + M pins to control all the LEDs. For example, with 16 pins (8+8), we can control 64 LEDs (8×8). As stated before, if we wanted to control each of the 64 LEDs individually, we would need 64 pins.
In order to simplify things, we will use as an example a 3×3 matrix, meaning that we will have 3 rows and 3 columns. We will also assume that each LED will be represented by 2 coordinates, the first one representing the row and the second one the column, as shown in figure 2.
To illustrate how the matrix works, we start by assuming that both the rows and the columns are disconnected from VCC and GND, respectively. If we now connect, for example, row 1 to VCC, all the LEDs on that row will have their anodes connected to VCC. But, since no column is connected to GND, their cathodes are not connected to GND either, and thus no LED will be turned on. Figure 3 illustrates this situation.
If we now disconnect row 1 from VCC and connect column 1 to GND, all the cathodes of the LEDs in column 1 will be connected do GND. As expected, the LEDs will also not emit light because the anodes are not connected to VCC. Figure 4 shows this configuration.
So, if we want to turn on LED [1,1], we just need to connect row 1 to VCC and column 1 to GND. In this case, all anodes of LEDs in row 1 will be connected to VCC and all cathodes of LEDs in column 1 to GND, but only LED [1,1] will be connected to both GND and VCC, and thus emit light. Figure 5 exemplifies the working configuration.
Naturally, we will need to control the connections of the rows to VCC, for which we will use a PNP transistor. The characteristics of the transistor should be adequate to the LED used, but those calculations are outside the scope of this post.
To control the connections of the columns to GND, we can use an ULN2803A.
We should not forget to put a resistor in series with each LED row, which should be dimensioned accordingly to the value of VCC and the current consumption of the LED. Check here for an automatic tool to calculate the series resistor value to use with a LED.
We should also need to put a resistor in series with the base pin of the PNP transistors, to avoid damaging the output pins of the controlling device. Check the section “Base Resistors!” of this article to understand why we need them.
For the sake of simplicity, we first start with the configuration for a row of the matrix, shown in figure 6.
In figure 7, we show the configuration for a column of the matrix.
Figure 8 shows the whole matrix configuration. Although the sobreposition makes the design a little bit confusing, soldering it in a perf board is actually very simple.
Although this example uses the ULN2803A to sink current (to control the connections to ground), a NPN transistor could instead be used for each column. Internally, the ULN is composed of NPN Darligton pairs , meaning the result would be similar with discrete transistors.
To guarantee that everything works fine, I recommend to first try the design with just one LED and check if it turns on by activating the corresponding PNP transistor and ULN channel. This way, we avoid detecting a wrong connection after everything is soldered. Also, for bigger matrixes, I recommend building it by rows and testing if the whole matrix works after each row is soldered.
Also, after finish wiring the matrix, test the inputs to control rows and columns with a voltage source and a multimeter first, instead of using a microcontroller right away. This way, you can guarantee that you are not exceeding the maximum output current of your device when controlling the LEDs.