Skip to Content

Tutorial de Arduino para pantalla de matriz de puntos LED MAX7219

Tutorial de Arduino para pantalla de matriz de puntos LED MAX7219

En este tutorial, aprenderás a controlar una pantalla de matriz de puntos LED con Arduino. He incluido un diagrama de conexiones y muchos ejemplos de código. El código de este tutorial puede usarse para pantallas de 8×8, 8×32 e incluso más grandes. MAX7219 LED dot matrix display con Arduino. He incluido un diagrama de conexiones y muchos ejemplos de código. El código de este tutorial puede usarse para pantallas de 8×8, 8×32 e incluso más grandes.

Para este tutorial, usaré el MD_Parola en combinación con la MD_MAX72XX biblioteca de Arduino. Estas bibliotecas facilitan mucho mostrar texto desplazable y otras animaciones. En la primera parte de este artículo, cubriré los conceptos básicos para imprimir texto en la pantalla. Luego, veremos texto desplazable y otras animaciones de texto. Por último, te mostraré cómo usar sprites de texto.

Si quieres aprender más sobre este u otros tipos de pantallas, consulta los artículos a continuación:

Artículos recomendados

Materiales

Componentes de hardware

8×32 MAX7219 LED dot matrix display × 1 Amazon
8x8-MAX7219-LED-dot-matrix-display8×8 MAX7219 LED dot matrix display (alternativa) × 1 Amazon
generic-MAX7219-8x8-LED-dot-matrix-displayGeneric 8×8 MAX7219 LED dot matrix display (alternativa) × 1 Amazon
Arduino Uno Rev 3Arduino Uno Rev3 × 1 Amazon
Jumper wires  (macho a hembra) × 4 Amazon
USB cable type A/B × 1 Amazon
Male headers ~ 20 Amazon
Jumpers ~ 20 Amazon

Software

Arduino IDEArduino IDE

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Acerca del controlador LED MAX7219

El controlador LED MAX7219 puede usarse para controlar displays de 7 segmentos de hasta 8 dígitos, displays de barras o 64 LEDs individuales. El controlador se comunica con Arduino mediante SPI, por lo que solo necesitas tres cables para controlar la pantalla.

Como el MAX7219 puede controlar un máximo de 64 LEDs, el tamaño máximo de pantalla de matriz de puntos que puede manejar es de 8×8 píxeles. Sin embargo, puedes encadenar en serie varios controladores y matrices para controlar fácilmente pantallas mucho más grandes como 8×32, 8×64 o incluso mayores. Aun así, solo necesitas tres cables para controlar todos los circuitos integrados, por lo que se requieren muy pocos pines de E/S del Arduino.

A continuación puedes encontrar las especificaciones de una pantalla típica de matriz de puntos LED MAX7219 8×32.

Especificaciones de la pantalla de matriz de puntos LED MAX7219

Voltaje de funcionamiento 5 V
Controlador de pantalla MAX7219 x 4
Niveles de brillo 16
Dimensiones de la pantalla 32 x 128 x 15 mm
Píxeles 8×32, ⌀ 3 mm
Costo Check price

Para más información, puedes consultar la hoja de datos:

Casi todas las pantallas que he usado en el pasado utilizan una matriz LED tipo 1088AS de 8×8. Puedes encontrar una hoja de datos de uno de los fabricantes a continuación:

Cómo conectar la pantalla de matriz de puntos al Arduino

El controlador LED MAX7219 se comunica con Arduino mediante SPI (Interfaz Periférica Serial). Con una interfaz SPI siempre hay un dispositivo maestro (el Arduino) que controla los dispositivos periféricos (también llamados esclavos). Puedes controlar la pantalla a través del hardware SPI del microcontrolador AVR del Arduino o usando tres pines digitales arbitrarios (SPI por software).

Los pines hardware SPI (MOSI, MISO y SCK) están en una ubicación específica en cada placa Arduino. Esta interfaz es más rápida que usar SPI por software, pero necesitas usar los siguientes pines de salida fijos:

Ubicación de pines hardware SPI

Placa MOSI MISO SCK Nivel
Arduino Uno 11 o ICSP-4 12 o ICSP-1 13 o ICSP-3 5 V
Arduino Mega 51 o ICSP-4 50 o ICSP-1 52 o ICSP-3 5 V
Arduino Leonardo ICSP-4 ICSP-1 ICSP-3 5 V
Arduino Due SPI-4 SPI1 SPI-3 3.3 V
Arduino MKR1000 8 10 9 3.3 V
Ubicación de pines hardware SPI en diferentes placas Arduino.

Ten en cuenta que los pines MOSI, MISO y SCK también están en una ubicación física consistente en el conector ICSP de 6 pines:

ICSPHeader
Fuente: Arduino.cc

Para controlar pantallas MAX7219 solo necesitas hacer tres conexiones:

  • MOSI (Master Out Slave In) conectado a DIN – La línea maestra que envía datos a los periféricos.
  • SCK (Serial Clock) conectado a CLK – Los pulsos de reloj que sincronizan la transmisión de datos generados por el maestro.
  • SS (Slave Select) conectado a CS – El pin en cada dispositivo que el maestro puede usar para habilitar o deshabilitar dispositivos específicos.

Puedes encadenar en serie varias pantallas para crear una pantalla grande conectando DOUT de la primera pantalla a DIN de la siguiente. VCC, GND, CLK y CS se comparten entre todas las pantallas.

Puedes seleccionar cualquiera de los pines digitales del Arduino para el pin SS/CS. Ten en cuenta que para este tutorial usé el pin 3 (ver tabla abajo).

El diagrama de conexiones a continuación muestra cómo conectar la pantalla de matriz de puntos LED MAX7219 al Arduino. Ten en cuenta que al usar la biblioteca MD_Parola, debes orientar la pantalla con el conector DIN a la derecha, de lo contrario el texto se imprimirá al revés. Para más información, consulta la sección siguiente.

MAX7219-LED-dot-matrix-display-with-Arduino-Uno-wiring-diagram-schematic-pinout
Diagrama de conexiones de la pantalla de matriz de puntos LED MAX7219 con Arduino

Las conexiones también se muestran en la tabla a continuación:

Conexiones de la pantalla de matriz de puntos LED MAX7219

Pantalla MAX7219 Arduino
VCC 5 V
GND GND
DIN 11 (MOSI)
CS 3 (SS)
CLK 13 (SCK)

Si prefieres usar SPI por software, puedes conectar DIN, CS y CLK a cualquiera de los pines digitales del Arduino. Solo necesitas especificar los números de pin en la configuración del código Arduino (ver ejemplos abajo).

Requisitos de alimentación

La máxima corriente que el Arduino Uno puede suministrar de forma segura cuando se alimenta por USB es alrededor de 400 mA a 5 V. Si quieres controlar una pantalla grande, se recomienda usar una fuente de alimentación externa.

Instalación de las bibliotecas Arduino MD_Parola y MD_MAX72XX

Para controlar la pantalla MAX7219 usaremos dos excelentes bibliotecas Arduino creadas por Marco Colli de MajicDesigns. La biblioteca MD_Parola permite crear muchas animaciones de texto diferentes como desplazamiento y efectos de texto sprite. Esta biblioteca depende de MD_MAX72XX, que implementa las funciones hardware de la matriz LED.

Estas son algunas funciones y características de la biblioteca:

  • Justificación de texto a la izquierda, derecha o centrado
  • Desplazamiento de texto con efectos de entrada y salida
  • Control de parámetros de pantalla y velocidad de animación
  • Múltiples pantallas virtuales (zonas) en cada cadena de módulos LED
  • Soporte para interfaz hardware SPI
  • Fuentes definidas por el usuario y/o sustituciones de caracteres individuales
  • Soporte para pantallas de doble altura
  • Soporte para mezclar texto y gráficos en la misma pantalla

Marco ha estado trabajando en esta biblioteca durante varios años y ha escrito excelentes tutoriales sobre his blog. El código fuente y la documentación de las bibliotecas están disponibles aquí:

Puedes instalar las bibliotecas a través del Gestor de Bibliotecas del IDE de Arduino. Ve a Tools > Manage Libraries… o presiona Ctrl + Shift + I en Windows. El Gestor de Bibliotecas se abrirá y actualizará la lista de bibliotecas instaladas.

Installing an Arduino library step 1 open Library Manager
Gestionar bibliotecas

Busca ‘MD_MAX72XX’ y busca las bibliotecas de majicDesigns. Selecciona la versión más reciente y haz clic en instalar. Asegúrate de instalar tanto la biblioteca MD_MAX72XX como la MD_Parola.

Installing an Arduino library step 2 MD_Parola and MD_MAX72XX
Gestor de bibliotecas

Diferentes tipos de pantallas de matriz de puntos LED

Hay muchos tipos y tamaños diferentes de pantallas de matriz de puntos LED MAX7219 en el mercado. La biblioteca MD_MAX72XX soporta casi todas estas pantallas, pero debes configurar la biblioteca correctamente para el tipo de matriz que uses.

A continuación puedes encontrar información sobre cómo conectar y configurar las pantallas MAX7219 más comunes que puedes comprar en Amazon, AliExpress y eBay.

Pantalla de matriz de puntos LED MAX7219 (Find at Amazon)

Probablemente esta sea la pantalla MAX7219 más común que puedes encontrar. Normalmente viene como matriz LED de 8×8 o 8×32 y puedes comprarlas con diferentes colores de LED.

Orientación y conexiones del módulo

Puedes conectar fácilmente varios módulos de 8×8 o 8×32 para crear una pantalla más grande. Normalmente suelto pines macho rectos en la parte trasera de los módulos y los conecto con jumpers. Así puedes desmontarlos sin tener que desoldar conexiones.

Jumpers (Find at Amazon)

La pantalla se orienta con el lado DIN a la derecha. Ten en cuenta que el texto serigrafiado en la parte trasera del PCB puede estar al revés en esta orientación.

           DP A  B  C  D  E  F  G 
         +------------------------+ 
         | 7  6  5  4  3  2  1  0 | D0 
 CLK <---|                      1 | D1 <--- CLK 
  CS <---|                      2 | D2 <--- CS 
DOUT <---|                      3 | D3 <--- DIN 
 GND ----|                   O  4 | D4 ---- GND 
 VCC ----|                O  O  5 | D5 ---- VCC 
         |             O  O  O  6 | D6 
         |          O  O  O  O  7 | D7 
         +------------------------+

Hardware configuration in Arduino code

When setting up the display in your Arduino code you need to set the HARDWARE_TYPE to FC16_HW and specify the number of devices you have connected. An 8×8 matrix counts as 1 device, so if you want to control an 8×32 module you need to set MAX_DEVICES to 4 (an 8×32 display contains 4 MAX7219 ICs).

// Hardware SPI:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 2

// Create a new instance of the MD_MAX72XX class:
MD_Parola matrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// For software SPI you also need to specify the DATA_PIN and the CLK_PIN connections:
// #define DATA_PIN 3
// #define CLK_PIN 4

// Create a new instance of the MD_MAX72XX class:
// MD_Parola matrix = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

Generic 8×8 module

MAX7219 8x8 Module (Find at Amazon)

This is an 8×8 module mounted on a green PCB with the MAX7219 IC below the LED matrix. They are characterized by the 5-pin connectors at the short ends of the rectangular PCB.

Module orientation and connections

The generic module needs to be oriented with the MAX7219 IC at the top. You can connect multiple modules together with some short female to female jumper wires. Simply connect all the pins of the DOUT side of the first module to the DIN side of the next module.

      C  C  D  G  V
      L  S  I  N  C
      K     N  D  C
      |  |  |  |  |
      V  V  V  |  |
  D7 D6 D5 D4 D3 D2 D1 D0
+------------------------+
| 7  6  5  4  3  2  1  0 | DP
|                      1 | A
|                      2 | B
|                      3 | C
| O                    4 | D
| O  O                 5 | E
| O  O  O              6 | F
| O  O  O  O           7 | G
+------------------------+
      |  |  |  |  |
      V  V  V  |  |
      C  C  D  G  V
      L  S  O  N  C
      K     U  D  C
            T

Hardware configuration in Arduino code

For the generic display modules, you need to set the HARDWARE_TYPE to GENERIC_HW. The rest of the setup and MAX_DEVICES is the same as for the FC-16 modules.

// Hardware SPI:
#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW
#define MAX_DEVICES 1
#define CS_PIN 2

// Create a new instance of the MD_MAX72XX class:
MD_Parola matrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// For software SPI you also need to specify the DATA_PIN and the CLK_PIN connections:
// #define DATA_PIN 3
// #define CLK_PIN 4

// Create a new instance of the MD_MAX72XX class:
// MD_Parola matrix = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

Arduino example codes

Below you will find several example codes that cover the basic functions of the MD_Parola Arduino library. After each example I explain how the code works so you should be able to modify it to suit your needs. You can also find more examples when you go to File > Examples > MD_Parola in the Arduino IDE, but they don't include any explanation so they might be a bit hard to follow.

Basic Arduino example code to print text

With the example code below you can print text on the display without any animations.

You can upload the example code to your Arduino via the Arduino IDE. For this tutorial, I used this standard 8x32 LED dot matrix display (Find at Amazon) but you can use other types and/or sizes as well (see code explanation below).

/* Basic example code for MAX7219 LED dot matrix display 
  with Arduino. More info: https://www.makerguides.com */

#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"

// Define hardware type, size, and output pins:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#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);

// Setup for software SPI:
// #define DATAPIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, 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_CENTER);
  myDisplay.print("Center");
  delay(2000);
  myDisplay.setTextAlignment(PA_LEFT);
  myDisplay.print("Left");
  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);
}

You should see the following output:

Text alignment

How the code works

The first step is to include all the required Arduino libraries. As I mentioned before, the MD_MAX72XX library implements the hardware functions of the LED matrix and the MD_Parola library the text effects. You will also need to include the SPI library, which comes pre-installed in the Arduino IDE. This library is used for the Serial Peripheral Interface communication between the display and the Arduino.

#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"

Next, we need to specify which hardware we are using. Since I used a standard 8×32 display (also known as FC-16), I set the HARDWARE_TYPE to FC16_HW. The number of MAX7219 ICs in an 8×32 display is 4 so I set MAX_DEVICES to 4. Lastly, I defined to which pin the CS pin of the display is connected (output pin 3 in this case). See the section about display types for a more detailed explanation on how to set up other types of displays.

The statement #define is used to give a name to a constant value. The compiler will replace any references to this constant with the defined value when the program is compiled. So everywhere you mention CS_PIN, the compiler will replace it with the value 3 when the program is compiled.

// Define hardware type, size, and output pins:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3

After this, a new instance of the MD_Parola class is created with the function MD_Parola(). This function needs three parameters, the first is the hardware type, the second the CS pin, and the third the number of max devices connected.

Note that I have called the MD_Parola object 'myDisplay' but you can use other names as well. You will need to change ‘myDisplay’ to the new name in the rest of the sketch.

When you want to use software SPI instead of hardware SPI, you also need to define the data and clock output pins and pass these as parameters when setting up the display object.

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

// Setup for software SPI:
// #define DATAPIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, 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 display is cleared with the function displayClear().

void setup() {
  // Intialize the object:
  myDisplay.begin();
  // Set the intensity (brightness) of the display (0-15):
  myDisplay.setIntensity(0);
  // Clear the display:
  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 ‘Center’ is printed with myDisplay.print("Center"). 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 invert the display, i.e. LEDs normally on turn off and vice versa, with myDisplay.setInvert(true).

void loop() {
  myDisplay.setTextAlignment(PA_CENTER);
  myDisplay.print("Center");
  delay(2000);
  myDisplay.setTextAlignment(PA_LEFT);
  myDisplay.print("Left");
  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);
}

Scrolling text Arduino example code

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 in the MD_Parola library, which makes it super easy to create scrolling text effects. In the following examples, I will show you how to set this up, as well as how to use some of the other available text effects.

Scrolling text

You can copy the code below by clicking on the button in the top right corner of the code field.

/* Example code for scrolling text effect on 
   MAX7219 LED dot matrix display with Arduino. 
   More info: https://www.makerguides.com */

#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"

// Define hardware type, size, and output pins:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#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);

// Setup for software SPI:
// #define DATA_PIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, 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.displayText("Scrolling text", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}

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

How the code works

The first part of the code up to the end of the setup section is exactly the same as in the previous example. At the end of the setup section, we specify how we want to display the text with the function displayText(pText, align, speed, pause, effectIn, effectOut). This function takes 5 arguments.

The first parameter is the text string, in this case "Scrolling text".

The second argument sets the alignment of the text during the optional pause. You can use the same alignment options as in the previous example, i.e. PA_CENTER, PA_LEFT, or PA_RIGHT.

The third and fourth arguments set the speed of the animation and pause time respectively. The speed of the display is the time in milliseconds between animation frames. The lower this time the faster the animation. If you want to pause the text in between the in and out animation, you can set the pause time in milliseconds. I set it to zero so the text scrolls continuously.

Next, the in and out effects are specified. In this case I used PA_SCROLL_LEFT for both. See the example below for other text effects.

  myDisplay.displayText("Scrolling text", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);

In the loop section, you only need two functions to create a scrolling text display.

First, we use the function displayAnimate() in an if statement. This function animates the display using the currently specified text and animation parameters and returns true when the animation has finished. When the animation has finished, we reset the display with the function displayReset() so the text is displayed in a loop.

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

Other text effects

The library includes several other text effects that you can use:

  • PA_PRINT,
  • PA_SCAN_HORIZ,
  • PA_SCROLL_LEFT,
  • PA_WIPE,
  • PA_SCROLL_UP_LEFT,
  • PA_SCROLL_UP,
  • PA_OPENING_CURSOR,
  • PA_GROW_UP,
  • PA_MESH,
  • PA_SCROLL_UP_RIGHT,
  • PA_BLINDS,
  • PA_CLOSING,
  • PA_RANDOM,
  • PA_GROW_DOWN,
  • PA_SCAN_VERT,
  • PA_SCROLL_DOWN_LEFT,
  • PA_WIPE_CURSOR,
  • PA_DISSOLVE,
  • PA_OPENING,
  • PA_CLOSING_CURSOR,
  • PA_SCROLL_DOWN_RIGHT,
  • PA_SCROLL_RIGHT,
  • PA_SLICE,
  • PA_SCROLL_DOWN

The example code below steps through the different effect so you can see what they look like.

/*Example code for scrolling text and other text effects 
  on MAX7219 LED dot matrix display with Arduino. 
  More info: https://www.makerguides.com */

#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"

int i = 0;

textEffect_t texteffect[] =
{
  PA_PRINT,
  PA_SCAN_HORIZ,
  PA_SCROLL_LEFT,
  PA_WIPE,
  PA_SCROLL_UP_LEFT,
  PA_SCROLL_UP,
  PA_OPENING_CURSOR,
  PA_GROW_UP,
  PA_MESH,
  PA_SCROLL_UP_RIGHT,
  PA_BLINDS,
  PA_CLOSING,
  PA_RANDOM,
  PA_GROW_DOWN,
  PA_SCAN_VERT,
  PA_SCROLL_DOWN_LEFT,
  PA_WIPE_CURSOR,
  PA_DISSOLVE,
  PA_OPENING,
  PA_CLOSING_CURSOR,
  PA_SCROLL_DOWN_RIGHT,
  PA_SCROLL_RIGHT,
  PA_SLICE,
  PA_SCROLL_DOWN
};

// Define hardware type, size, and output pins:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#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);

// Setup for software SPI:
// #define DATA_PIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

void setup() {
  myDisplay.begin();
  myDisplay.setIntensity(0);
  myDisplay.setTextAlignment(PA_CENTER);
  myDisplay.setPause(1000);
  myDisplay.setSpeed(100);
  myDisplay.displayClear();
}

void loop() {
  if (myDisplay.displayAnimate()) {
    if (i < sizeof(texteffect)) {
      i++;
    }
    else {
      i = 0;
    }
    myDisplay.displayText("Hello", myDisplay.getTextAlignment(), 
                          myDisplay.getSpeed(), myDisplay.getPause(), 
                          texteffect[i], texteffect[i]);
    myDisplay.displayReset();
  }
}

Text sprites

A relatively new function of the MD_Parola library is animated text sprites. In computer graphics, a sprite is a two-dimensional bitmap that is integrated into a larger scene (in this case, the matrix display).

A sprite is made up of a number of frames that run sequentially to make the animation on the display. Once the animation reaches the last frame it restarts from the first frame.

Note that I used an 8×64 matrix display for this example by connecting two 8×32 displays together (MAX_DEVICES is set to 8).

/*Example code for sprite text effect on 
  MAX7219 LED dot matrix display with Arduino. 
  More info: https://www.makerguides.com */

#include "MD_Parola.h"
#include "MD_MAX72xx.h"
#include "SPI.h"

// Define hardware type, size, and output pins:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 8
#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);

// Setup for software SPI:
// #define DATA_PIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Sprite definitions:
const uint8_t F_PMAN1 = 6;
const uint8_t W_PMAN1 = 8;
const uint8_t PROGMEM pacman1[F_PMAN1 * W_PMAN1] =  // gobbling pacman animation
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
};

const uint8_t F_PMAN2 = 6;
const uint8_t W_PMAN2 = 18;
const uint8_t PROGMEM pacman2[F_PMAN2 * W_PMAN2] =  // pacman pursued by a ghost
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe,
};

const uint8_t F_WAVE = 14;
const uint8_t W_WAVE = 14;
const uint8_t PROGMEM wave[F_WAVE * W_WAVE] =  // triangular wave / worm
{
  0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10,
  0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20,
  0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40,
  0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
  0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
  0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10,
  0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08,
  0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04,
  0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02,
  0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02,
  0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04,
  0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x08,
};

const uint8_t F_ROLL1 = 4;
const uint8_t W_ROLL1 = 8;
const uint8_t PROGMEM roll1[F_ROLL1 * W_ROLL1] =  // rolling square
{
  0xff, 0x8f, 0x8f, 0x8f, 0x81, 0x81, 0x81, 0xff,
  0xff, 0xf1, 0xf1, 0xf1, 0x81, 0x81, 0x81, 0xff,
  0xff, 0x81, 0x81, 0x81, 0xf1, 0xf1, 0xf1, 0xff,
  0xff, 0x81, 0x81, 0x81, 0x8f, 0x8f, 0x8f, 0xff,
};

const uint8_t F_ROLL2 = 4;
const uint8_t W_ROLL2 = 8;
const uint8_t PROGMEM roll2[F_ROLL2 * W_ROLL2] =  // rolling octagon
{
  0x3c, 0x4e, 0x8f, 0x8f, 0x81, 0x81, 0x42, 0x3c,
  0x3c, 0x72, 0xf1, 0xf1, 0x81, 0x81, 0x42, 0x3c,
  0x3c, 0x42, 0x81, 0x81, 0xf1, 0xf1, 0x72, 0x3c,
  0x3c, 0x42, 0x81, 0x81, 0x8f, 0x8f, 0x4e, 0x3c,
};

const uint8_t F_LINES = 3;
const uint8_t W_LINES = 8;
const uint8_t PROGMEM lines[F_LINES * W_LINES] =  // spaced lines
{
  0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
  0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
  0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
};

const uint8_t F_ARROW1 = 3;
const uint8_t W_ARROW1 = 10;
const uint8_t PROGMEM arrow1[F_ARROW1 * W_ARROW1] =  // arrow fading to center
{
  0x18, 0x3c, 0x7e, 0xff, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00,
  0x18, 0x3c, 0x7e, 0xff, 0x00, 0x7e, 0x00, 0x00, 0x18, 0x00,
  0x18, 0x3c, 0x7e, 0xff, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18,
};

const uint8_t F_ARROW2 = 3;
const uint8_t W_ARROW2 = 9;
const uint8_t PROGMEM arrow2[F_ARROW2 * W_ARROW2] =  // arrow fading to outside
{
  0x18, 0x3c, 0x7e, 0xe7, 0x00, 0x00, 0xc3, 0x00, 0x00,
  0x18, 0x3c, 0x7e, 0xe7, 0xe7, 0x00, 0x00, 0x81, 0x00,
  0x18, 0x3c, 0x7e, 0xe7, 0x00, 0xc3, 0x00, 0x00, 0x81,
};

const uint8_t F_SAILBOAT = 1;
const uint8_t W_SAILBOAT = 11;
const uint8_t PROGMEM sailboat[F_SAILBOAT * W_SAILBOAT] =  // sail boat
{
  0x10, 0x30, 0x58, 0x94, 0x92, 0x9f, 0x92, 0x94, 0x98, 0x50, 0x30,
};

const uint8_t F_STEAMBOAT = 2;
const uint8_t W_STEAMBOAT = 11;
const uint8_t PROGMEM steamboat[F_STEAMBOAT * W_STEAMBOAT] =  // steam boat
{
  0x10, 0x30, 0x50, 0x9c, 0x9e, 0x90, 0x91, 0x9c, 0x9d, 0x90, 0x71,
  0x10, 0x30, 0x50, 0x9c, 0x9c, 0x91, 0x90, 0x9d, 0x9e, 0x91, 0x70,
};

const uint8_t F_HEART = 5;
const uint8_t W_HEART = 9;
const uint8_t PROGMEM heart[F_HEART * W_HEART] =  // beating heart
{
  0x0e, 0x11, 0x21, 0x42, 0x84, 0x42, 0x21, 0x11, 0x0e,
  0x0e, 0x1f, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x1f, 0x0e,
  0x0e, 0x1f, 0x3f, 0x7e, 0xfc, 0x7e, 0x3f, 0x1f, 0x0e,
  0x0e, 0x1f, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x1f, 0x0e,
  0x0e, 0x11, 0x21, 0x42, 0x84, 0x42, 0x21, 0x11, 0x0e,
};

const uint8_t F_INVADER = 2;
const uint8_t W_INVADER = 10;
const uint8_t PROGMEM invader[F_INVADER * W_INVADER] =  // space invader
{
  0x0e, 0x98, 0x7d, 0x36, 0x3c, 0x3c, 0x36, 0x7d, 0x98, 0x0e,
  0x70, 0x18, 0x7d, 0xb6, 0x3c, 0x3c, 0xb6, 0x7d, 0x18, 0x70,
};

const uint8_t F_ROCKET = 2;
const uint8_t W_ROCKET = 11;
const uint8_t PROGMEM rocket[F_ROCKET * W_ROCKET] =  // rocket
{
  0x18, 0x24, 0x42, 0x81, 0x99, 0x18, 0x99, 0x18, 0xa5, 0x5a, 0x81,
  0x18, 0x24, 0x42, 0x81, 0x18, 0x99, 0x18, 0x99, 0x24, 0x42, 0x99,
};

const uint8_t F_FBALL = 2;
const uint8_t W_FBALL = 11;
const uint8_t PROGMEM fireball[F_FBALL * W_FBALL] =  // fireball
{
  0x7e, 0xab, 0x54, 0x28, 0x52, 0x24, 0x40, 0x18, 0x04, 0x10, 0x08,
  0x7e, 0xd5, 0x2a, 0x14, 0x24, 0x0a, 0x30, 0x04, 0x28, 0x08, 0x10,
};

const uint8_t F_CHEVRON = 1;
const uint8_t W_CHEVRON = 9;
const uint8_t PROGMEM chevron[F_CHEVRON * W_CHEVRON] =  // chevron
{
  0x18, 0x3c, 0x66, 0xc3, 0x99, 0x3c, 0x66, 0xc3, 0x81,
};

const uint8_t F_WALKER = 5;
const uint8_t W_WALKER = 7;
const uint8_t PROGMEM walker[F_WALKER * W_WALKER] =  // walking man
{
  0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68,
  0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0,
  0x00, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40,
  0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00,
  0x00, 0x10, 0x6e, 0x3e, 0xb8, 0xe8, 0x00,
};

void setup() {
  myDisplay.begin();
  myDisplay.setIntensity(0);
  myDisplay.displayClear();
  myDisplay.setSpriteData(pacman2, W_PMAN2, F_PMAN2, pacman2, W_PMAN2, F_PMAN2);
  myDisplay.displayText("Parola sprites", PA_CENTER, 50, 1000, PA_SPRITE, PA_SPRITE);
}

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

How the code works

After setting up the display like before, the text sprites are defined.

Two constants are used to define the sprite, one for the width (number of bytes) data for one sprite and the other for the number of frames contained in the animation. The total number of bytes required is the width * number of frames. Note that the sprite data is stored in PROGMEM to save RAM space.

Each row of the array is made up of hexadecimal numbers that set which LEDs need to light up in each column of the sprite.

The example includes many different sprite definitions, which you can also find in one of the examples that come with the library.

// Sprite definitions:
const uint8_t F_PMAN1 = 6;
const uint8_t W_PMAN1 = 8;
const uint8_t PROGMEM pacman1[F_PMAN1 * W_PMAN1] =  // gobbling pacman animation
{
  0x00, 0x81, 0xc3, 0xe7, 0xff, 0x7e, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c,
  0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c,
};

In the setup, the function setSpriteData(inData, inWidth, inFrames, outData, outWidth, outFrames) is used to set up user data needed so that the library can display the sprite when the PA_SPRITE animation type is selected in the displayText() function.

You can select any of the predefined sprites, in this case I used pacman2 (pacman pursued by a ghost).

  myDisplay.setSpriteData(pacman2, W_PMAN2, F_PMAN2, pacman2, W_PMAN2, F_PMAN2);
  myDisplay.displayText("Parola sprites", PA_CENTER, 50, 1000, PA_SPRITE, PA_SPRITE);

The loop section is the same as before.

Conclusion

In this article, I have shown you how you can use a MAX7219 LED dot matrix display with Arduino. We looked at the basics of printing text, scrolling text, other text effects, and text sprites. There still are some less frequently used functions in the MD_Parola library that I haven't covered in this tutorial but you can check those out in the MD_Parola documentation on GitHub.

We also haven't talked about the fact that the MD_Parola library can divide a display into multiple zones that run different animations. Read the post Coordinate Parola Zone Animations on MAX7219 Display and Parola A to Z – Multi Zone Displays for more information on that.

Finally, if you want to chain different animation, switch between different animations by pressing buttons, or regulate the speed of the animation via an analog input have a look at the Control Parola Animations on MAX7219 LED Display tutorial, where we cover these use cases.

If you have any questions, feel free to ask them in the comment section.

Happy tinkering!