Arduino with Serially Interfaced MAX7219 Operates 8X8 LED Matrix

by Lewis Loflin

The following demonstrates the use of the MAX7219 display driver with a Arduino Microcontroller. This sample code move an arrow across a 8X8 LED matrix. These units are inexpensive and sold by several vendors on Ebay for under $5. This code was ported over from my PIC18F2550 pages and was designed to work on either micro-controller without the use of other user libraries. This makes the code more portable.

This demo operates in the non-decode mode.

The MAX7219 is a serial input/output common-cathode display driver that interfaces microprocessors to a 7-segment numeric LED displays of up to 8 digits, bar-graph displays, or 64 individual LEDs.

First the address (0x00 - 0x0f) is clocked in by ssrWrite(), then the data or command byte is clocked in.

Included on-chip are a BCD code-B decoder, multiplex scan circuitry, segment and digit drivers, and an 8x8 static RAM that stores each digit. Only one external resistor is required to set the segment current for all LEDs.

A convenient 4-wire serial interface connects to all common uPs. Individual digits may be addressed and updated without rewriting the entire display. The MAX7219 will also allow the user to select code- B decoding or no-decode for each digit.

The devices include a 150uA low-power shutdown mode, analog and digital brightness control, a scan limit register that allows the user to display from 1 to 8 digits, and a test mode that forces all LEDs on.

Arduino connected to MAX7219

#define Rb5  7  // CS
#define Rb6  8  // DATA
#define Rb7  9  // CLK

// pattern for 8 X 8 LED matrix
char array1[] = { 
  0x00, 0x00, 0x81, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }; 

void setup()   {

  pinMode(Rb5, OUTPUT);
  pinMode(Rb6, OUTPUT);
  pinMode(Rb7, OUTPUT);
  digitalWrite(Rb5, LOW);

void loop()   {


  int k = 0;
  while(1)   {  
    for (int j=1; j<9; j++)   {
      writeMAX7219(j+k, array1[j]);
    if (k > 8) k = 0;

// shift data to MAX7219
// Rb7 -> CLK, Rb6 -> DATA, Rb5 -> CS not
void ssrOut(unsigned char val)  {  
  int j;
  for(j=1; j<=8; j++)  {   // shift out MSB first
    unsigned char  temp = val & 0x80; // MSB out first
    if (temp == 0x80) digitalWrite(Rb6, 1); // Rb6 DATA          
    else digitalWrite(Rb6, 0); 
    digitalWrite(Rb7, 1);
    digitalWrite(Rb7, 0);
    val = val << 1; // shift one place left
  }  // next jvoid pulseCS(void)   {
  digitalWrite(Rb5, 1);
  digitalWrite(Rb5, 0);

void init_MAX7219(void)   {
  digitalWrite(Rb5, 0); // CS NOT

  // set decode mode
  ssrOut(0x00); // no decode

  // set intensity
  ssrOut(0x08); // 0 - F

  // set scan limit
  ssrOut(0x07); // 8 digits
  // set for normal operation


void writeMAX7219(char address, char data)   {
  if ((address < 1) || (address > 8)) return;
  ssrOut(address); // valid numbers 1-8

You Tube Arduino Microcontroller Video Series March 2012: