Moving Forward with Arduino – Chapter 18 – RGB LED Matrix
Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice.
This is part of a series originally titled “Getting Started with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.
Welcome back fellow arduidans!
In this instalment we will take a turn away from the serious things for a while, (plus I wanted a bit of a break) and instead enjoy some introductory fun with RGB LED matrices. (Matrices is the plural form of matrix). I am sure some of you have seen these do all sorts of things, so now it is time for me to learn about them and share this with you.
First of all, let’s have a look at one:
Quite large – 60 by 60 mm. Thankfully this unit has the diffused/opaque LED surfaces – some cheaper ones have clear surfaces which don’ t look that good – it is like looking directly at an incandescent light globe, you can see the element more than the colour it emits. When you turn the matrix over, there are less pins than a newcomer may expect:
Two rows of sixteen pins. Considering there is so much real-estate on the bottom, one would think the manufacturer could print some markings on there – but they don’t. So you need the (example) data sheet.pdf. The three most important things we need to know are:
- the forward voltages: red – 2 V, green and blue – 3.3;
- the current at the recommended forward voltage – 20 milliamps;
- and the pinouts (click to enlarge):
It looks like a mess but isn’t that hard to work out. Do you remember how we used the 8×8 red LED matrix back in chapter nine? We will work on the same style of design in this chapter as well. I do realise there are chips from TI, Maxim and so on that are quite tricky – but I am trying to keep the cost down, of which I am sure you would appreciate. So instead we will use four 74HC595 shift registers (one to control the anodes of each colour, and one to control the cathodes via a bank of switching transistors.
To get this started, first let’s get the hardware out of the way. To fire this baby up we will need:
- an Arduino Uno or 100% compatible board;
- a common-cathode RGB LED matrix;
- 24 x 560 ohm resistors (this value may seem like a bit much – but the display was still very bright)
- 8 x 1 kilo ohm resistors (for transistors)
- 8 x BC548 transistors
- 4 x 74HC595 shift registers (IC1~4)
- 1 x 1uF 16V (or higher) electrolytic capacitor
- 1 x 0.1 uF 16V (or higher) ceramic capacitor
- a nice large breadboard
- plenty of connecting wire
Initially I was concerned about the amount of current this circuit would draw, however it was not to be an issue. With all the LEDs on, using the 560 ohm current-limiting resistors, the drain was much less than expected. To check, I powered the lot from a 9V PP3 battery and measured the current flow. 135 milliamps, not bad at all.
It just occurred to me that if you had an Arduino Mega – it could directly take care of everything instead of using three of the shift registers. Hmmm.
So here is our schematic:
In the schematic above, there are eight transistor-resistor combinations between the cathodes of the matrix (pins 25, 24, 23, 10, 9, 8, 7 and IC4. And there are 560 ohm resistors on all output pins of ICs 1~3. Furthermore, note that your LED matrix’s pinouts may vary – so please check your data sheet before wiring it all up… having to retrace all those wires once they’re in is a real problem. As you can see from the resulting breadboard photo:
Now how does all this work?
Quite easily really, the hardest part is putting the hardware together. First of all, please review how we used shift registers in chapter four. And, you may recall how we used two 74HC595 shift registers to control an 8×8 red LED matrix back in chapter nine. This is just the same type of set up, but with two more shift registers – now we have one for the cathodes (as we did before), and one shift register each for the red, green and blue LEDs.
Instead of sending out two bytes of data using shiftOut();, we need to send out four bytes. For example, to turn on every LED at once (thereby mixing red, green and blue – producing white) we would create a function such as:
So as you can see, the first byte out the door is the data for the cathodes, in this case 255 – which is 11111111 in binary, or in 74HC595-speak “hey, turn on all outputs”. And the same again in turn for each bank of colours, the other three registers are told to open all gates and let current flow through the LEDs to the common-cathode lines controlled by IC4. So naturally, using some binary to base-10 conversion you can set which LEDs to come on and where. And of course, by mixing the primary colours – you can create new ones. For example, the additive colour chart gives us:
So now you can create yellow with red and green; red and blue makes purple; green and blue makes aqua or teal, etc. However I am colour blind, so you tell me.
Example 18.1
This time we will view the demonstration video first:
Download the matching sketch.
Now to examine how each of the effects were created, so you can understand, use and modify them yourself.
The basic operations are contained in these four lines:
So all you need to do is replace r, b, g and c with the base-10 values you want. For example, to light up the red LED in position 1, 1 – use 1, 0, 0, 1. Or if you want the whole first line to be green, use: 255, 0, 0, 1. After a few moments you should become proficient at converting binary to base-10. This chart from chapter four should help you:

Remember that you can also create patterns and so on. For example, if you only wanted LEDs 1 and 8 for your x-axis, you would add 1 and 128 together, and use the sum (129) for your x-value. To save some time, I have created a few functions for you to use. For example:
void displayLEDs(int rr, int gg, int bb, int cc, int dd)
{
digitalWrite(latchpin, LOW);
shiftOut(datapin, clockpin, MSBFIRST, cc); // cathodes
shiftOut(datapin, clockpin, MSBFIRST, gg); // green
shiftOut(datapin, clockpin, MSBFIRST, bb); // blue
shiftOut(datapin, clockpin, MSBFIRST, rr); // red
digitalWrite(latchpin, HIGH);
delay(dd);
}
So instead of having to manually repeat a lot of code, you can just insert the values into displayLEDs();. Another handy thing to know about is looping. When looking at the matrix it is easy to accidentally think “Oh, I can just loop from 1 to 8″… No. Remember your binary to base-10 conversions. So if you wanted to scroll a horizontal line of red LEDs your cathode or y-axis value must increment as such: 1, 2, 4, 8, 16, 32, 64, 128. Every time the loop cycles, it needs to double the value. To do this, consider:
for (int q=1; q<129; q*=2)
{
displayLEDs(255,0,0,55,100);
}
Notice the q*=2? This will multiply the value of q by 2 every loop. Very useful. Another method would be to create an array, as such:
int va[]={1,2,4,8,16,32,64,128,255};
and refer to the elements as required. This is done within the function lostinspace(); within example 18.1.
The next thing to take into account is the screen refresh. Every time you send four bytes of data through the shift registers, those new bytes will ‘shift’ the old bytes out of the way. So if you want to alter the display even by just one LED, you need to redraw the entire display over again with four new bytes of data. Also note that to ‘hold’ an image on the display, you only need to send the data once – the shift registers will stay put until the next four bytes of data come along.
And sometimes, you might just want to turn off the display. Just send four zeros down to the registers, as the function clearMatrix(); does in the example sketch.
For now, please review the various functions found in example 18.1 – alter them, mess about and have some fun. Thus concludes our introduction to RGB LED matrices. However, stay tuned for more about this and other interesting things! If you have any requests, don’t hesitate to ask.
Have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.











Hi,
I was wondering if there’s a way to have the individual LED’s in the matrix change brightness to get more colors out of the matrix? I assume the best answer would be PWM but im not exactly sure how to implement that. Thanks.
-R
Hi Rod.
Yes it can be done, a quick poke around came up with this baby: http://focus.ti.com/docs/prod/folders/print/tlc59116.html.
Will get one next month and see how it runs. Sorry I couldn’t be of more help.
cheers
john
I’m having trouble understanding how you’re only seeing 135mA when running all LEDs.. That’s 192 LEDs for 135mA? 700 microamps per LED? I’m genuinely curious how this is, as I’m planning a project incorporating one of these units and am trying to get some numbers together.. Please let me know if I’m merely missing something that should be obvious. I do that now and again.
Thanks!
Hi
Yes, I couldn’t believe it either, but it was so. I’m pretty confident the meter is ok, it was only two months old at the time.
Though as with anything, give it a whirl yourself.
cheers
john
I’m trying to simplify this a little bit to make an arduino shield, and I had few quick questions.
Are the 8 transistors just used for NOT gates, or do they provide some extra power also?
Would it be possible to simply have the not gate in the code (bring the pin LOW when I tell it to turn “ON”)?
Is it possible to light up just two pins that aren’t in the same row or column or would that just light up four corners? I think it would, so how did you get around this? The way I’d do it is to flash them one row at a time.
Thanks, this was a very interesting read about the chips.
Hi Adam
The transistors are used as switches to control the cathodes for each row of on the matrix. I couldn’t use an IC as a current sink as there is the possibility of too much current.
Yes, you can light up two independent LEDs on the board at once. Just send the appropriate binary values out to the shift registers to turn on the LEDs you want on and the matching cathode row.
If you find this sort of thing interesting, more can be learned from the technical documents for the “Meggy Jr” kit from here http://www.evilmadscientist.com/article.php/meggyjrlib
Have fun
john
any chance you might be able to provide me with a schematic on how to make a 16×16 rgb display? i have 4 of the 8×8 rgb matrices and have NO idea on how to wire the 16×16. i’m pretty sure i can manipulate the programming but i need to wire the display somehow. would i also need more 8bit shift registers?
Just think in terms of having a 16 x 16 display. So, you will have six shift registers controlling the anodes (one each for RGB for first eight, then one each for RGB of second eight) and two shift registers controlling the 16 cathode lines. Then in software you need to ‘shift out’ 48 bits of data to control the anodes, and 16 bits of data to control the cathodes.
could you possibly show me a diagram on how to wire the 4 8×8′s to make a 16×16?
Sorry, busy. Please consider the schematic here – http://tronixstuff.files.wordpress.com/2010/09/schematicss2.jpg. You have four shift registers, one each for red, green, blue and the cathodes via the transistors. To add another matrix, you just add another four shift registers, another matrix, another 8 transistors, etc. And repeat for however many LED matrices you want to run. If you have the parts, I recommend you make one matrix work – then you will have a better understanding of how to run four or more. Don’t forget to allow for the increased current draw by using a separate power supply to that from your Arduino.
john
Hi! I do not totaly understand why do i need the transistor? Now i use only 3 shift registers (1 for cathodes and 2 for green and blue anodes) to experiment a little with two color out of the 3 and i have a problem: when i turn on more green leds the blue leds are getting less bright, and if i turn on all the greens, the blue ones are apparently off, only the green leds light. (and if i turn on only the blue leds, they are less bright than the green leds, when the greens are on only)
So i think the transistor could help me but how?
Hello
The transistors are used to turn on and off the higher current that can come from a line of LEDs. That is, if you have all of the top line of LEDs on, that’s around 160mA of current – which needs to be a switched on and off via a shift register controlling the transistor, as the transistor can deal with the higher current. You will need the transistors as described in my schematic.
cheers
john
Thx!
I noticed you have your 1uF electrolytic cap coming off of pin 12 on the last 595 chip (cathode chip)…does the placement of this cap matter? I have mine placed on my board before the latch pin touches the first 595 chip. Thanks for the great project!
It depends on the physical circuit layout, it’s just there to reduce noise on fast-changing latch line. If your circuit works then you’re fine.
Sorry to be a bit vague but it was a while ago.
cheers
john
Just wondering with the dim rows/bright columns problem what a possible solution might be in order to get the lights all the same brightness regardless of their pattern…
Cheers (for a great set of tutorials)
-Phil
Hello
You could use TI TLC5940 constant-current IC drivers with a common-anode LED matrix. It would be more expensive but solve the problem. I have demonstrated these ICs here – http://wp.me/pQmjR-Ey
have fun
john
Possible to build the RGB matrix with led alone?
Sure, the RGB matrix is just 8 rows of red, green and blue LEDs in a housing. See the matrix schematic in the article.
john
Hello i just picked up a rgb matrix like yours (http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=190502734111&ssPageName=ADME:X:AAQ:US:1123) looks at the data sheet on the sale page i cant determine if its common-cathode like yours. if its not the same what would i need to modify in your guide?
Hello
You have a common anode display. A bit of a pain but you can work with it. Use a 74HC595 to control the anodes, and two TLC5940s to control the R, G and B lines. See http://wp.me/pQmjR-Ey to read about TLC5940.
cheers
john
Hello, I don’t really get why a col of 8 is dimmer than a row of 8. Can you explain that problem more in detail or can you post any source where I can read about that?
If the transistors can deliver enough power (say 1000mA), why is there a difference if I drain 100mA or 800mA from it? Please point me at where I’m wrong
thanks
Hello.
Problem is when you run several LEDs in series, the current reduces due to the voltage drop across each LED – thereby reducing the overall brightness of the column.
First got to say excellent site and tutorials me and my son have learnt so much so thank you.
now here is the question we are going to make a 8×8 matrix using Superflux RGB which are 20ma per led colour where i am thinking we will have trouble is that the bc548 transistors are rated to 100ma so if 8 lights are on that will be 160ma and if i light all 3 colours to make white it will be triple that about 480ma so would we need a higher rated transistor or being the noob at this that i am have i got the calculations all wrong
also how many 8×8 matrices using this method could we run from a mega2560.
many thanks in advance
Mick
PS i colored in the matrix schematic if you want a copy it can be fount here i found it a bit easier to understand.
http://binaryg.co.uk/8x8_rgb_schematic_color.jpg
Hi Mick
If you use an I/O expander such as the MCP23017 (see the recent article http://tronixstuff.wordpress.com/2011/08/26/tutorial-maximising-your-arduinos-io-ports/) you could run 8 matrices. You could run a lot more using 74HC595 shift registers, but you would have to update every single LED every time a change was required, whereas with the MC23017 you only need to change on matrix not all of them. As shown in the article a whole matrix set to white uses 135mA with 560R resistors on the LEDs.
Thanks and great work on the colour diagram
cheers
john
Looks like i got it all muddled its the shift registers that i need to beef up i have been looking around and think this TPIC6595 might do the job i will give it ago and see what happens.
close call on the light and blue smoke display as all the ic`s went up in flames
as i posted you replied to my last post thanks by the way. i am using a home built matrix using superflux rgb leds not the smae pre built one your are using here are the specs
FORWARD VOLTAGE 3.5—5 volts
FORWARD CURRENT 20m/a
You may want to check out ULN2803A darlington transistors – http://focus.ti.com/lit/ds/symlink/uln2803a.pdf
They can switch much more current and even be used in parallel for more current handling.
have fun
john
I`m Really glad you mentioned the ULN2803 because i have ordered 5 of them the other week so as soon as they are delivered i will start playing. also got some io expanders/multiplexers and a few ENC28J60 chips to play with so i`m sure i will be back bugging you for advice sometime soon thanks for all your help and keep up the good work i dont think i would have made so much progress in the arduino digital world without your site.
Mick
Hi, I want to give a similar project a go, but I want to make my own array using 4 pin common anode LED’s, but will it be possible to have more than one colour in a given column or row (on separate LED’s obviously) for example :
BGR
GRB
RBG
would this be possible at all or would all 9 LED’s be on full (R-100%, B-100% and G-100%).
am I misunderstanding the LED matrix set-up or something in the circuit.
Thanks
For that kind of setup you need to investigate ‘charlieplexing’ – a way to control many LEDs with not that many wires. if you are up to it, examine how the “lolshield” works – http://jimmieprodgers.com/kits/lolshield/
cheers
john
I am out of my league here, but determined to get this to work. Is it possible to use this same type of setup to drive a 4×4 grid of RGB LED strips? The strips have 18 RGB Leds with current limiting resistors. I just tried with a 2×2 grid and one 595 with the 16 and 10 pins hooked up to 12V. I used 2 NTE253 transistors. Well I smoked the 595. Was my mistake (the one that killed the chip) hooking it up to 12 V, or was it trying to use one chip to control 2 anodes, and 2 cathodes of each color?
Thanks!
74HC595s only like up to about 6~7 volts. You should read the data sheet http://www.nxp.com/documents/data_sheet/74HC_HCT595.pdf
Can you reply with a link to the RGB LED strips?
I’ve actually realized a big mistake. Common anode vs. common cathode set-up. So I have now set things up using the TLC 5940s and the NTE253s. I got things working last night on a test run using one color each on two different strips. I only needed 2 of the outputs for this and things seems to work, but I cannot get the leds to shut completely off at all while the program is running. I am wondering if I need to use mosfets instead of the npns?
What value resistors are you using on the base of the NTE253s? If you aren’t using any, put a 1k between the output pin of the TLC5940 and the base.
Here is the LED Strip I am using http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&item=140593523381&ssPageName=ADME:L:OU:US:1123
I have cut the strip into sections using 18 leds of each color per section.
Thank you. You have no idea how much this helps. Even though I don’t understand how you light up a single LED in a row, I will once I have the parts in front of me.
Glad you enjoy it
cheers
john
sir, good day! I would like to make a similar project like this but im planning to make a 20×6 RGB matrix. i just would like to clarify if this is correct.. (3 pcs. of 74hc959 for 20 pins of red led), (3 pcs. of 74hc959 for 20 pins of green led), (3 pcs. of 74hc959 for 20 pins of blue led) and (1 pc of 74hc959 for 6 pins of common cathode).
Sure, sounds fine.
by the way, why do i need to use a shift register for the common cathode?
We do this to simplify addressing the anodes and cathodes into one serial data shift out.
sir if i will be using rgb common anode, should i use the same components like what you did with the common cathode?
It’s a little different, see here http://francisshanahan.com/index.php/2009/how-to-build-a-8x8x3-led-matrix-with-pwm-using-an-arduino/
Hi !!
First of all, i would like to thank you for these great tutorials.
I have a problem. I built the same way like you did in order to display messages.
I managed to do this. However, during the message’s display, there’s some unwanted flickering
but i don’t know why. I think, it may be due to the transistors but i used BC548 like you…
Do you have an idea of how to solve this problem?
Thanks
Sorry it is very hard to say. As always, check wiring connections are solid, and especially the power lines.
Thanks once again for another excellent tutorial.
Using the information from some of your other tutorials on shift registers and TLC 5940′s I then found it very easy to wire up an 8 by 8 RGB common anode,using one shift register for the anodes and sink the current through one of 2 daisy chained TLC’s.
I am using 2 arrays,one for the byte to the SR,and one for which pin to sink on the TLC,and am now enjoying developing patterns etc,
Thanks again for interesting and informative tutorials
Jayfdee
hello sir, is it possible to use sparkfun rgb matrix v5 library with your hardware,
because i have common cathode RGB matrix but Sparkfun library is on common anode.
and if yes then what changes are nedded.
A fair bit of work may need to be done. You would be better off asking on the Sparkfun support forum at http://forum.sparkfun.com/ or just get yourself a common-anode display and save time.