Nobody should stop making 8x8 LED matricies. Ever.

Well, it’s about time i finished this project. Finally, have an 8x8 LED matrix to play around with and I become a fully-fledged member of the arduino community. Here are the details:

  • It’s monocolor red
  • controlled by two 74HC595 shift registers.
  • It’s run off three pins from the arduino controlling the two shift registers.
  • The code work is modified from the ASK manual by earthshine design.

Video and pictures (below the joule thief picture) Random Things I Tinker: What I've been doing

Everything is running fine; the only thing left is to refine the code for it to make changing the display pattern easier. If anyone wants me to list the code just ask for it and I will.

Improvements for next time: hook the anodes up to either a transistor or a P-FET, and ground to a darlington array. And make it bigger. Oh and use diffused LEDs (I had clear ones so I decided to use wax paper over the array to diffuse the light a little and make the image clearer).



Pretty awesome. I love how clean it is! I have been dabbling with the Arduino for a bit now, but have actually never done a matrix. I would really like to.

Can you give some references you used in creating this? Source code? I have a lot of 74HC595 shift registers sitting around.

Keep it up! Thanks..

Thanks! Oh hey i just read and replied to your post in the FAQ place before I read this. Yeah I can post code, probably late tomorrow because I want to annotate it before I put it out (It's basically the same as the ASK manual, except for the scrolling part) I would recommend using a premade matrix as making your own is pretty messy, but it's a good experience to see what actually makes it work. I actually made mine just because I had them laying around collecting dust. Either way, I'll post code soon (tomorrow, maybe tomorrow night).

Ok, here’s code:

#include <TimerOne.h>    //Download the TimerOne library if you haven't already
int StoreClock = 13;     //Pin connected to Pin 12 of 74HC595 (Latch)
int ShiftClock = 12;    //Pin connected to Pin 11 of 74HC595 (Clock)
int dataPin = 11;       //Pin connected to Pin 14 of 74HC595 (Data)
int displaySize = 74;   //How many bytes are in the StoreDisplay array
uint8_t StoreDisplay[74];  //Stored bytes to be output
uint8_t ActiveDisplay[8];  //Bytes that represent what is actually being displayed
long counter1 = 0;   //Counter which is used to change the display
int active = 4; //This will change every so often in order to move the display

void setup() {
  pinMode(StoreClock, OUTPUT);   //set pins to output
  pinMode(ShiftClock, OUTPUT);
  pinMode(dataPin, OUTPUT);
  StoreDisplay[0] = B00000000;  //What's going to be output in bytes
  StoreDisplay[1] = B00000000;
  StoreDisplay[2] = B00000000;
  StoreDisplay[3] = B00000000;
  StoreDisplay[4] = B00000000;
  StoreDisplay[5] = B00000000;
  StoreDisplay[6] = B00000000;
  StoreDisplay[7] = B00000000;
  StoreDisplay[8] = B11111111;
  StoreDisplay[9] = B10000001;
  StoreDisplay[10] = B10000001;
  StoreDisplay[11] = B01000010;
  StoreDisplay[12] = B00111100;
  StoreDisplay[13] = B00000000;
  StoreDisplay[14] = B00000000;
  StoreDisplay[15] = B11111000;
  StoreDisplay[16] = B00010111;
  StoreDisplay[17] = B00010001;
  StoreDisplay[18] = B00010111;
  StoreDisplay[19] = B11111000;
  StoreDisplay[20] = B00000000;
  StoreDisplay[21] = B00000000;
  StoreDisplay[22] = B11111111;
  StoreDisplay[23] = B00001001;
  StoreDisplay[24] = B00001001;
  StoreDisplay[25] = B00001001;
  StoreDisplay[26] = B00000001;
  StoreDisplay[27] = B00000000;
  StoreDisplay[28] = B00000000;
  StoreDisplay[29] = B00000001;
  StoreDisplay[30] = B00000001;
  StoreDisplay[31] = B11111111;
  StoreDisplay[32] = B00000001;
  StoreDisplay[33] = B00000001;
  StoreDisplay[34] = B00000000;
  StoreDisplay[35] = B00000000;
  StoreDisplay[36] = B00000000;
  StoreDisplay[37] = B00000000;
  StoreDisplay[38] = B00000000;
  StoreDisplay[39] = B11111111;
  StoreDisplay[40] = B00010001;
  StoreDisplay[41] = B00010001;
  StoreDisplay[42] = B00010001;
  StoreDisplay[43] = B00001110;
  StoreDisplay[44] = B00000000;
  StoreDisplay[45] = B00000000;
  StoreDisplay[46] = B01111111;
  StoreDisplay[47] = B10000000;
  StoreDisplay[48] = B10000000;
  StoreDisplay[49] = B10000000;
  StoreDisplay[50] = B01111111;
  StoreDisplay[51] = B00000000;
  StoreDisplay[52] = B00000000;
  StoreDisplay[53] = B11111111;
  StoreDisplay[54] = B00000110;
  StoreDisplay[55] = B00011000;
  StoreDisplay[56] = B01100000;
  StoreDisplay[57] = B11111111;
  StoreDisplay[58] = B00000000;
  StoreDisplay[59] = B00000000;
  StoreDisplay[60] = B11111111;
  StoreDisplay[61] = B00011000;
  StoreDisplay[62] = B00100100;
  StoreDisplay[63] = B01000010;
  StoreDisplay[64] = B10000001;
  StoreDisplay[65] = B00000000;
  StoreDisplay[66] = B00000000;
  StoreDisplay[67] = B00000000;
  StoreDisplay[68] = B00000000;
  StoreDisplay[69] = B00000000;
  StoreDisplay[70] = B00000000;
  StoreDisplay[71] = B00000000;
  StoreDisplay[72] = B00000000;
  StoreDisplay[73] = B00000000;
  StoreDisplay[74] = B00000000;
  Timer1.initialize(10000);              //Start a timer from TimerOne and fire it every 10000 cycles
  Timer1.attachInterrupt(screenUpdate);  //Update the screen every 10000 cycles

void loop() {
  if (counter1 >= 30000) {                        //When counter1 reaches this, change the display image
    counter1 = 0;                                 //Reset the counter first
    for (int i=0; i<8; i++) { 
      ActiveDisplay[i]= StoreDisplay[active+i];   //Change what is in the active display based on the variable "active"
    active++;                                     //Change active for the next time counter1 fires this for loop again
    if (active == displaySize-6){                 //Reset active when active increases to this point, making the animation loop again
      active = 0;

void screenUpdate() {
  uint8_t row = B00000001;
  for (byte k = 0; k < 9; k++) {
    digitalWrite(StoreClock, LOW);      // Open up the latch ready to receive data
    shiftIt(~row );
    shiftIt(ActiveDisplay[k] );         // StoreDisplay array
    digitalWrite(StoreClock, HIGH);     // Close the latch, sending the data in the registers out to thematrix
    row = row << 1;

void shiftIt(byte dataOut) {
  // Shift out 8 bits LSB first,
  // on rising edge of clock
  boolean pinState;
  //clear shift register read for sending data
  digitalWrite(dataPin, LOW);
  // for each bit in dataOut send out a bit
  for (int i=0; i<8; i++) {
    //set ShiftClock to LOW prior to sending bit
    digitalWrite(ShiftClock, LOW);
    // if the value of DataOut and (logical AND) a bitmask
    // are true, set pinState to 1 (HIGH)
    if ( dataOut & (1<<i) ) {
      pinState = HIGH;
    else {
      pinState = LOW;
    //sets dataPin to HIGH or LOW depending on pinState
    digitalWrite(dataPin, pinState);
    //send bit out on rising edge of clock
    digitalWrite(ShiftClock, HIGH);
    digitalWrite(dataPin, LOW);
  digitalWrite(ShiftClock, LOW);   //stop shifting

Greatly appreciated!

I've run into a bit of a problem though and was wondering if you may be able to help me. I have a 5x7 matrix handy, so I was trying to adapt this setup for this smaller matrix. Before even really dealing with the size of it, I've run into an issue with how the things is to be wired up.

Basically, my question is, did you use output 1-8 of one shift register for all the rows and 1-8 of the other for all the columns? I found the data sheet for the 5x7 that I have, and I put 1-7 of the first register to the associated rows (1-7) on the matrix, then did the same for the columns but with the 1-5 output on the second shift register. But, it doesn't seem to be doing anything. When I manually ground the column cathode pins, it lights up the entire column. I'm a bit stumped. I following the wiring diagram for shift registers from the site in the tutorial section about using shift registers. I've used this information before when using them to power a 7-segment LED with success, so I assumed using this resource to hook the two shift registers together would be appropriate.

Anyways, any info you may be able to provide would be greatly helpful. I may just get one of the MAX ICs, as they seem to simpler in operation.

I figured it out! I rewired the whole thing, and realized I had wired something to ground that wasn't supposed to be. So now I'm just trying to figure out how to adapt the code to properly work with my 5x7 matrix. I kind of rigged it to work right, but it's just showing a solid pattern of what I tell it to. Trying to work out how to make the patter change (like one dot moving through the matrix).

Yes I would recommend using one shift register to control the rows, another for the columns. As it is now, the code should still work, kinda, if you just limit your window from an 8x8 to a 5x7 for the characters. I think it should scroll still if you adjust code accordingly, but i haven't given it too much thought. If you run into a specific problem along the way let me know.

hi, could you tell me how to adapt your program to be used in a direct drive 8x8 matrix. thanks

To do that, you need to take a look here:

Basically, the only part of my project that you would use is the matrix, which you can build yourself or buy one. If you have any questions after you look at that link, let me know and I'll try to help