I've had these LED matrix modules laying around for many years and for some
reason never got around to using them. They are very old. If memory serves,
they are some of the original prototypes invented by Alexander Graham Bell
in 1492. Today I finally got around to playing with them. I hooked up a single
module to an AtMega32 and made it scroll text and do simple graphical things.
Here's a video of it in action:
Each module contains 64 LEDs arranged in an 8x8 array. However, there are only
16 pins on the back of each module, meaning that the LEDs are not individually
controllable. The cathodes of all the LEDs in each row are connected together
and brought out to one pin. Similarly, all the anodes of each column are brought
out to one pin. 8 rows equals 8 cathode pins, and 8 columns equals 8 anode pins.
To light any single LED, we provide power to the anode pin for the LED's entire
column, and we also provide a path to ground through the cathode pin for the
LED's entire row (hopefully using a current-limiting resistor somewhere in
there so we don't burn out the LED). This is illustrated in the image below.
The yellow line shows the column we've activated via the anode pin, and the
blue line shows the row we've activated via the cathode pin. Wherever a yellow
and blue line intersect, an LED will light.
But suppose we wanted to light two LEDs in the following pattern:
Can you figure out which pins to activate in order to light them up without
lighting up any other LEDs? Don't spend too much time on this. It can't be done.
Here's why:
To get both LEDs lit, both column pins and both row pins must be active.
The problem is that this creates a 2x2 matrix of active cells, meaning that
all 4 LEDs in that little matrix will be lit, as illustrated by this image:
This is the price we pay for having only 16 pins to control 64 LEDs.
In order to light up every LED desired, it's very likely that other unwanted
LEDs will light up as well. To keep those unwanted LEDs from being lit we have
to cycle through the array lighting only a few LEDs at a time (a single row for
instance, or a single column). If we cycle through the whole array quickly
enough, the eye can't tell that only a few LEDs are lit at once so it looks
like all the desired LEDs are on constantly.
On the down side, we lose some brightness because no LED can be lit 100% of the
time. In fact, if we activate only 1 column of LEDs at a time, each LED is
illuminated at most 1/8th of the time.
After we've let our one little column glow for a while, we'll switch to the
next column and give it a chance. Then we'll move on to the next, until all
columns have had a chance to glow. Then we'll start over at the first column
again. If this process happens quickly enough (say, several hundred times a
second), then the display is flicker-free. It just doesn't look quite as
bright as it might otherwise.
However, since our duty cycle for each LED is only 1/8th of what it would be
normally, we can lower the value of our current-limiting resistors a bit.
This will allow more current to flow through the LED, making it brighter, but
it will be on for such a short time that there will be no damaging
heat build-up from the higher current. Of course if we over do it we may
shorten the life of the LEDs this way.
Now since we are driving only one column at a time, we know that no more than
8 LEDs can be lit at one time. This means we only need 8 current-limiting
resistors for all 64 LEDs. We put one resistor on each row pin as illustrated below:
If we had chosen to drive one row at a time rather than one column, we'd simply
have put the resistors on the column pins to get the same effect.
You may have noticed in my images that some LEDs appear much brighter than the
others. Specifically, the more lit LEDs a column has, the dimmer the LEDs in
that column get. It's particularly noticeable in the following image in which
all the columns have two LEDs lit except the 5th, which has 7 and is
consequently much dimmer.
This happens because I'm driving the LEDs directly from an MCU's I/O pins.
There is a limit to how much current each I/O pin can supply, and when
several LEDs are lit, they need more current than the pin can supply. They
have to share what little current is available, and so they are all dimmer.
This problem can be eliminated by driving each column with a transistor or an
LED driver chip rather than directly with an MCU pin.
That covers how to put a static image on the display. But how do we make it
scroll? Well, we just change the static image periodically, where "periodically"
means "much less often than our column-by-column refresh loop". For instance,
our refresh loop may iterate 400 times a second (a very flexible number), while
our image-changing loop may iterate only a few times a second; maybe just 5-10
times per second for scrolling text or 30 times per second for video-like
animation.