Max72xxPanel - Interface for Adafruit GFX for MAX7219

Today I posted a library to Github which implements a hardware driver for Adafruit's GFX library for the cheap MAX7219 8x8 led matrix. It is rather basic, but does support double buffering to prevent screen flicker, especially useful for applications like a ticker tape.

Please feel free to report bugs!

Thankyou for library!

I've tested it a bit with 7219, if you want put in examples a comment like:

Max72xxPanel matrix = Max72xxPanel(12, 11, 10); // DIN, CLK, LOAD

i think may be useful, for quick start without read the Max72xxPanel.cpp or .h files

Why not use SPI for sending data to the MAX7219?
It works quite well with the default settings (4 MHz clock).

alessiocavalieri:
I've tested it a bit with 7219, if you want put in examples a comment like:

Max72xxPanel matrix = Max72xxPanel(12, 11, 10); // DIN, CLK, LOAD

i think may be useful, for quick start without read the Max72xxPanel.cpp or .h files

Done.

CrossRoads:
Why not use SPI for sending data to the MAX7219?
It works quite well with the default settings (4 MHz clock).

As opposed to the MAX7221, the MAX7219 is not fully SPI compatible. The MAX7219 reads the DIN line even when LOAD (~CS) is low. From the MAXIM datasheet:

For the MAX7219, serial data at DIN, sent in 16-bit packets, is shifted into the internal 16-bit shift register
with each rising edge of CLK regardless of the state of LOAD. For the MAX7221, CS must be low to clock data
in or out. The data is then latched into either the digit or control registers on the rising edge of LOAD/CS.
LOAD/CS must go high concurrently with or after the 16th rising clock edge, but before the next rising clock
edge or data will be lost.

I would say this doen't matter, so I tried to use Arduino's SPI library. But the display isn't properly addressed, most of the time the whole display lights up. So this won't work for a MAX7219:

digitalWrite(SPI_CS, LOW);
SPI.transfer(xx);
SPI.transfer(xx);
digitalWrite(SPI_CS, HIGH);

I'm trying to use the code with two matrix modules but i don't understand how.

I've tried the hDisplays and the vDisplays parameters without success, i.e. :

Same thing displayed in each of the two matrix in cascade:

Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 1, 1);

Nothing displayed in the 2nd matrix in cascade:

Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 2, 1);
Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 1, 2);
Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 2, 2);

Something wrong in my approach?

Mark Ruys,
Have you tested this?

digitalWrite(SPI_CS, LOW);
SPI.transfer(xx);
SPI.transfer(xx);
digitalWrite(SPI_CS, HIGH);

I have used that exact sequence on several MAX7219 designs, and it works just fine.

alessiocavalieri:
Nothing displayed in the 2nd matrix in cascade:

Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 2, 1);
Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 1, 2);
Max72xxPanel matrix = Max72xxPanel(5, 4, 3, 2, 2);

Currently, the library does not support cascade displays positioned vertically. So the last digit should always be 1.

I have checked the code for bugs for multiple horizontal displays, but found none. Unfortunately, I own only a single 8x8 display, so It's a bit difficult to fix the code as I can't test it.

The examples I wrote didn't support multiple horizontal displays. I fixed this, so please download and install the library again.

I suggest you first try the MadFly example (which doesn't use double buffering), attach the Data OUT pin of the first display to the Data IN pin of the second, and give it another try. If it fails, someone owning multiple displays might try to fix it (or someone send me a display for testing, in which case I'll add support for multiple vertical displays too :wink: )

I have not cascaded them either, just connected up 4 in parallel with unique SS for each so I didn't have to fool with sending out a bunch of No-ops thru 3 chips to access a register on the 4th.
I used mine for a scrolling display, didn't the software hassle of having to send out every 8th byte from the array where I was storing the messge being displayed.
Only have serial and the 4MAX7219's connected, so plenty of free pins available for unique SS outputs.

Here's a video of it working
www.crossroadsfencing.com/BobuinoRev17/Scroll_Test.AVI
Later version of the software holds each position for 40 or 50mS, faster than that it was hard to read as the text whipped by.
Got a you tube version somewhere, have to find the link.

CrossRoads:
I have not cascaded them either, just connected up 4 in parallel with unique SS for each so I didn't have to fool with sending out a bunch of No-ops thru 3 chips to access a register on the 4th.

The Max72xxPanel library uses double buffering, so no NOPs involved. Still, each refresh the number of pixels times two are serially send out to DIN.

Later version of the software holds each position for 40 or 50mS, faster than that it was hard to read as the text whipped by.

Care to share us your code? I'm particular interested how you used <SPI.h> in combination with a MAX7219, as my attempt failed. Could also be caused as I happen to own a fake MAX7219 (http://tronixstuff.wordpress.com/2013/05/16/the-max7219-led-display-controller-real-or-fake/)...

Buy some real parts from taydaelectronics.com, $1.25 each.
Will post when I get home.

CrossRoads:
Buy some real parts from taydaelectronics.com, $1.25 each.

:smiley: I never knew fake MAX7219's existed until I stumbled upon the site mentioned earlier. Back to topic: I miswired DIN to MISO, after doing to right, the <SPI.h> library worked. So I'll probably switch Max72xxPanel to using the SPI library. Sorry for the confusion...

Operator error, will get you every time 8)

Ok, downloaded the new code, it works in horizontal cascade mode.

This picture show uncorrect visualization (ticker example) because my modules are stackable as vertical only:

Imgur

this is the rear side of cascade connectors:

Imgur

Now is necesary think how to implement vertical cascade mode...

CrossRoads:
Why not use SPI for sending data to the MAX7219?
It works quite well with the default settings (4 MHz clock).

Implemented. Memory footage is even lower now. Unfortunately the Max72xxPanel constructor has changed (dropped MOSI and CLK pin definitions):

Max72xxPanel(int csPin, int hDisplays=1, int vDisplays=1);

Some day I'll implement multiple vertical displays...

Just rotate the character set 90 Deg... and turn it (the display) on end...

alessiocavalieri:
I'm trying to use the code with two matrix modules but i don't understand how.

I've just commited some changes to support multiple vertically connected displays. Any set of matrices in the form of a rectangular should work now. Connect them in cascade, starting from the upper left to the bottom right:
1 2
3 4
5 6
Please give it a try, as I have only a single display and can't test the modifications for multiple displays myself.

SPI, works fine, but some tuning in cascade is required, my test downloadable as movie + readme:

https://www.dropbox.com/sh/3zx1m6vshfvir4g/k5qnJVpXAo?m

I have tested this library:

http://forum.arduino.cc/index.php?topic=144872.0

https://github.com/mjkzz/LedMatrix

with these lib i'm able to scroll a rectangle between two horizontal matrix modules, probably you can get some ideas...

#include <avr/io.h>
#include "LedMatrix.h"

LedMatrix  				ledDisplay	= LedMatrix(51, 53, 52, 16, 16);

void setup()
{
  ledDisplay.init(8);
  ledDisplay.blank();
  ledDisplay.update();
  Serial.begin(9600);
}

void loop()
{
/*  for (int i=0;i<16;i++) {
   ledDisplay.rectangle(0,0,i,6,1);
   ledDisplay.update();
   Serial.println(i);
   delay(1);
  }
  for (int i=16;i>0;i--) {
   ledDisplay.rectangle(0,0,i,6,0);
   ledDisplay.update();
   Serial.println(i);
   delay(1);
  }
  ledDisplay.blank();
  ledDisplay.update();
*/
  ledDisplay.rectangle(12,2,13,3,GRAPHIC_DRAW_SRC);
  ledDisplay.update();
  for (int i=0;i<16;i++) {
    ledDisplay.scroll(SCROLL_LEFT,0);
    ledDisplay.update();
    delay(10);
  }
}

alessiocavalieri:
SPI, works fine, but some tuning in cascade is required, my test downloadable as movie + readme:

Thank you for your report. As I don't have the hardware to test, it's rather difficult to fix it. But I did found a bug in my rotation code in case of multiple matrices, so you might give the library another try.