8×8 LED Matrix

This article describes a project using an AVR microcontroller to control an 8×8 LED Matrix. The matrix is programmed to display text, either by scrolling or by blinking one letter at the time.


The video shows the LED matrix working when it was a breadboard prototype.

The electronics

The schematics look like this:

As the LED-matrix has 0.1 inch pin distance, I used two 8-pin headers, A & B, instead of making a custom footprint. The wires starting with K are the cathodes and A are the anodes. They are connected to the microcontroller pins closest to them, making the board one-sided but also harder to program. The actual board was made using a CNC mill, which required extra thick wires. The result is shown in the following picture:

The board was meant to run on 3.3v with PWM on all LEDs, so no resistors were added for the matrix.

The TWI (i2c) lines SDA and SDL were routed to a header. This way I can create a stand-alone matrix-module outputting text received from other microcontrollers.

The software

The libraries mat88.h and mat88.c contains the functions for writing text to the LEDs. These functions can be used without worrying about their contents. mat88_int() must be called at initialization, and calling sei() enables interrupts. The following example displays scrolling text on the matrix:

scrollwrite() has three input parameters; one null terminated string, a 16bit uint with the scrolling speed and an uchar for the number of times to display. The refresh function must be called as often as possible, and uses an overflow interrupt to keep track of it’s own time.

The scrollwrite function can be replaced by mat88_blinkwrite(), using the same input parameters. The speed variable then decides how fast the letters will blink on the matrix.

Calling the mat88_draw(pattern), where pattern is an 8-byte unsigned char array, displays custom graphics on the matrix. An example of an input argument to mat88_draw() could be an up arrow, look closely to see the ones forming an arrow in the zeros:

There is also a mat88_putc() function, that displays a single letter on the matrix. The following sections describes how these functions work.

How it works

Light the LEDs by PWM
The matrix has of 8 anode pins and 8 cathode pins. Simply put, the anodes represent the rows and the cathodes represents the columns. So to light a LED at (3,5), Anode 3 would be set high and Cathode 5 would be set low. The anodes are sorted in an array A[8], the cathodes in K[8]. The status of these are then mapped to their corresponding output pins by the following three write operations to the PORT registers:

A detail oriented person might notice that these values don’t match the schematics at all. This is because I’ve accidentally soldered the matrix in the wrong orientation, so they match if you read header A & B upside down. Shit happens!

This write operations are preformed in the timer compare A interrupt routine of Timer0. The contents of matrix[8], a bit drawing such as the arrow_up shown above, is displayed on the matrix by PWM. The toggle variable has two states, f0 for lighting LEDs and 0f for dark. This way the LEDs are ran at a 50% duty cycle.

The code currently uses Timer0, but can use any available 8/16-bit timer with a little tweaking.

The state machine has four states: M8_INACTIVE, M8_STATIC, M8_BLINKWRITE, and M8_SCROLLWRITE. The inactive state is whenever some text is done displaying, or before the scroll/blink/static functions have been called. The static state is for writing a letter or displaying a figure.

The mat88_refresh() function keeps track of timing and states. If it is time, it uses an array of function pointers to choose which state to run. Each state will update the contents of the matrix[8] variable to change what is output by PWM.

Writing text by blinking
mat88_ISRblinkwrite() writes letters from the alphabet array found in mat88_abc.h into the matrix[8] variable. It will display the contents of the blobj struct:

For each call it keeps track of which letter to output and how many more times (rounds) remaining to display the given text string. When all rounds have been shown, it sets the active state to INACTIVE.

Writing text by scrolling
mat88_ISRscrollwrite() writes letters from the alphabet array found in mat88_abc.h into the matrix[8] variable It will display whatever is provided in the swobj struct:

For each call it keeps track of which two letters to display, and how much of each. Each iteration moves the letter one LED column to the left. Just like ISRblinkwrite, it also keeps track of how many more times (rounds) remaining to display the given text string. When all rounds have been shown, it sets the active state to INACTIVE.

Future work

It would be an idea to make the card stackable with a controller card.



Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">