MAX7219 Pantalla de matriz de puntos LED y Arduino Deja un comentario

MAX7219 Pantalla de matriz de puntos LED

En este tutorial, aprenderá a controlar una pantalla de matriz de puntos LED MAX7219 con Arduino. Hemos incluido un diagrama de cableado y muchos códigos de ejemplo. El código de este tutorial puede ser usado para pantallas de 8×8, 8×32, e incluso más grandes.

Para este tutorial, usaremos el MD_Parola en combinación con la biblioteca MD_MAX72XX de Arduino. Estas bibliotecas hacen que la visualización de texto en movimiento y otras animaciones sea muy fácil. En la primera parte de este artículo, cubriremos los fundamentos de la impresión de texto en la pantalla. A continuación, veremos el texto que se desplaza y otras animaciones de texto. Por último, te mostraremos cómo usar los sprites de texto.

Lo que vamos a necesitar

Qué es el controlador de LED MAX7219

El controlador de LED del MAX7219 puede usarse para controlar pantallas de 7 segmentos de hasta 8 dígitos, pantallas de gráficos de barras o 64 LEDs individuales. El driver se comunica con el Arduino a través de SPI por lo que sólo se necesitan tres cables para controlar la pantalla.

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

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

Voltaje 5 V
Controlador de pantalla MAX7219 x 4
Niveles de brillo 16
Dimensiones de la pantalla 32 x 128 x 15 mm
Pixeles 8×32, ⌀ 3 mm

Para más información, puede consultar la siguiente hoja de datos o datasheet de MAX7219 en este enlace.

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

El controlador de la pantalla LED del MAX7219 se comunica con el Arduino a través de SPI (Serial Peripheral Interface). Para aprender más sobre este protocolo de datos, por favor echa un vistazo a esta página en el sitio web de Arduino.

Con una interfaz SPI siempre hay un dispositivo maestro (el Arduino) que controla los dispositivos periféricos (también conocidos como esclavos). Puede controlar la pantalla ya sea a través de la interfaz SPI de hardware del microcontrolador AVR de Arduino o de tres pines digitales arbitrarios (SPI de software).

Los pines SPI de hardware (MOSI, MISO y SCK) están en un lugar específico en cada placa Arduino. Esta interfaz es más rápida que el uso de SPI por software, pero necesitará usar los siguientes pines de salida fijos:

Tabla MOSI MISO SCK Nivel
Arduino Uno 11 or ICSP-4 12 or ICSP-1 13 or ICSP-3 5 V
Arduino Mega 51 or ICSP-4 50 or ICSP-1 52 or 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

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

MAX7219 Conexiones de la pantalla de matriz de puntos LED

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

Si quieres utilizar el software SPI en su lugar, puedes conectar DIN, CS y CLK a cualquiera de los pines digitales del Arduino. Sólo tienes que especificar los números de pin en la configuración del código de Arduino (ver ejemplos a continuación).

Requisitos de potencia

La máxima potencia que el Arduino Uno puede entregar con seguridad cuando se alimenta de un USB es de alrededor de 400 mA a 5 V.

Instalación de las librerías MD_Parola y MD_MAX72XX Arduino

Para controlar la pantalla del MAX7219 usaremos dos impresionantes bibliotecas de Arduino creadas por Marco Colli de MajicDesigns. La librería MD_Parola puede ser usada para crear muchas animaciones de texto diferentes como el scrolling y efectos de texto sprite. Esta biblioteca depende de la biblioteca MD_MAX72XX que implementa las funciones de hardware de la matriz de LEDs.

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

  • Justificación de texto a la izquierda, a la derecha o en el centro
  • Desplazamiento de texto con efectos de entrada y salida
  • Controlar los parámetros de visualización y la velocidad de la animación
  • Múltiples pantallas virtuales (zonas) en cada cadena de módulos LED
  • Soporte para la interfaz SPI de hardware
  • 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 algunos excelentes tutoriales en su blog. El código fuente y la documentación de las bibliotecas se pueden encontrar aquí:

Puedes instalar las bibliotecas a través del Administrador de Bibliotecas del IDE de Arduino. Ve a Herramientas > Gestionar bibliotecas… o escriba Ctrl + Shift + I en Windows. El Administrador de Librerías abrirá y actualizará la lista de bibliotecas instaladas.

Diferentes tipos de pantallas de matriz de puntos LED

Hay muchos tipos y tamaños diferentes de pantallas de matriz de puntos LED MAX7219 disponibles en el mercado. La biblioteca MD_MAX72XX soporta casi todos estos displays, pero es necesario configurar la biblioteca correctamente para el tipo de matriz que se utiliza.

A continuación puede encontrar información sobre la conexión y configuración de los displays de matriz de puntos LED MAX7219 más comunes que puedes comprar en Amazon, AliExpress y eBay.

Módulo FC-16 8×8 u 8×32

Orientación y conexiones del módulo

Puede conectar fácilmente varios módulos de 8×8 u 8×32 para crear una pantalla más grande. Típicamente sueldo cabezales macho rectos en la parte trasera de los módulos y los conecto entre sí usando puentes. De esta manera puedes desmontarlos sin tener que desoldar ninguna conexió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 +------------------------+

Configuración del hardware en código Arduino

Al configurar la pantalla en su código de Arduino necesita configurar el HARDWARE_TYPE a FC16_HW y especificar el número de dispositivos que ha conectado. Una matriz de 8×8 cuenta como 1 dispositivo, por lo que si desea controlar un módulo de 8×32 necesita configurar MAX_DEVICES a 4 (una pantalla de 8×32 contiene 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);

Módulo genérico 8×8

Módulo genérico 8×8 - MAX7219 Pantalla de matriz de puntos LED y Arduinoanimacion print - MAX7219 Pantalla de matriz de puntos LED y Arduino

Este es un módulo de 8×8 montado en un PCB verde con el MAX7219 IC debajo de la matriz de LEDs. Se caracterizan por los conectores de 5 pines en los extremos cortos del PCB rectangular.

Orientación y conexiones del módulo

El módulo genérico debe orientarse con el MAX7219 IC en la parte superior. Se pueden conectar varios módulos juntos con algunos cables de puente cortos de hembra a hembra. Simplemente conecte todos los pines del lado DOUT del primer módulo al lado DIN del siguiente módulo.

      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

Configuración del hardware en el código Arduino

Para los módulos de visualización genéricos, es necesario establecer el HARDWARE_TYPE en GENERIC_HW. El resto de la configuración y MAX_DEVICES es la misma que para los módulos FC-16.

// 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);

Códigos de ejemplo de Arduino

A continuación encontrarás varios códigos de ejemplo que cubren las funciones básicas de la biblioteca MD_Parola Arduino. Después de cada ejemplo explicamos cómo funciona el código, así que deberías ser capaz de modificarlo para adaptarlo a tus necesidades. También puedes encontrar más ejemplos cuando vaya a Archivo > Ejemplos > MD_Parola en el IDE de Arduino, pero no incluyen ninguna explicación por lo que pueden ser un poco difíciles de seguir.

Código básico de ejemplo de Arduino para imprimir el texto

Con el código de ejemplo que se muestra a continuación, puedes imprimir el texto en la pantalla sin ninguna animación.

Puedes subir el código de ejemplo a tu Arduino a través del IDE de Arduino. Para este tutorial, hemos utilizado esta pantalla de matriz de puntos LED de 8×32 estándar, pero también puedes utilizar otros tipos y/o tamaños (véase la explicación del código a continuación).

Puedes copiar el código haciendo clic en el botón en la esquina superior derecha del campo de código.

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

// Include the required Arduino libraries:
#include 
#include 
#include 

// 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);
}

Debería ver la siguiente salida:

 

Cómo funciona el código

El primer paso es incluir todas las bibliotecas de Arduino necesarias. Como he mencionado antes, la biblioteca MD_MAX72XX implementa las funciones de hardware de la matriz de LEDs y la biblioteca MD_Parola los efectos de texto. También tendrá que incluir la biblioteca SPI, que viene preinstalada en el IDE de Arduino. Esta biblioteca se utiliza para la comunicación de la Interfaz Periférica Serial entre la pantalla y el Arduino.

// Include the required Arduino libraries:
#include 
#include 
#include 

A continuación, necesitamos especificar qué hardware estamos usando. Como hemos utilizado una pantalla estándar de 8×32 (también conocida como FC-16), hemos configurado el HARDWARE_TYPE a FC16_HW. El número de ICs de MAX7219 en una pantalla de 8×32 es 4, así que pusimos MAX_DEVICES en 4. Por último, definimos a qué clavija se conecta la clavija CS de la pantalla (la clavija de salida 3 en este caso). Mira la sección, más arriba, sobre tipos de pantalla para una explicación más detallada sobre cómo configurar otros tipos de pantallas.

La instrucción #define se usa para dar un nombre a un valor constante. El compilador reemplazará cualquier referencia a esta constante con el valor definido cuando el programa sea compilado. Así que en cualquier lugar que se mencione CS_PIN, el compilador la reemplazará con el valor 3 cuando se compila el programa.

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

Después de esto, se crea una nueva instancia de la clase MD_Parola con la función MD_Parola(). Esta función necesita tres parámetros, el primero es el tipo de hardware, el segundo el pin CS, y el tercero el número máximo de dispositivos conectados.

Ten en cuenta que he llamado al objeto MD_Parola ‘myDisplay’ pero también puedes usar otros nombres. Tendrás que cambiar ‘myDisplay’ por el nuevo nombre en el resto del código.

Si deseas utilizar SPI de software en lugar de SPI de hardware, también deberá definir los pines de salida de datos y de reloj y pasarlos como parámetros al configurar el objeto display.

// 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);

En la sección de configuración del código, primero inicializamos el objeto con la función begin(). El brillo de la pantalla se puede ajustar con la función setIntensity(). Se puede introducir un valor entre 0 (brillo mínimo) y 15 (brillo máximo). La pantalla se borra con la función 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();
}

En la sección de bucle del código, primero establecemos la alineación del texto a imprimir con la función setTextAlignment(). Puedes alinear el texto con PA_LEFT, PA_CENTER, y PA_RIGHT respectivamente.

A continuación, la cadena ‘Center’ se imprime con myDisplay.print(“Center”). Observe que debe colocar comillas (” “) alrededor del texto ya que estamos imprimiendo una cadena de texto. Cuando quieras imprimir números, no es necesario poner comillas. Por ejemplo, myDisplay.print(1234). Puedes invertir la pantalla, es decir, los LED normalmente encendidos se apagan y viceversa, con 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);
}

Desplazamiento de texto, Código de ejemplo de Arduino

Cuando se quiere imprimir un mensaje en una pantalla de matriz de puntos, a menudo se encuentra que la pantalla es demasiado pequeña para que quepa todo el mensaje. La solución está en la biblioteca MD_Parola, que facilita enormemente la creación de efectos de texto en movimiento. En los siguientes ejemplos, le mostraré cómo configurarla, así como cómo utilizar algunos de los otros efectos de texto disponibles.

Puedes copiar el código que aparece a continuación haciendo clic en el botón de la esquina superior derecha del campo de código.

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

// Include the required Arduino libraries:
#include 
#include 
#include 

// 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();
  myDisplay.displayText("Scrolling text", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}

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

Cómo funciona el código

La primera parte del código hasta el final de la sección de configuración es exactamente la misma que en el ejemplo anterior. Al final de la sección de configuración, especificamos cómo queremos mostrar el texto con la función displayText(pText, align, speed, pause, effectIn, effectOut). Esta función toma 5 argumentos.

El primer parámetro es la cadena de texto, en este caso “Scrolling text”.

El segundo argumento establece la alineación del texto durante la pausa opcional. Puedes usar las mismas opciones de alineación que en el ejemplo anterior, es decir, PA_CENTER, PA_LEFT, or PA_RIGHT.

El tercer y cuarto argumento establecen la velocidad de la animación y el tiempo de pausa respectivamente. La velocidad de la visualización es el tiempo en milisegundos entre los cuadros de la animación. Cuanto menor sea este tiempo, más rápida será la animación. Si quieres hacer una pausa en el texto entre la animación de entrada y la de salida, puedes establecer el tiempo de pausa en milisegundos. Lo hemos puesto a cero para que el texto se desplace continuamente.

A continuación, se especifican los efectos de entrada y salida. En este caso usé PA_SCROLL_LEFT para ambos. Vea el ejemplo a continuación para otros efectos de texto.

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

En la sección de loop o bucle, sólo se necesitan dos funciones para crear una pantalla de texto en movimiento.

Primero, usamos la función displayAnimate() en una sentencia if. Esta función anima la visualización utilizando los parámetros de texto y animación especificados actualmente y devuelve true cuando la animación ha terminado. Cuando la animación ha terminado, reiniciamos la visualización con la función displayReset() para que el texto se muestre en bucle.

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

Otros efectos de texto:

La biblioteca incluye varios otros efectos de texto que puedes usar:

  • 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

El código de ejemplo que se muestra a continuación muestra los diferentes efectos para que puedas ver cómo se ven.

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

// Include the required Arduino libraries:
#include 
#include 
#include 

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 DATAPIN 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();
  }
}

Sprites de texto

Una función relativamente nueva de la biblioteca MD_Parola son los sprites de texto animados. En los gráficos de ordenador, un sprite es un mapa de bits bidimensional que se integra en una escena más grande (en este caso, la pantalla de la matriz).

Un sprite se compone de un número de cuadros que se ejecutan secuencialmente para hacer la animación en la pantalla. Una vez que la animación llega al último cuadro, se reinicia desde el primer cuadro.

Observa que usamos un display de matriz 8×64 para este ejemplo conectando dos displays de 8×32 juntos (MAX_DEVICES está ajustado a 8).

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

// Include the required Arduino libraries:
#include 
#include 
#include 

// 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 DATAPIN 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();
  }
}

Cómo funciona el código

Después de configurar la pantalla como antes, se definen los sprites de texto.

Se utilizan dos constantes para definir el sprite, una para el ancho (número de bytes) de los datos de un sprite y la otra para el número de frames contenidos en la animación. El número total de bytes necesarios es el ancho * número de frames. Ten en cuenta que los datos del sprite se almacenan en el PROGMEM para ahorrar espacio en la RAM.

Cada fila de la matriz está compuesta por números hexadecimales que establecen qué LEDs deben encenderse en cada columna del sprite.

El ejemplo incluye muchas definiciones diferentes de sprites, que también puedes encontrar en uno de los ejemplos que vienen con la biblioteca.

// 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,
};

En la configuración, la función setSpriteData(inData, inWidth, inFrames, outData, outWidth, outFrames) se usa para configurar los datos de usuario necesarios para que la librería pueda mostrar el sprite cuando se selecciona el tipo de animación PA_SPRITE en la función displayText().

Se puede seleccionar cualquiera de los sprites predefinidos, en este caso utilizamos pacman2 (pacman perseguido por un fantasma).

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

La sección de bucle es la misma que antes.

Más ejemplos de efectos con Parola:

Conclusión

En este artículo, te hemos mostrado cómo puedes usar una pantalla de matriz de puntos LED MAX7219 con Arduino. Hemos visto los fundamentos de la impresión de texto, el desplazamiento de texto, otros efectos de texto y los sprites de texto. Todavía hay algunas funciones de uso menos frecuente en la biblioteca MD_Parola que no hemos cubierto en este tutorial, pero podéis comprobarlas en la documentación de MD_Parola en GitHub.

Esperamos que hayas encontrado este tutorial útil e informativo. Si es así, por favor compártelo con un amigo al que también le guste la electrónica.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Enviar Whatsapp
Hola 👋
¿En qué podemos ayudarte?