IAN LANG ELECTRONICS

I'm aware that this section of the website is becoming something of a long advertisement for Oomlout.com and feel that I should point out that I don't work for them and I don't have shares in them either, despite what it's looking like. I can't emphasise enough though how good a company they are to trade with if you're doing anything with an Arduino or general prototyping and for that reason they have become my supplier of first resort.

So what have I been buying from them this time? It's a rather fantastic little LED matrix actually, which has eight leds across and eight down (8 columns and 8 rows, or 64 LEDs) in a square pattern just over an inch big and at such an economical price you could buy them by the bucketload. The link is on the left.

http://www.oomlout.co.uk/8-x-8-bicolour-led-matrix-p-233.html

8x8 LED Matrix

Go Back

That's the bunny on the right, looking slightly bigger than it does in the flesh,

so to speak, and underneath all those little dots you can see are not one

but two LEDs, one being red and the other being green. Which shines

depends on the way the cathode is connected.The cathodes are common

to the columns and thus each column of red LEDs and each of green

has a cathode to which all the LEDs in that column are attached.

In contrast the anodes of all the LEDs in a row are attached

commonly, regardless of whether they are red or green ones.

The red ones take less juice than the green do, and so for now

we'll just use the red ones to experiment with. Now, this kind of

display is much, much harder to work with than the LCD we've used

before, and takes some careful thinking about. What it can do is display

simple bitmaps, animations and scroll text. It's not easy but it is repeatable.

On the left is the schematic for the way the internal workings of the matrix are wired and I have to say it is actually quite eye-boggling. You will see that there are in fact 128 little LEDs built into this matrix (64 red and 64 green) and that the cathodes for red ones are pins 23, 20,17,14,2,5,8 and 11. The anodes for both red and green in their rows are 22,19,16,13,3,6,9 and 12.

 

Why they are laid out in this way I don't know, it makes for a difficult wiring-up and is in technical terms widely known as an "embuggerance". Moreover, it doesn't fit properly on a standard breadboard and so my solution was to bridge it over two breadboards using the edge holes. This is known as a "total embuggerance". The actual wiring up you'll need to do is shown in the schematic below:

So you'll find that you use all of the digital I/O pins, and 4 of the analogue ones as well. It's a tricky wire and your breadboard will look like Colonel Gadaffi's drawing room, and it's easy to misplace a wire. With pin 1 in the upper right hand corner, the rows go from left to right and the columns go up and down. Here's some code, modified from that supplied by Oomlout, that will test your wiring. What should happen is that the matrix will light red in the top left hand corner, and one by one all the LEDs in that column should light. Then it moves on and does the same in the next column. When all 64 LEDs are lit, it follows the same pattern in switching them off one by one.

 

int rowA[] = {9,8,7,6,5,4,3,2};  //pins that rows are attached to

int colA[] = {17,16,15,14,13,12,11,10};//pins that columns are attached to

byte data[] = {0,0,0,0,0,0,0,0};// empty array which we'll need later

const int powers[] = {1,2,4,8,16,32,64,128};//powers of two up to the eighth

void setup(){

for(int i = 0; i <8; i++){ ///all the following set the pins to output

pinMode(rowA[i], OUTPUT);

pinMode(colA[i], OUTPUT);

}}

void loop(){

 for(int i = 0; i < 8; i++){

for(int ii = 0; ii< 8; ii++){

data[i] = data[i]+ powers[ii];   //Goes through each row of lights lighting each column one after another

showSprite();}}

for(int i = 0; i < 8; i++){

for(int ii = 0; ii< 8; ii++){

data[i] = data[i] - powers[ii];   //Goes through each row of lights turning off each column one after another

showSprite();}}

}

void showSprite(){

 for(int iii = 0; iii < 20; iii++){                 //show the current frame speed20 times

for(int column = 0; column < 8; column++){            //iterate through each column

 for(int i = 0; i < 8; i++){                          

 digitalWrite(rowA[i], LOW);}                   //turn off all row pins  

 for(int i = 0; i < 8; i++){ //Set only the one pin

 if(i == column){     digitalWrite(colA[i], LOW);}  //turns the current row on

 else{                digitalWrite(colA[i], HIGH); }//turns the rest of the rows off

 }

 

 for(int row = 0; row < 8; row++){                    //iterate through each pixel in the current column

int bit = (data[column] >> row) & 1;        // now you know why I banged on about bitwise in chapter 11

if(bit == 1){

 digitalWrite(rowA[row], HIGH);                   //if the bit in the data array is set turn the LED on

}

 

 }

 delay(1);                       //leave the column on for pauseDelay microseconds (too high a delay causes flicker)

}

 }

}

 

Before I messed about with it this was an extraordinarily complex bit of programming and it still in some ways is. Two things I hate is passing variables between functions and declaring inside the argument parameter, because it gets too confusing for anybody who's got to fathom out the code later, so I stripped those out immediately. Global variables use more space but are better for humans. There's a 328 on board and so no need. Let's have a canter through the code.

 

int rowA[] = {9,8,7,6,5,4,3,2};  //pins that rows are attached to

int colA[] = {17,16,15,14,13,12,11,10};//pins that columns are attached to

 

Well, the first two lines are arrays and are self explanatory, and they are followed by:

 

byte data[] = {0,0,0,0,0,0,0,0};// empty array which we'll need later

 

When we get to the loop,we're going to fill this up with the values of the following array:

 

const int powers[] = {1,2,4,8,16,32,64,128};//powers of two up to the eighth

 

These will be stored as binary numbers, in fact as sixteen bits. You'll remember me banging on about that in chapter 11. Now you're going to see why it's important. Next we come to the setup:

 

void setup(){

for(int i = 0; i <8; i++){ ///all the following set the pins to output

pinMode(rowA[i], OUTPUT);

pinMode(colA[i], OUTPUT);

}}

 

All we do in the setup is turn the pins we are using to control the matrix into output ones. Now, look at the contents of the array colA:

 

int colA[] = {17,16,15,14,13,12,11,10};

 

Pins 14,15,16,17 are another way of saying A0,A1,A2,A3. All we've done is set them to low impedance, which makes them useless as input pins but means we can use them as digital outputs.

On to the loop, then and the first thing we do is set up a nested loop:

 

void loop(){

 for(int i = 0; i < 8; i++){

for(int ii = 0; ii< 8; ii++){

 

in the interior loop, we do this:

data[i] = data[i]+ powers[ii];   //Goes through each row of lights lighting each column one after another

showSprite();}

 

So: we take the i th position of the formerly empty array data we set up as a global variable and give it the value of itself and the ii th power of two as defined by the array powers. Then we call the function showSprite. That function looks like this:

 

void showSprite(){

 for(int iii = 0; iii < 20; iii++){                 //show the current frame speed2 times

for(int column = 0; column < 8; column++){            //iterate through each column

 for(int i = 0; i < 8; i++){                          

 digitalWrite(rowA[i], LOW);}                   //turn off all row pins  

 for(int i = 0; i < 8; i++){ //Set only the one pin

 if(i == column){     digitalWrite(colA[i], LOW);}  //turns the current row on

 else{                digitalWrite(colA[i], HIGH); }//turns the rest of the rows off

 }

 

 for(int row = 0; row < 8; row++){                    //iterate through each pixel in the current column

int bit = (data[column] >> row) & 1;        // now you know why I banged on about bitwise in chapter 11

if(bit == 1){

 digitalWrite(rowA[row], HIGH);                   //if the bit in the data array is set turn the LED on

}

 

 }

 delay(1);                       //leave the column on for pauseDelay microseconds (too high a delay causes flicker)

}

 }

}

 

It looks quite scary and believe me it's the very devil itself to work out when you've got precious little documentation to tell you what it's doing. Fortunately, over the page, there's now tons of it.

 

 

 

More >