Interfacing MAX7219 LED Dot Matrix Display with Arduino

Sooner or later, Arduino enthusiasts always come across the dot matrix display. It is a two-dimensional patterned LED array that is used to represent characters, symbols, and images. Almost all modern outdoor LED displays use dot matrices.

And there is hardly any better option than the MAX7219 IC to control them. This is a simple and somewhat inexpensive way of controlling a single matrix. In addition they can be chained together to control two or more dot matrices for larger projects.

Overall they are a lot of fun and quite useful as well, so let’s get started.

MAX7219 Module Overview

There are several MAX7219 breakout boards available, two of which are more popular – one is the generic module and the other is the FC-16 module.

max7219 module variants

A typical MAX7219 module contains a 8×8 dot matrix display and a MAX7219 LED display driver. Let’s get to know them one by one.

The Dot Matrix Display

8x8 dot matrix display

A typical single color 8×8 dot matrix unit has 16 pins, 8 for each row and 8 for each column. The reason for all rows and columns being wired together is to reduce the number of pins required. If this were not the case, an 8×8 dot matrix unit would require 65 pins, one for each LED and one for a common anode or cathode connector. By wiring rows and columns together, only 16 pins are required. This technique of controlling a large number of LEDs with fewer pins is called Multiplexing.

8x8 dot matrix internal structure multiplexing

In this technique, each column is activated for a very short period of time and at the same time LEDs on that column are lit by addressing the corresponding row. The columns are switched so fast (hundreds or thousands of times a second) that the persistence of the human eye perceives the display to be fully lit. Therefore only a maximum of eight LEDs are lit at a time.

led matrix display working animation persistence of vision

MAX7219 Chip

The annoying thing about multiplexing is that you need to use 8 power transistors and you have to constantly refresh the display to keep the image stable.

Enter the mighty MAX7219 Chip, which does all the control and refresh work for you. All you have to do is send it serial commands through the 4-pin SPI interface and it will automatically take care of the rest.

max7219 ic

It can fully control 64 individual LEDs – including maintaining the same brightness, and allowing you to adjust the brightness of the LEDs with hardware or software (or both). Once the display is updated by the microcontroller, the MAX7219 then takes care of all the work of refreshing the display at 800 Hz. Thereby removing the overhead from the microcontroller, which can be off doing other important things.

You can even turn the display off for power saving mode, and still send data while it is off. And another good thing is that when powered on, it keeps the LEDs off, so no wacky displays for the first seconds of operation.

The MAX7219 chip communicates via the SPI interface, so it only require 3 data pins to connect to a microcontroller, and what’s more we can daisy-chain several modules together for larger display using the same 3 wires.

Setting Maximum Current and Brightness

The MAX7219 chip allows you to adjust the brightness of the display with hardware or software (or both). To adjust the brightness at the hardware level, the MAX7219 breakout board comes with a resistor (RSet).

max7219 rset resistance for setting brightness

This resistor is responsible for setting the upper limit of the current that is fed into the LEDs and, hence, the overall brightness of the display.

The following table shows the values of the resistor that you should use according to the voltage and forward current for your LED matrix. e.g. if you have a 2V 20 mA LED, your resistor value will be 28kΩ (the values are in kΩ).

Rset vs. Segment current and LED forward voltage
ISEG (mA)VLED (V)
1.52.02.53.03.5
4012.211.811.010.69.69
3017.817.115.815.014.0
2029.828.025.924.522.6
1066.763.759.355.451.2

Adjusting brightness through software is covered later in this tutorial.

MAX7219 Module Pinout

Whichever variant of the module you choose, there will be two connectors on that module.

max7219 dot matrix led display module pinout

Input Connector

The breakout pins at one end of the module are used for communication with the microcontroller.

VCC connects to 5V. Due to the high current draw of the display (up to 1A, if the brightness is cranked all the way up), it is recommended to run it directly from the external power supply instead of the 5V supply from the Arduino. Otherwise, be sure to keep the brightness below 50%, so that the Arduino’s voltage regulator does not overheat.

GND connects to the common ground.

DIN is the Data In. Connect it to any digital pin of the microcontroller.

CS/LOAD is Chip Select (sometimes labeled as LOAD). Connect it to any digital pin of the microcontroller.

CLK is the Clock pin. Connect it to any digital pin of the microcontroller.

Output Connector

The breakout pins at the other end of the module are used when you want to daisy-chain displays.

VCC Connects to 5V on next module.

GND Connects to GND on next module.

DOUT is Data Out and connects to the DIN pin of the next module.

CS/LOAD Connects to CS / LOAD on next module.

CLK Connects to CLK on next module.

Wiring MAX7219 Module with Arduino UNO

Now that we know everything about the module, we can begin hooking it up to our Arduino!

Let’s first supply power to the module. Because the display draws a lot of current, we will run the module from the external power supply instead of the 5V supply from the Arduino board. If you are going to use a single MAX7219 module you can power the module directly from the Arduino, but avoid it if you can.

Now we are remaining with the pins that are used for SPI communication. As MAX7219 module require a lot of data transfer, it will give the best performance when connected up to the hardware SPI pins on a microcontroller. The hardware SPI pins are much faster than software SPI.

Note that each Arduino Board has different SPI pins which should be connected accordingly. For Arduino boards such as the UNO/Nano V3.0 those pins are digital 13 (SCK), 12 (MISO), 11 (MOSI) and 10 (SS).

If you are using a different Arduino board, it is advisable to check the official documentation about ‘SPI pin locations‘ before proceeding.

Below is the hookup for the experiments with the Generic MAX7219 Module:

wiring generic max7219 led display module with arduino

Below is the hookup for the FC-16 MAX7219 Module:

wiring fc16 max7219 led display module with arduino

If you want to daisy-chain multiple displays to create a larger display, connect the DOUT of the first display to the DIN of the next display. VCC, GND, CLK and CS will all be shared between displays.

Once your module is connected to the Arduino it’s time to write some code!

Library Installation

Controlling the MAX7219 module is a bunch of work. Fortunately, MD_Parola library was written to hide away the complexities of the MAX7219 so that we can issue simple commands to control the display.

To install the library navigate to the Sketch > Include Library > Manage Libraries… Wait for Library Manager to download libraries index and update list of installed libraries.

Arduino Library Installation - Selecting Manage Libraries in Arduino IDE

Filter your search by typing ‘max72xx‘. There should be a couple entries. Look for MD_MAX72XX by MajicDesigns. Click on that entry, and then select Install.

md_max72xx library installation

This MD_MAX72XX library is a hardware-specific library which handles lower-level functions. It needs to be paired with MD_Parola Library to create many different text animations like scrolling and sprite text effects. Install this library as well.

md_parola library installation

Basic Arduino Code – Printing Text

For our first experiment we will print a simple text on the display without any animation.

But before you proceed to upload the sketch, you need to make some changes to make it work for you. You must modify the following two variables.

changes to make

The first variable, HARDWARE_TYPE, tells the arduino which version of the module you are using.

  • Set the HARDWARE_TYPE to GENERIC_HW, if you are using a module that usually comes with a green PCB and a through hole MAX7219 IC, as shown below.
    max7219 generic module
  • Set the HARDWARE_TYPE to FC16_HW, if you are using a module that usually comes with a blue PCB and a SMD MAX7219 IC as shown below.
    max7219 fc 16 module

With the second variable, MAX_DEVICES, you set the number of 8×8 dot matrix displays being used. An 8×8 matrix counts as 1 device, so if you want to control an 8×32 module you must set MAX_DEVICES to 4 (an 8×32 display contains 4 MAX7219 ICs).

Once you are done, go ahead and try the sketch out and then we will dissect it in some detail.

// Including the required Arduino libraries
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Uncomment according to your hardware type
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

// Defining size, and output pins
#define MAX_DEVICES 4
#define CS_PIN 3

// Create a new instance of the MD_Parola class with hardware SPI connection
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

void setup() {
	// Intialize the object
	myDisplay.begin();

	// Set the intensity (brightness) of the display (0-15)
	myDisplay.setIntensity(0);

	// Clear the display
	myDisplay.displayClear();
}

void loop() {
	myDisplay.setTextAlignment(PA_LEFT);
	myDisplay.print("Left");
	delay(2000);
	
	myDisplay.setTextAlignment(PA_CENTER);
	myDisplay.print("Center");
	delay(2000);

	myDisplay.setTextAlignment(PA_RIGHT);
	myDisplay.print("Right");
	delay(2000);

	myDisplay.setTextAlignment(PA_CENTER);
	myDisplay.setInvert(true);
	myDisplay.print("Invert");
	delay(2000);

	myDisplay.setInvert(false);
	myDisplay.print(1234);
	delay(2000);
}

Output

After uploading the sketch, you have to orient the display properly to see the output. If you are using a generic module, orient it so that the MAX7219 IC is on top. And if you are using a FC-16 module then orient it so that the DIN side remains on the right side.

If all is well, you will see the following output.

max7219 led display arduino text output

Code Explanation

The first step is to include all the necessary Arduino libraries. As stated earlier, the MD_MAX72XX library implements the hardware-specific functions of the LED matrix while the MD_Parola library implements the text effect. You also have to include the SPI library, which comes pre-installed in the Arduino IDE. This library is used for communication between the display and the Arduino via SPI.

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

Next, we need to specify which hardware we are using. Since we are using a FC-16 module for our experiments, the HARDWARE_TYPE is set to FC16_HW. The number of MAX7219 ICs we are using is 4, so MAX_DEVICES is set to 4. Finally, the pin to which pin the CS pin of the display is connected, is defined.

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3

Next, a new instance of the MD_Parola class is created with the function MD_Parola(). This function requires three parameters, the first being the hardware type, the second the CS pin, and the third the maximum number of connected devices.

MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

In the setup section of the code, we first initialize the object with the function begin(). The brightness of the display can be set with the function setIntensity(). You can enter a value between 0 (minimum brightness) and 15 (maximum brightness). The function displayClear() clears the display.

void setup() {
  myDisplay.begin();
  myDisplay.setIntensity(0);
  myDisplay.displayClear();
}

In the loop section of the code, we first set the alignment of the text to be printed with the function setTextAlignment(). You can left, center, and right align the text with PA_LEFT, PA_CENTER, and PA_RIGHT respectively.

Next, the string ‘Left’ is printed with myDisplay.print("Left"). Note that you need to place quotation marks " " around the text since we are printing a text string. When you want to print numbers, no quotation marks are necessary. For example myDisplay.print(1234). You can also invert the display using the function setInvert().

void loop() {
	myDisplay.setTextAlignment(PA_LEFT);
	myDisplay.print("Left");
	delay(2000);
	
	myDisplay.setTextAlignment(PA_CENTER);
	myDisplay.print("Center");
	delay(2000);

	myDisplay.setTextAlignment(PA_RIGHT);
	myDisplay.print("Right");
	delay(2000);

	myDisplay.setTextAlignment(PA_CENTER);
	myDisplay.setInvert(true);
	myDisplay.print("Invert");
	delay(2000);

	myDisplay.setInvert(false);
	myDisplay.print(1234);
	delay(2000);
}

Arduino Code – Scrolling Text

When you want to print a message on a dot matrix display, you will often find that the display is too small to fit the entire message. The solution is to use the scroll text effect. The following example shows you how to scroll a message.

// Including the required Arduino libraries
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Uncomment according to your hardware type
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

// Defining size, and output pins
#define MAX_DEVICES 4
#define CS_PIN 3

// Create a new instance of the MD_Parola class with hardware SPI connection
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

void setup() {
	// Intialize the object
	myDisplay.begin();

	// Set the intensity (brightness) of the display (0-15)
	myDisplay.setIntensity(0);

	// Clear the display
	myDisplay.displayClear();

	myDisplay.displayScroll("Hello", PA_CENTER, PA_SCROLL_LEFT, 100);
}

void loop() {
	if (myDisplay.displayAnimate()) {
		myDisplay.displayReset();
	}
}

If everything is fine, you will see the following output.

max7219 led display arduino scrolling output

Code Explanation

You will notice that the first part of the code by the end of the setup section is exactly the same as the previous example. At the end of the setup section, the displayScroll() function is used.

myDisplay.displayScroll("Hello", PA_CENTER, PA_SCROLL_LEFT, 100);

As you can see this function takes four arguments: displayScroll(pText, align, textEffect, speed)

  • pText – is the text string. Your message goes here.
  • align – sets the alignment of text during optional pause. You can use the same alignment options as in the previous example, like PA_CENTER, PA_LEFT, or PA_RIGHT.
  • textEffect – specifies the scrolling effects. Setting it to PA_SCROLL_LEFT will scroll the text left.
  • speed ​​- determines the speed of the animation. The speed is the time in milliseconds between animation frames. Short time results in faster animation.

Apart from this, in the loop section, only two functions are used to create a scrolling text. First, we use the function displayAnimate() in an if statement. This function scrolls the text and returns true when the scrolling is finished. When the scrolling is finished, we reset the display with the function displayReset(), so that we get continuous scrolling.

void loop() {
	if (myDisplay.displayAnimate()) {
		myDisplay.displayReset();
	}
}

For other text effects, please visit MD_Parola Library Reference on github.