A single LED can be handy in testing Arduino projects. But when you add an LED matrix, you can get really creative, spelling out letters, numbers, and symbols. It’s also a handy way to learn how more complex displays – like the one you’re reading this on – work. In this guide, we’ll show you how to set up a basic 8×8 LED matrix.
A basic LED matrix like the one we’ll use features an 8×8 grid of LEDs that can be used to draw characters, basic images and more. In previous guides, we’ve shown how the Arduino can control a single LED. This component stretches that concept across an array of 64 LEDs that can all be controlled with a single Arduino.
In an LED matrix, a current is run through rows of LEDs. In order to complete the circuit and activate an individual light, a column is connected to ground. Where the power and ground lines intersect, LEDs are activated. You can think of it a bit like the board game Battleship. For example, if power is run to rows A, B, and C, but only column 1 is connected to ground, then lights at A1, B1, and C1 will light up. The rest will stay dark.
This is a handy way to turn on multiple LEDs at once, but it creates a problem if you only want certain LEDs in a column to turn on. Say, instead, you wanted lights A1, B2, and C3 to light up creating a diagonal line. Activating all three rows and columns would turn on the entire grid, which isn’t what we want.
To solve this problem, an Arduino can run through a loop, activating only a single row of LEDs at a time. This way, you can activate as many columns as you want without affecting the next row. Without a lengthy delay() function, the rows will be activated in such quick succession that the human eye won’t be able to tell. But we will show how to add a delay so you can see how it works anyway.
We’re using a more complicated method to control the LED matrix for educational purposes – other components can reduce the number of pins required – and so this will take quite a few more pins and wires than most of our other guides. For that reason, we’ll be using an Arduino Mega 2560, instead of the usual Arduino Uno, to control this matrix. You’ll also need the following:
Arduino Mega 2560 | ![]() |
8×8 LED Matrix | ![]() |
8 x 220ohm resistor
Most LEDs will burn out if you connect them directly to the 5V output of an Arduino. Place a resistor from your kit between the output pin and the LED. |
![]() |
A pair of breadboards | ![]() |
Arduino IDE | ![]() |
You’ll also need a USB cable and quite a few wires – at least 32!
There are a number of ways to organize the wiring for this project, but since it can get complex, we recommend using a pair of breadboards latched together, one to handle the LED matrix, and another for wiring in the resistors. It’s possible to accomplish the same thing by using wires with female ends running to the LED matrix, though it will be sitting off to the side instead of stationary, which can be a little more cumbersome.
The code for this project will make use of loops and arrays to write each LED individually. The result will be an array at the top of your script that you can modify easily to change the image that your LED matrix displays. First, paste the full code into the Arduino IDE and upload it to your Arduino Mega.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
int toDisplay[][8] = { {1,0,0,0,0,0,0,0}, {1,0,0,0,0,0,0,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,0,0}, {1,1,1,1,0,0,1,0}, {1,0,0,1,0,0,1,0}, {1,0,0,1,0,0,1,0}, {1,0,0,1,0,0,1,0} }; void setup() { for (int i=2; i<=9; i++) { pinMode(i, OUTPUT); pinMode(i+44, OUTPUT); digitalWrite(i, LOW); digitalWrite(i+44, HIGH); } pinMode(A0, INPUT); } void loop() { for (int i=0; i<8; i++) { if (i==0) { digitalWrite(9, LOW); } else { digitalWrite(i+1, LOW); } for (int j=0; j<8; j++) { if (toDisplay[i][j] == 1) { digitalWrite(j+46, LOW); } else { digitalWrite(j+46, HIGH); } } digitalWrite(i+2, HIGH); delay(1); } } |
Next, let’s walk through how each of these sections work.
1 2 3 4 5 6 7 8 9 10 |
int toDisplay[][8] = { {1,0,0,0,0,0,0,0}, {1,0,0,0,0,0,0,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,0,0}, {1,1,1,1,0,0,1,0}, {1,0,0,1,0,0,1,0}, {1,0,0,1,0,0,1,0}, {1,0,0,1,0,0,1,0} }; |
Before either of the main loops in the sketch, this multi-dimensional array will define which LEDs should be lit up and which should stay dark. There are eight rows of eight values each, which correspond with the eight rows of LEDs on the matrix. By laying them out in a grid in the sketch, it makes it easier to visualize what shape the LEDs will make up.
1 2 3 4 5 6 7 8 9 |
void setup() { for (int i=2; i<=9; i++) { pinMode(i, OUTPUT); pinMode(i+44, OUTPUT); digitalWrite(i, LOW); digitalWrite(i+44, HIGH); } pinMode(A0, INPUT); } |
In the setup() section, we’ll initialize the pins we need for the matrix. Since there are sixteen different pins, we can do this more efficiently than one at a time. The pins running to ground will be plugged into pins 2 through 9. The pins sending power to the matrix will run to pins 46 through 53. This section will use a loop to initialize both sets of pins.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
void loop() { for (int i=0; i<8; i++) { if (i==0) { digitalWrite(9, LOW); } else { digitalWrite(i+1, LOW); } for (int j=0; j<8; j++) { if (toDisplay[i][j] == 1) { digitalWrite(j+46, LOW); } else { digitalWrite(j+46, HIGH); } } digitalWrite(i+2, HIGH); delay(1); } } |
In the main loop() section of the sketch, there’s one multi-step loop. The first if statement will reset the last used row to LOW, which will stop power from flowing to it.
The next nested for loop will check data in the array. If a cell is listed as 1, it will set the ground wire for that column to LOW, allowing current to flow out. Otherwise it will set the pin to HIGH which will prevent a circuit from being completed along that column. It will do this for all eight cells in a given row.
Finally, the last digitalWrite() statement will turn the entire row on. Any columns set to LOW will light up. The rest will stay dark. When the sketch loops again, it will immediately start by turning off that row.
The last command is a delay() statement which sets the delay between each row. It’s set to 1 millisecond in our example because when the statement isn’t there, the LEDs get a bit too dim. However, you can increase the delay to see what the sketch is doing more slowly. You should see each row light up one at a time, before turning off as the next row turns on.
For this project, the wiring is relatively straightforward, there’s just a lot of it. Since there are many pins, we’ll describe what you want to do for each complete circuit, rather than list every individual wire as we usually do.
Pins 2 through 9 should be your power pins, and pins 46 through 53 should be your ground pins. Run a wire from the power pin, to the LED matrix (check for more details on which pins below – this is important), from the LED matrix into a 220 ohm resistor, and then run a wire back to a pin on the Arduino. Pin 2 should eventually lead to pin 46, pin 3 should lead to pin 47 and so on.
The main complication here is with the LED matrix itself. Counterintuitively, the pins on either side of the matrix aren’t in a coherent order at all. For example, we want pin 2 to power what we’ll call Row A. Yet the pin for this is the fourth pin from the left on the top of the LED matrix. The other end of this circuit – which should lead to Column 1 – is the first pin on the right on the bottom of the matrix.
Since this ordering is rather complicated, we’ll spell out which pins on the matrix each Arduino pin should be wired to directly.
Along the top of the matrix (the side with the number printed on it) there are eight pins. From left to right, these should be wired to the following pins on the Arduino:
Next, the bottom row of eight pins on the matrix (the side without numbers) should be wired to the following pins (from left to right, with the numbers still facing upwards):
Once all the wires are connected, you can turn on your project and you’ll see your LED matrix light up. Try changing the arrangement of 1s in the initial array and re-upload the script to create different shapes. You can also adjust the length of the delay() command to see each row light up one at a time.