Interfacing MAX7219 LED Dot Matrix Display with Arduino

Dot matrix displays are something that all Arduino enthusiasts come across at some point. These displays are so popular that almost all modern outdoor LED displays use them to display characters, symbols, and images.

When it comes to controlling dot-matrix displays, there is hardly a better option than the MAX7219. It can easily control a single dot matrix and, for larger projects, it can be chained together to control two or more dot matrices.

All in all, 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: the generic module and the FC-16 module.

max7219 module variants

A typical MAX7219 module includes an 8×8 dot matrix display and a MAX7219 LED display driver. Let’s get familiar with them.

The Dot Matrix Display

8x8 dot matrix display

An 8×8 dot matrix display typically has 16 pins, 8 for each row and 8 for each column. All rows and columns are wired together in order to reduce the number of pins. If this were not the case, an 8×8 dot matrix display would require 65 pins, one for each LED and one for a common anode or common cathode connector. By connecting rows and columns, only 16 pins are needed to control the entire matrix. This technique of controlling a large number of LEDs with fewer pins is referred to as Multiplexing.

8x8 dot matrix internal structure multiplexing

In this technique, each column is activated for a very short time, and at the same time, the LEDs on that column are lit by addressing the corresponding row. As a result, no more than eight LEDs are lit at the same time. The columns are switched so fast (hundreds or thousands of times per second) that the human eye perceives the display as fully lit.

led matrix display working animation persistence of vision

MAX7219 Chip

The only problem with multiplexing is that you have to refresh the display all the time to keep the image stable.

Then there’s the MAX7219 Chip, which handles all of 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 take care of the rest.

max7219 ic

It can fully control 64 individual LEDs while keeping their brightness constant. Once the microcontroller has updated the display, the MAX7219 handles the work of refreshing the display at 800 Hz. This frees up the microcontroller to do other important things.

The MAX7219 has a power saving mode in which the display can be turned off to save power. It also turns off the LEDs during startup, preventing wacky displays for the first few seconds of operation.

The MAX7219 communicates via the SPI interface, so it only needs 3 data pins to connect to a microcontroller. In addition, we can daisy-chain multiple modules together for a larger display using the same 3 wires.

Setting Maximum Current and Brightness

The MAX7219 allows you to adjust the brightness of the display using either hardware or software (or both).

At the Hardware Level

The MAX7219 breakout board includes a resistor (RSet) for adjusting the brightness at the hardware level.

max7219 rset resistance for setting brightness

This resistor controls the maximum current supplied to the LEDs and, hence, the overall brightness of the display.

The table below shows the resistor values you should use based on the voltage and forward current of your LED matrix. A 2V 20 mA LED, for instance, would require a 28kΩ resistor.

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

At the Software Level

We’ll discuss adjusting brightness using software later in this tutorial.

MAX7219 Module Pinout

Regardless of which variant you select, the module will have two connectors.

max7219 dot matrix led display module pinout

Input Connector

The breakout pins on one end of the module are used to communicate with the microcontroller.

VCC is connected to 5V. Because the display draws a lot of current (up to 1A at maximum brightness), it’s best to use an external power supply instead of the Arduino’s 5V supply. If you want to use the Arduino’s 5V supply, keep the brightness below 25% to avoid overheating the voltage regulator.

GND is the common ground pin.

DIN is the Data pin. 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 stands for Clock pin. Connect it to any digital pin of the microcontroller.

Output Connector

The breakout pins on the other end of the module are used to daisy-chain displays.

VCC connects to 5V on the next module.

GND connects to GND on the next module.

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

CS/LOAD connects to CS / LOAD on the next module.

CLK connects to CLK on the next module.

Wiring MAX7219 Module with Arduino UNO

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

Let’s start with the module’s power supply connections. Because the display consumes a lot of current, we’ll use an external power supply instead of the Arduino board’s 5V supply. If you are only using a single MAX7219 module, you can power it directly from the Arduino, but you should avoid doing so if possible.

Let’s wire up the SPI pins. Note that each Arduino board has a unique set of SPI pins that must be connected accordingly. For Arduino boards such as the UNO/Nano V3.0, these pins are digital 13 (SCK), 12 (MISO), 11 (MOSI), and 10 (SS).

If you’re using a different Arduino board, check the official documentation for SPI pin locations before proceeding.

Here is the wiring for the Generic MAX7219 Module:

wiring generic max7219 led display module with arduino

Here is the wiring for the FC-16 MAX7219 Module:

wiring fc16 max7219 led display module with arduino

If you want to daisy-chain multiple displays to make 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 lot of work. Fortunately, the MD Parola library was written to hide the complexities of the MAX7219, allowing us to control the display with simple commands.

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

Arduino Library Installation - Selecting Manage Libraries in Arduino IDE

Filter your search by entering ‘max72xx’. Look for MD_MAX72XX by MajicDesigns. Click on that entry and then choose Install.

md_max72xx library installation

The MD_MAX72XX library is a hardware-specific library that handles lower-level functions. It must be used in conjunction with the MD_Parola Library to create a variety of text animations such as scrolling and sprite text effects. Install this library as well.

md_parola library installation

Arduino Example Code 1 – Printing Text

Our first experiment involves displaying a simple text without any animation.

But, before you upload the sketch, you must modify the following two variables.

changes to make

The first variable, HARDWARE_TYPE, informs the Arduino of the module variant.

  • Set the HARDWARE_TYPE to GENERIC_HW, if you’re using a module with a green PCB and a through hole MAX7219 IC like the one shown below.
    max7219 generic module
  • Set the HARDWARE_TYPE to FC16_HW, if you’re using a module with a blue PCB and an SMD MAX7219 IC like the one shown below.
    max7219 fc 16 module

The second variable, MAX_DEVICES, specifies the number of MAX7219 ICs being used. A single MAX7219 IC counts as one device, so if you want to control an 8×32 display, set MAX_DEVICES to 4 because an 8×32 display has four MAX7219 ICs.

When you’re finished, try out the sketch, and then we’ll go over it in 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

To see the output, the display must be properly oriented. If you’re using a generic module, make sure the MAX7219 IC is on top. If you’re using an FC-16 module, make sure the DIN side is on the right side.

If everything goes 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 previously stated, the MD_MAX72XX library implements the hardware-specific functions of the LED matrix, whereas the MD_Parola library implements the text effect. You must also include the SPI library, which is used to communicate with the display via SPI.

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

Next, we must specify which hardware is being used. Because we are using an FC-16 module for our experiments, the HARDWARE_TYPE is set to FC16_HW. We’re using 4 MAX7219 ICs, so MAX_DEVICES is set to 4. Finally, the pin to which the display’s CS pin is connected is defined.

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

The function MD_Parola() is then used to create a new instance of the MD_Parola class. The first parameter is the hardware type, the second is the CS pin, and the third is the number of MAX7219 ICs being used.

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

In the setup section of the code, we first use the function begin() to initialize the object. The brightness of the display can be adjusted using the function setIntensity(), which accepts values ranging from 0 (lowest brightness) to 15 (maximum brightness). The display is cleared using the displayClear() function.

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(), to which the values PA_LEFT, PA_CENTER, and PA_RIGHT can be passed to align the text to the left, center, or right, respectively.

The string ‘Left’ is then printed using myDisplay.print("Left"). Please keep in mind that the text string should be enclosed in quotation marks " ". When printing numbers, no quotation marks are required; for example, to display 1234, write myDisplay.print(1234). You can also use the setInvert() function to invert the display.

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 Example Code 2 – 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 whole message. The solution is the scroll text effect.

The example below demonstrates 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 goes well, you will see the following output.

max7219 led display arduino scrolling output

Code Explanation

You’ll notice that everything from the beginning of the code to the end of the setup section is the same as the previous example. The only difference is that the displayScroll() function is called at the end of the setup section.

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.

Only two functions are used to scroll text in the loop section. First, in an if statement, we use the function displayAnimate(). This function scrolls the text and returns true when it is finished. When the scrolling is finished, we use the function displayReset() to reset the display, resulting in continuous scrolling.

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

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