This post describes how I interfaced a 8x8 LED matrix with as MAX7219 multiplexing LED driver.

The 8x8 LED matrix chip

The 8x8 LED is this one (BL-M12A881UR-11):

I got it from Adafruit for around $US 3.95:

http://www.adafruit.com/products/455

The first problem you have with this is trying to work out which pin is pin 1. It isn't particularly obviously marked.

The datasheet for the product shows this:

That seems to imply that pin 1 is the one on the left if you orient the device so that the part number is towards you, as shown on the photo above where the arrow is. This appears to be the case. I marked mine with a dot from a marker pen so I wouldn't lose track of it.

Flipping it over, now pin 1 is on the right, and the other pins follow, as shown:

Wiring it up can be a bit tedious, especially as it is a bit large to fit onto a standard breadboard. I eventually soldered a 16-core ribbon cable to it like this:

The cable is "flipped" at the half-way mark, so that the pin numbers at the other end go from 1 (the red line) to 16 (the other end).

I then soldered the other end of the cable to a 16-pin header block, like this:

That could then be plugged into a breadboard for patching up to the MAX7219.

The MAX7219 multiplexing chip

Now onto the multiplexing chip, the MAX7219.

I got this also from Adafruit for around $US 10:

http://www.adafruit.com/products/453

Pinouts:

This chip has the advantage of being a constant current driver, which means you don't need to have lots of resistors between it and the LEDs to stop them drawing too much current. A single resistor connected between the ISET pin (pin 18) and Vcc (not Gnd) lets you set the desired current draw for all LEDs.

This table shows the approximate resistor sizes (in K ohms):

Since the datasheet for the BL-M12A881UR-11 specifies that it has a forward voltage drop of around 2.2V at 20 mA, I chose a 27K resistor as the RSET resistor.

The MAX7219 lets you drive up to 8 x 8-segments LEDs (7 segments plus decimal place), or simply an 8 x 8 matrix like the one I am using.

Once you have downloaded the bit pattern for what you want it to display, it automatically multiplexes that out to the LEDs by sourcing current on the appropriate segments (A to G, plus DP) and then sinking current through digits 0 through to 7, in sequence. The overall effect, since the chip sequences through the digits at about 800 Hz, is that they all appear to be on at once.

Schematic

I wired it up like this:

The 27K resistor sets the output current. The 0.1uF and 10 uF capacitors are recommended to help decouple the power line, and absorb any transient spikes in power required to turn the LEDs on and off.

The 10K "pull-down" resistor on SS is used to stop data being clocked into the chip while the Arduino (or other processor) is being powered up, and the lines at that stage might be "floating".

Note that there are two ground pins: 4 and 9.

I have wired up the DP position before A through to G, because of this table:

To get the bit positions right you need to have DP next to A (and not next to G).

The finished wiring (a bit of a rats nest) looks like this:

Note that we only need 5 wires between the breadboard and the Arduino: +5V, Gnd, MOSI, SCK and SS.

Program code

To send data to the MAX7219 is easy, we just use SPI. To send data we need to send 16 bits, which is a "register" followed by "data", like this:

The NOOP (no operation) register is used when you need to cascade MAX7219 chips together.

Registers 1 through 8 are the digits (where the 8 bits of data are which segments to display for that digit).

The "decode mode" register is used, if required, with ordinary 7-segment displays to have the chip automatically translate numbers into the correct segments. I'm not using that mode here.

The "intensity" mode register lets you set an intensity level (0 to 15) which controls the duty cycle of the PWM sent to the LEDs, and thus how bright they are.

The "scan limit" register can be used if you are using 7-segment displays. Say you only had 4 digits, then by lowering the scan limit they could be brighter, because the chip doesn't waste time trying to send data to digits that don't exist.

The "shutdown" register can be used to blank all digits at once, either because you want them blank for some reason, or to save power.

The "display test" register turns all LEDs on, presumably to test the display.

Font

To display text (like letters, numbers, symbols) I have borrowed the CP437 font from another project. Put this into a "font.h" file:

Since I only had one matrix, I displayed a string a letter at a time, with a specified pause for you to view it. There is also a brief blank interval between letters (for things like "ee" in "greet") so the flicker shows you have changed letters.

This is a 4-segment common-cathode display. It's important to get a common-cathode display because of the way the MAX7219 works.

The datasheet that I found shows:

Once again it is hard to tell where pin 1 is, but guessing it is in the same place as the other one (on the left with the part number towards you) that appeared to be confirmed by testing. To show on a photo:

Schematic

This time the wiring is pretty simple. Just follow the wiring diagram for the LED display and connect up the wires as marked:

Program code

This simple Arduino sketch shows how you can send numbers to the 7-segment display. This time we can let the MAX7219 work out which segments to light up by switching to "digits" mode. We also set the scan limit to 3 (in other words, 4 segments) which makes each one brighter.

The kit is designed to "daisy-chain" the boards, so the DOUT of each board goes into the DIN of the next one, thus you could display multiple letters.

Displaying text upside down

These devices might be more easily mounted upside down (with the chip at the top and the flat surface at the bottom). In this case you can rotate the letters 180 degrees by replacing the "letter" function by this:

The MAX7219 is designed to be daisy-chained so you can have multiple 64-pixel displays connected together (like those scrolling signs you see in shop windows).

To make use of this you basically have to treat them like a serial of shift register. When SS goes high the last 16 bits that were shifted out are latched into each display. So if you have two displays and you want to affect the further one then you have to send 32 bits, the first 16 are the "real" data, followed by a NOP (0x00) and another 0x00. The chips are designed to ignore the NOP, so only the further chip is affected. Of course, if you had three chips you would have to send:

REGISTER DATA NOP NOP NOP NOP

That way you are sending 48 bits, which get propagated along the chain to affect the third chip.

However if you have three chips and you want to update the middle one you need NOPs at each side, eg.

NOP NOP REGISTER DATA NOP NOP

Otherwise subsequent chips down the chain update when you don't want them to.

If you want to send the same thing to each chip (Eg. configuration) then you don't need the NOPs, you just have to send REGISTER/DATA x number of times, where x is the count of chips.

Here is an example of addressing two chips (in number mode) which between them display a 16-digit number.

You can buy 8-digit display modules from eBay for around $US 2 to $US 5 each.

I got a batch of these ones a while ago, they are designed to butt up against each other vertically or horizontally, like this:

The reverse side:

The decimal point on the LED modules is on the bottom - that is adjacent to pin 1.

The modules come with the MAX7219 chip, a chip socket, some 10 µF capacitors (2 per board), a resistor (1 per board),
and some connecting pins.

The LED modules - available in various colours:

Assembly

Start by soldering on the two capacitors and the resistor - orientation does not matter.

Detail for the surface-mounted devices:

The SMD parts might look a bit daunting, but if you stay calm they can be soldered OK. The main problem is they are so small they tend to skitter away like frightened mice. You could try to hold them down with an alligator clip:

Or tape one side down and solder the other:

Once you have one side soldered you can remove the restraining device and solder the other side.

Solder together the links and the earth pads:

Add a single connector for data from the Arduino:

Note the data flow direction. The DIN (Data in) pin starts at one side and then flows out of the DOUT (Data out) pin into the DIN pin on the next board. Data direction shown by the arrows.

Solder on the chip sockets before the LEDs or you won't be able to do it afterwards.

Then turn it over and install the LEDs. I suggest putting all the LED modules on before you solder, in case you need to push them sideways slightly to make them fit. If you solder one in first that might be impossible later.

Note that the furthest module from the data plug gets the first part of the text ("Testing" in this case). This is because the letters are "pushed" from one module to the next.

You could also solder them sideways if you just wanted to display a long number with more than 8 digits.

Scrolling display

For a scrolling display you can have a longer message, as in the example below, and pull out 8 (or 16 or 24) characters at a time from inside that message, and display that. Next time, move forwards one byte. Eventually wrap around back to the start.

There is also a demo of scrolling text, however that scrolls a chip at a time, not a pixel at a time.

Smooth scrolling

Library updated on 2nd October 2015 to have smooth scrolling. A new example has been added which demonstrates this. To achieve this each for each display module (8 x 8 pixels) the code calculates the pixels for the byte before, the current byte, and the byte after. Then it applies the pixel offset to choose a starting point somewhere in those 24 (horizontally) pixels.

During testing of the MAX7219 display modules, I noticed some unreliable behaviour. This was caused by the high current requirements of these modules, particularly if a lot of pixels are on, and it is in high-intensity mode.

For example, checking a single 64-pixel module:

All LEDs on (sending the character 0xDB):

Intensity Milliamps
--------------------
1 35
7 131
15 236

Some LEDs on (sending the letter 'A'):

Intensity Milliamps
--------------------
1 19
7 68
15 126

You can see from that, that if you had 16 modules (ie. displaying 16 characters at once) in full intensity, and if they happened to power on with all bits set, you would need:

16 * 236 = 3.776 amps

Yes, almost 4 amps! Now, there is no way that can be powered from the Arduino board (at least not without getting a big voltage drop, which could make the processor reset repeatedly, or making the voltage regulator get very hot).

For running multiple chips like this (for example, for a scrolling LED sign) you would need to provide a separate 5V power supply, suitably rated (eg. 5 amps) for the LED strip. Of course, the Ground wires need to be connected to the Arduino ground as well.