Skip to Content

MAX7219 LED pantalla de matriz de puntos Arduino tutorial

MAX7219 LED pantalla de matriz de puntos Arduino tutorial

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

For this tutorial, I will be using the MD_Parola in combination with the MD_MAX72XX Arduino library. These libraries make displaying scrolling text and other animations super easy. In the first part of this article, I will cover the basics of printing text on the display. Next, we will look at scrolling text and other text animations. Lastly, I will show you how to use text sprites.

Si quiere saber más sobre otros tipos de expositores, consulte los siguientes artículos:

Artículos recomendados

Si tiene alguna pregunta, deje un comentario a continuación.

Suministros

Componentes de hardware

Pantalla de matriz de puntos LED de 8×32 MAX7219× 1Amazon
8x8-MAX7219-LED-dot-matrix-displayPantalla de matriz de puntos LED 8×8 MAX7219 (alternativa)× 1Amazon
generic-MAX7219-8x8-LED-dot-matrix-displayPantalla genérica de matriz de puntos LED 8×8 MAX7219 (alternativa)× 1Amazon
Arduino Uno Rev 3Arduino Uno Rev3× 1Amazon
Cables de puente (macho a hembra)× 4Amazon
Cable USB tipo A/B× 1Amazon
Cabezales macho~ 20Amazon
Puentes~ 20Amazon

Software

Arduino IDEArduino IDE

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com. As an Amazon Associate we earn from qualifying purchases.

Acerca del controlador LED MAX7219

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

Dado que el MAX7219 puede controlar un máximo de 64 LEDs, el tamaño máximo de pantalla de matriz de puntos que puede controlar es de 8×8 píxeles. Sin embargo, puedes conectar en cadena múltiples controladores y matrices y controlar fácilmente pantallas mucho más grandes como 8×32, 8×64, o incluso mayores. 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 puede encontrar las especificaciones de una pantalla típica de matriz de puntos LED MAX7219 de 8×32.

Especificaciones de la pantalla de matriz de puntos LED MAX7219

Tensión de funcionamiento5 V
Controlador de la pantallaMAX7219 x 4
Niveles de luminosidad16
Dimensiones de la pantalla32 x 128 x 15 mm
Píxeles8×32, ⌀ 3 mm
CosteComprobar el precio

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

Casi todas las pantallas que he usado en el pasado utilizaban una matriz de LEDs tipo 1088AS de 8×8. Puedes encontrar una hoja de datos de una de las empresas que las fabrican a continuación:

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

El controlador de la pantalla LED MAX7219 se comunica con el Arduino a través de SPI (Serial Peripheral Interface). Para saber más sobre este protocolo de datos, consulte 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). Puedes controlar la pantalla a través de la interfaz SPI del microcontrolador AVR de Arduino o de tres pines digitales arbitrarios (SPI por software).

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

Ubicación de los pines SPI del hardware

JuntaMOSIMISOSCKNivel
Arduino Uno11 o ICSP-412 o ICSP-113 o ICSP-35 V
Arduino Mega51 o ICSP-450 o ICSP-152 o ICSP-35 V
Arduino LeonardoICSP-4ICSP-1ICSP-35 V
Arduino DueSPI-4SPI1SPI-33.3 V
Arduino MKR100081093.3 V
Ubicación de los pines SPI del hardware en diferentes placas Arduino.

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

ICSPHeader
Fuente: Arduino.cc

Para controlar las pantallas del MAX7219 sólo es necesario realizar 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 de cada dispositivo que el maestro puede utilizar para activar y desactivar dispositivos específicos.

Puede conectar en cadena 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 he utilizado el pin 3 (ver tabla inferior).

El siguiente diagrama de cableado muestra cómo conectar la pantalla de matriz de puntos LED MAX7219 al Arduino. Tenga en cuenta que cuando se utiliza la biblioteca MD_Parola, es necesario 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, consulte la sección siguiente.

MAX7219-Pantalla de matriz de puntos LED con Arduino-Uno-diagrama de cableado-esquema
Pantalla de matriz de puntos LED MAX7219 con diagrama de cableado de Arduino

Las conexiones también se indican en la tabla siguiente:

Conexiones de la pantalla de matriz de puntos LED MAX7219

Pantalla MAX7219Arduino
VCC5 V
GNDGND
DIN11 (MOSI)
CS3 (SS)
CLK13 (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 los pines en la configuración del código de Arduino (ver ejemplos más abajo).

Requisitos de potencia

La potencia máxima que el Arduino Uno puede suministrar con seguridad cuando se alimenta desde el USB es de unos 400 mA a 5 V. Por lo tanto, si quieres controlar una pantalla grande, se aconseja utilizar una fuente de alimentación externa.

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

Para controlar la pantalla MAX7219 vamos a utilizar dos impresionantes bibliotecas Arduino creadas por Marco Colli de MajicDesigns. La biblioteca MD_Parola se puede utilizar para crear muchas animaciones de texto diferentes, como el desplazamiento y los efectos de texto sprite. Esta librería depende de la librería MD_MAX72XX que implementa las funciones de hardware de la matriz LED.

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

  • Justificación del texto a la izquierda, a la derecha o al centro
  • Desplazamiento de texto con efectos de entrada y salida
  • Controla 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
  • Compatibilidad con 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 librerías a través del gestor de librerías del IDE de Arduino. Ve a Herramientas > Gestionar Bibliotecas... o escribe Ctrl + Shift + I en Windows. El Gestor de Bibliotecas se abrirá y actualizará la lista de bibliotecas instaladas.

Instalar una librería Arduino paso 1 abrir Library Manager
Manage libraries

Busca 'MD_MAX72XX' y busca las librerías de majicDesigns. Seleccione la última versión y haga clic en instalar. Asegúrese de instalar tanto la biblioteca MD_MAX72XX como la biblioteca MD_Parola.

Instalación de una biblioteca Arduino paso 2 MD_Parola y MD_MAX72XX
Library manager

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 es compatible con casi todas estas pantallas, pero es necesario configurar la biblioteca correctamente para el tipo de matriz que se utiliza.

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

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

MAX7219 Dot led Matrix Display (Find at Amazon)

Esta es probablemente la pantalla MAX7219 más común que se puede encontrar. Normalmente viene como una matriz de LEDs de 8×8 u 8×32 y puedes comprarlos con diferentes colores de LEDs.

Orientación y conexiones de los módulos

Puedes conectar fácilmente varios módulos de 8×8 u 8×32 para crear una pantalla más grande. Yo suelo soldar cabezales macho rectos en la parte posterior de los módulos y conectarlos entre sí mediante puentes. De este modo, puedes desmontarlos sin tener que desoldar ninguna conexión.

Jumpers (Find at Amazon)

La pantalla está orientada con el lado DIN a la derecha. Tenga en cuenta que el texto serigrafiado en la parte posterior de la placa de circuito impreso podría 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 
         +------------------------+

Configuración del hardware en el código de Arduino

Cuando configure la pantalla en su código Arduino necesita establecer 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, así que si quieres controlar un módulo de 8×32 necesitas establecer 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

MAX7219 8x8 Module (Find at Amazon)

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

Orientación y conexiones de los módulos

El módulo genérico debe orientarse con el CI MAX7219 en la parte superior. Puedes conectar varios módulos juntos con algunos cables cortos de puente hembra a hembra. Simplemente conecta 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 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 de 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 el mismo 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 librería MD_Parola Arduino. Después de cada ejemplo explico cómo funciona el código para que puedas modificarlo según tus necesidades. También puedes encontrar más ejemplos si vas 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 texto

Con el código de ejemplo que se muestra a continuación se puede imprimir un texto en la pantalla sin ningún tipo de animación.

Puedes cargar el código de ejemplo en tu Arduino a través del IDE de Arduino. Para este tutorial, utilicé esta pantalla de matriz de puntos LED estándar de 8x32, pero también puedes utilizar otros tipos y/o tamaños (ver la explicación del código más abajo).

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

Debería ver la siguiente salida:

Text alignment

Cómo funciona el código

El primer paso es incluir todas las librerías 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 necesitarás incluir la librería SPI, que viene preinstalada en el IDE de Arduino. Esta biblioteca se utiliza para la comunicación de la interfaz periférica en serie entre la pantalla y el Arduino.

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

A continuación, tenemos que especificar el hardware que estamos utilizando. Como usé una pantalla estándar de 8×32 (también conocida como FC-16), establecí el HARDWARE_TYPE como FC16_HW. El número de ICs MAX7219 en un display de 8×32 es de 4 por lo que establecí MAX_DEVICES a 4. Por último, definí a qué pin se conecta el pin CS del display (pin de salida 3 en este caso). Vea la sección sobre tipos de pantallas para una explicación más detallada sobre cómo configurar otros tipos de pantallas.

La declaración #define se utiliza para dar un nombre a un valor constante. El compilador sustituirá cualquier referencia a esta constante por el valor definido cuando se compile el programa. Por lo tanto, en todos los casos en los que se menciona CS_PINel compilador lo sustituirá por el valor 3 al compilar 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 de dispositivos máximos conectados.

Ten en cuenta que he llamado al objeto MD_Parola 'miPantalla' pero puedes usar otros nombres también. Tendrás que cambiar 'miPantalla' por el nuevo nombre en el resto del sketch.

Si quieres utilizar el SPI por software en lugar del SPI por hardware, también tienes que definir los pines de salida de datos y de reloj y pasarlos como parámetros cuando configures el objeto de visualización.

// 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(). 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 a la izquierda, al centro y a la derecha con PA_LEFT, PA_CENTER y PA_RIGHT respectivamente.

A continuación, se imprime la cadena 'Centro' con myDisplay.print("Center"). Tenga en cuenta que debe colocar comillas (" ") alrededor del texto, ya que estamos imprimiendo un cadena de texto. Si desea imprimir números, no es necesario poner comillas. Por ejemplo myDisplay.print(1234). Se puede invertir la visualización, es decir, los LEDs 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 quiera imprimir un mensaje en una pantalla de matriz de puntos, a menudo encontrará que la pantalla es demasiado pequeña para que quepa todo el mensaje. La solución está en la biblioteca MD_Parola, que hace que sea súper fácil crear efectos de desplazamiento de texto. En los siguientes ejemplos, le mostraré cómo configurar esto, así como la forma de utilizar algunos de los otros efectos de texto disponibles.

Scrolling text

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

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 "Texto de desplazamiento".

El segundo argumento establece la alineación del texto durante la pausa opcional. Puede utilizar las mismas opciones de alineación que en el ejemplo anterior, es decir, PA_CENTER, PA_LEFT o 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 cuadros de animación. Cuanto menor sea este tiempo, más rápida será la animación. Si quieres pausar el texto entre la animación de entrada y salida, puedes establecer el tiempo de pausa en milisegundos. Yo lo puse a cero para que el texto se desplace continuamente.

A continuación se especifican los efectos de entrada y salida. En este caso he utilizado PA_SCROLL_LEFT para ambos. Vea el ejemplo de abajo para otros efectos de texto.

  myDisplay.displayText("Texto de desplazamiento", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);

En la sección de bucle, sólo necesitas dos funciones para crear una pantalla de texto desplazable.

En primer lugar, utilizamos la función displayAnimate() en un if declaración. Esta función anima la pantalla utilizando el texto y los parámetros de animación actualmente especificados y devuelve true cuando la animación ha terminado. Cuando la animación ha terminado, reiniciamos la pantalla con la función displayReset() para que el texto se muestre en un bucle.

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

Otros efectos de texto

La biblioteca incluye otros efectos de texto que puede utilizar:

  • 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 recorre los diferentes efectos para que puedas ver cómo son.

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

Sprites de texto

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

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

Tenga en cuenta que he utilizado una pantalla matricial de 8×64 para este ejemplo, conectando dos pantallas de 8×32 juntas (MAX_DEVICES está ajustado a 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();
  }
}

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 los datos de anchura (número de bytes) de un sprite y la otra para el número de fotogramas que contiene la animación. El número total de bytes necesarios es la anchura * número de fotogramas. Tenga en cuenta que los datos del sprite se almacenan en PROGMEM para ahorrar espacio en la memoria RAM.

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

El ejemplo incluye muchas definiciones de sprites diferentes, 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 utiliza para configurar los datos de usuario necesarios para que la biblioteca pueda mostrar el sprite cuando se selecciona el tipo de animación PA_SPRITE en el displayText() función.

Puedes seleccionar cualquiera de los sprites predefinidos, en este caso he utilizado 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 del bucle es la misma que antes.

Conclusión

En este artículo, te he mostrado cómo puedes utilizar 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 he cubierto en este tutorial, pero se puede comprobar en la documentación MD_Parola en GitHub.

Espero que este tutorial te haya resultado útil e informativo. Si lo has hecho, ¡compártelo con un amigo al que también le guste la electrónica y hacer cosas!

Me encantaría saber qué proyectos planeas construir (o ya has construido) con esta pantalla. Si tienes alguna pregunta, sugerencia, o si crees que faltan cosas en este tutorial, por favor deja un comentario abajo.

Tenga en cuenta que los comentarios son retenidos por la moderación para evitar el spam.

Licencia Creative Commons

Glen Lewis

Monday 11th of December 2023

Hi Guys I am using “MAX7219 LED dot 8x8 matrix display Arduino” x 8 Is it possible to have 2 x (separate) pieces of data displayed at the same time? its for a scoreboard so score 1 displayed Left justified and score 2 displayed Right justified (at the same time). I have already built the scoreboard and now I want to display the final info to a larger scoreboard through a Bluetooth connection (Serial) as I plan to run it through Bluetooth i don't think I could use 2 separate 8x8x4 displays?? any pointers and coding help would be greatly appreciated Kind regards Glen

Siggi.M

Friday 29th of March 2024

@Stefan Maetschke, Hallo Stefan, vielen Dank für die super schnelle Antwort. Die Tips sind große Klasse. Ich werde das ausprobieren und bei Erfolg Dir schreiben. Viele Grüße Siggi

Siggi.M

Thursday 28th of March 2024

@Stefan Maetschke, Hallo Stefan, ich habe mein Programm fertig. Die 8x32 LED-Matrix und das ESP32 Modul ist in einem LGB-Wagen (selbst kreiert) eingebaut. Die Steuerung erfolgt über Infrarot mit einer Infrarotfernbedienung. Damit kann ich die verschiedenen Animationen anzeigen lassen. Dabei ist auch eine Temperaturanzeige mit dem DHT11 . Insgesamt 8 Animationen plus Temperatur und ein "default" -Wert. Alles funktioniert einwandfrei. Ein Video vom LGB-Wagen könnte ich Dir schicken, wenn ich Deine email-Adresse hätte.

Nun habe ich eine Frage zur "loop"-Schleife. Wie kann ich mehrere Animationen automatisch nacheinander ablaufen lassen (also ohne Infrarotauswahl)? Hast Du vielleicht einen Tip?

Hier mein jetziger code: Vielleicht gibt es hier noch eine Vereinfachung? Danke schon mal im voraus und ein schönes Osterfest.

/* Laufschrift+Animation für LGB-INFO Wagen Hardware: ESP32-WROOM-DA Modul, DHT11, IR-VS1838 LED-Matrix 8x32 (4x(8x8)) Infrarotbedienung ESP32-WROOM-DA-Module 24.03.2024 - SiggiMu*/

#include #include #include #include //============================= #include #include //============================= // Define hardware type, size, and output pins: #define HARDWARE_TYPE MD_MAX72XX::FC16_HW #define MAX_DEVICES 4 // Setup for software SPI: #define CS_PIN 15 #define DATA_PIN 23 #define CLK_PIN 18 #define delay_t 50 // in milliseconds //======für Temperaturanzeige================================ #define SPEED_TIME 75 // Speed of the transition #define PAUSE_TIME 0 #define MAX_MESG 20 #define DHTPIN 25 // These are for the temperature6 #define DHTTYPE DHT11 #define TIMEDHT 1000 //------für Temperaturanzeige---------------------------------------------------------- char szTime[9]; // mm:ss\0 char szMesg[MAX_MESG + 1] = ""; float celsius; uint8_t degC[] = { 6, 3, 3, 56, 68, 68, 68 }; // Deg C uint8_t clear = 0x00; uint32_t timerDHT = TIMEDHT; DHT dht(DHTPIN, DHTTYPE); uint8_t decToBcd(uint8_t value) {return ((value / 10 * 16) + (value % 10));} //======Infrarot und extra LED================================ const int RECV_PIN = 36; IRrecv irrecv(RECV_PIN); decode_results results; int ircode = 0; int ircodex = 0; const int bluePin = 2; bool LEDstatus=false; //============================================================ MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay0 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay1 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay2 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay3 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay4 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay5 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay6 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay8 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); MD_Parola myDisplay9 = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); //=======Static-Bilder face=Smiley arrow=Pfeil================= byte herz[8] = {0xc6, 0x129, 0x111, 0x101, 0x82, 0x44, 0x28, 0x10}; byte face[8] = {0x3C, 0x42, 0xA5, 0x81, 0xA5, 0x99, 0x42, 0x3C}; byte face2[8] = {0x00, 0x24, 0x24, 0x24, 0x00, 0x42, 0x3C, 0x00}; byte arrow[8] = {0x18, 0x0C, 0x06, 0xFF, 0xFF, 0x06, 0x0C, 0x18}; byte leerz[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //=========================================================== const uint8_t F_LOK = 5; const uint8_t W_LOK = 32; const uint8_t PROGMEM lok[F_LOK * W_LOK] = // Lokomotive, Wagen, 2 Walker { 0x78, 0xcc, 0xcb, 0x48, 0x4f, 0xc9, 0xc9, 0x7f, 0x20, 0x7f, 0xc9, 0xc9, 0x4f, 0x49, 0xcf, 0xc9, 0x7f, 0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68, 0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68, 0x00, 0x78, 0xcc, 0xcb, 0x48, 0x4f, 0xc9, 0xc9, 0x7f, 0x20, 0x7f, 0xc9, 0xc9, 0x4f, 0x49, 0xcf, 0xc9, 0x7f, 0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0, 0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0, 0x00, 0x78, 0x48, 0x8a, 0x48, 0x4f, 0x49, 0x89, 0x7f, 0x20, 0x7f, 0xc9, 0xc9, 0x4f, 0x49, 0xcf, 0xc9, 0x7f, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40, 0x00, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40, 0x00, 0x00, 0x78, 0xcc, 0xcb, 0x48, 0x4f, 0xc9, 0xc9, 0x7f, 0x20, 0x7f, 0xc9, 0xc9, 0x4f, 0x49, 0xcf, 0xc9, 0x7f, 0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x6e, 0x3e, 0xb8, 0xe8, 0x00, 0x00, 0x10, 0x6e, 0x3e, 0xb8, 0xe8, 0x00, 0x00, }; //=========================================================== const uint8_t F_WALKER = 5; const uint8_t W_WALKER = 19; const uint8_t PROGMEM walker[F_WALKER * W_WALKER] = // walking man, 2 Walker { 0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x77, 0x1f, 0x1c, 0x94, 0x68, 0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xee, 0x3e, 0x38, 0x28, 0xd0, 0x00, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xfe, 0x38, 0x28, 0x40, 0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0xbe, 0xf8, 0x00, }; //============================================================ 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_PMAN2 = 6; const uint8_t W_PMAN2 = 19; 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, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe, 0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe, 0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe, 0x24, 0x66, 0xe7, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe, 0x00, 0x42, 0xe7, 0xe7, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7b, 0xf3, 0x7f, 0xfb, 0x73, 0xfe, }; //============================================================ 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_HASE = 2; const uint8_t W_HASE = 15; const uint8_t PROGMEM hase[F_HASE * W_HASE] = // hase { 0x00, 0x18, 0x34, 0xbe, 0xff, 0xfb, 0x78, 0xfc, 0xfc, 0xfc, 0xfc, 0x78, 0x30, 0x18, 0x00, 0x00, 0x0c, 0x1a, 0x5e, 0x7f, 0x7b, 0x79, 0xfc, 0xfc, 0xfc, 0xfc, 0x78, 0x70, 0x30, 0x00, }; // ========================================================== void setup() { //-------für Temperatur----------------------------------------------------------------------- Serial.begin(9600); dht.begin(); // initialize the DHT sensor

Wire.begin(); myDisplay9.begin(2); myDisplay9.setIntensity(2); myDisplay9.setInvert(false); myDisplay9.setZone(0, MAX_DEVICES - 4, MAX_DEVICES - 1); myDisplay9.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 0, PA_PRINT, PA_NO_EFFECT); myDisplay9.addChar('$', degC); dht.begin(); //---------------------------------------------------------------------------- irrecv.enableIRIn(); pinMode(bluePin, OUTPUT);

mx.begin(); mx.control(MD_MAX72XX::INTENSITY, 0); mx.clear(); //=================================================================================== myDisplay.begin(); myDisplay.setIntensity(2); myDisplay.displayClear(); myDisplay.displayText("Cool ", PA_CENTER, 100, 1000, PA_PRINT, PA_NO_EFFECT);

myDisplay0.begin(); myDisplay0.setIntensity(2); myDisplay0.displayClear(); myDisplay0.displayScroll("Push Taste", PA_CENTER, PA_SCROLL_LEFT, 100); //=================================================================================== myDisplay1.begin(); myDisplay1.setIntensity(2); myDisplay1.displayClear();

myDisplay2.begin(); myDisplay2.setIntensity(2); myDisplay2.displayClear();

myDisplay3.begin(); myDisplay3.setIntensity(2); myDisplay3.displayClear();

myDisplay4.begin(); myDisplay4.setIntensity(2); myDisplay4.displayClear();

myDisplay5.begin(); myDisplay5.setIntensity(2); myDisplay5.displayClear();

myDisplay6.begin(); myDisplay6.setIntensity(2); myDisplay6.displayClear();

myDisplay8.begin(); myDisplay8.setIntensity(2); myDisplay8.displayClear(); myDisplay8.displayText("Hallo ", PA_RIGHT, 100, 1000, PA_PRINT, PA_NO_EFFECT); // ("Text"", PA_CENTER, SCROLL_SPEED, PAUSE_TIME, PA_PRINT, PA_NO_EFFECT); //================================================================================

myDisplay1.setSpriteData(lok, W_LOK, F_LOK, lok, W_LOK, F_LOK); myDisplay1.displayText(" LGB ", PA_CENTER, 60, 4000, PA_SPRITE, PA_SPRITE);

myDisplay2.setSpriteData(walker, W_WALKER, F_WALKER, walker, W_WALKER, F_WALKER); myDisplay2.displayText(" Lauf! ", PA_CENTER, 60, 4000, PA_SPRITE, PA_SPRITE);

myDisplay3.setSpriteData(heart, W_HEART, F_HEART, heart, W_HEART, F_HEART); myDisplay3.displayText(" Herz ", PA_CENTER, 60, 4000, PA_SPRITE, PA_SPRITE);

myDisplay4.setSpriteData(pacman2, W_PMAN2, F_PMAN2, pacman2, W_PMAN2, F_PMAN2); myDisplay4.displayText(" Man? ", PA_CENTER, 60, 4000, PA_SPRITE, PA_SPRITE);

myDisplay5.setSpriteData(rocket, W_ROCKET, F_ROCKET, rocket, W_ROCKET, F_ROCKET); myDisplay5.displayText(" Rakete ", PA_CENTER, 60, 4000, PA_SPRITE, PA_SPRITE);

myDisplay6.setSpriteData(hase, W_HASE, F_HASE, hase, W_HASE, F_HASE); myDisplay6.displayText(" Ostern ", PA_CENTER, 60, 4000, PA_SPRITE, PA_SPRITE); } //======================================================================= void loop() { if (irrecv.decode(&results)){ irrecv.resume(); } ircode = (results.value); if (ircode == 16738455) {ircodex = 10 ;} //1 if (ircode == 16750695) {ircodex = 20 ;} //2 if (ircode == 16756815) {ircodex = 30 ;} //3 if (ircode == 16724175) {ircodex = 40 ;} //4 if (ircode == 16718055) {ircodex = 50 ;} //5 if (ircode == 16743045) {ircodex = 60 ;} //6 if (ircode == 16716015) {ircodex = 70 ;} //7 if (ircode == 16726215) {ircodex = 80 ;} //8 if (ircode == 16734885) {ircodex = 90 ;} //9 if (ircode == 16728765) {ircodex = 99 ;} //* if (ircode == 16730805) {ircodex = 100 ;} //0 if (ircode == 16732845) {ircodex = 110 ;} //# if (ircode == 16712445) {ircodex = 200 ;} //ok

switch(ircodex){ default: digitalWrite(bluePin, LOW); if (myDisplay0.displayAnimate()){ myDisplay0.displayReset();} delay(10); //ircodex = 10; break; case 10: digitalWrite(bluePin, HIGH); if (myDisplay1.displayAnimate()){ myDisplay1.displayReset();} break; case 20: digitalWrite(bluePin, HIGH); if (myDisplay2.displayAnimate()){ myDisplay2.displayReset();} break; case 30: digitalWrite(bluePin, HIGH); if (myDisplay3.displayAnimate()){ myDisplay3.displayReset();} break; case 40: digitalWrite(bluePin, HIGH); if (myDisplay4.displayAnimate()){ myDisplay4.displayReset();} break; case 50: digitalWrite(bluePin, HIGH); if (myDisplay5.displayAnimate()){ myDisplay5.displayReset();} break; case 60: digitalWrite(bluePin, HIGH); if (myDisplay6.displayAnimate()){ myDisplay6.displayReset();} break; case 80: digitalWrite(bluePin, LOW); myDisplay8.displayReset(); if (myDisplay8.displayAnimate()){ myDisplay8.displayReset();} delay(500); Zeichen2(); delay(2000); ircodex=100; break; case 99: digitalWrite(bluePin, HIGH); if (myDisplay8.displayAnimate()){ myDisplay8.displayReset();} delay(500); Zeichen2(); delay(3000); if (myDisplay.displayAnimate()){ myDisplay.displayReset();} delay(500); Zeichen12(); delay(3000); ircodex=100; break; case 110: digitalWrite(bluePin, LOW); myDisplay.displayReset(); if (myDisplay.displayAnimate()){ myDisplay.displayReset();} delay(500); Zeichen12(); delay(2000); ircodex = 100; break; case 100: digitalWrite(bluePin, LOW); myDisplay.displayClear(); myDisplay0.displayClear(); myDisplay1.displayClear(); myDisplay2.displayClear(); myDisplay3.displayClear(); myDisplay4.displayClear(); myDisplay5.displayClear(); myDisplay6.displayClear(); myDisplay8.displayClear(); myDisplay9.displayClear(); ircodex = 0; break; case 200: int i; for (int i=0;i<10;i++){ float tempC = dht.readTemperature(); Serial.println(tempC); tempC = (tempC-2); celsius = tempC; static uint32_t lastTime = 0; // Memory (ms) static uint8_t display = 0; // Current display mode static bool flasher = false; // Seconds passing flasher getTemperature(); myDisplay9.setIntensity(1); myDisplay9.displayAnimate(); myDisplay9.setPause(0, 1000); myDisplay9.setTextEffect(0, PA_NO_EFFECT, PA_NO_EFFECT); dtostrf(celsius, 3, 1, szMesg); strcat(szMesg, "$"); myDisplay9.displayReset(0); // Rest zone zero delay(2000); Serial.println (i); if (i == 8) { break; ircodex = 10; } break; } } } //=============Funktionen======================================================= void getTemperature() { if ((millis() - timerDHT) > TIMEDHT) { // Wait for a time between measurements timerDHT = millis(); // Update the timer celsius = dht.readTemperature(); } } //------------------------------------------------------------------------------ void Zeichen1() { for (int i = 0; i <= 7; i++) { mx.setRow(3, 3, i, herz[i]); //mx.setRow(0, 0, i, herz[i]); } delay(delay_t); } //------------------------------------------------------------------------------ void Zeichen2() { for (int i = 0; i <= 7; i++) { mx.setRow(3, 3, i, face[i]); //mx.setRow(1, 1, i, face[i]); } delay(delay_t); } //------------------------------------------------------------------------------ void Zeichen3() { for (int i = 0; i <= 7; i++) { mx.setRow(2, 2, i, face2[i]); } delay(delay_t); } //------------------------------------------------------------------------------ void Zeichen4() { for (int i = 0; i <= 7; i++) { mx.setRow(3, 3, i, arrow[i]); } delay(delay_t); } //------------------------------------------------------------------------------ void Zeichen11() { for (int i = 0; i <= 7; i++) { mx.setRow(3, 3, i, leerz[i]); } delay(delay_t); } //------------------------------------------------------------------------------ void Zeichen12() { for (int i = 0; i <= 7; i++) { mx.setRow(0, 0, i, face[i]); } delay(delay_t); } //------------------------------------------------------------------------------

Stefan Maetschke

Monday 18th of December 2023

It's a bit tricky to answer, but you probably want to avoid trying to "display 2 x (separate) pieces of data at the same time". The easiest way is probably to display the two data pieces together and do the left and right justification yourself.

Siggi.M

Monday 25th of September 2023

Hello, the tutorial "MAX7219 LED dot matrix display Arduino" It's great because everything is explained. All examples run on the Arduino Nano without any problems. Thanks for that. I have a question about the last example:

"Example code for sprite text effect on MAX7219 LED dot matrix display with Arduino." In the processing loop: 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);}

I want instead of "myDisplay.displayText". "myDisplay.display... 2 graphic characters" Insert Can someone please help me how to do this?

I want to have a locomotive with wagons drive across the display and let the walker run behind it. Is for my garden railway. Thank you in advance Siggi

Jean-Marc

Friday 25th of August 2023

Forget my last comment, my Display is no I2C. I am definitively too old !!!!!!!! Greetings Jean-Marc

Jean-Marc

Friday 25th of August 2023

I think this library is exactly what i am looking for. Unfortunatly i have a I2c version of a 8x32 Display. Is there a way (other library ?) to use it. Now i use it with a other library. It works but this new library would have much more functionalities. In advance thanks a lot for your help. I started 2022 with Raspberry and arduino stuff. What a wonderful world. thanks a lot to all the makers for a lot of examples. I am 81 but still fully motivated Jean-Marc

Glen Lewis

Monday 11th of December 2023

@Jean-Marc, Electronics is in your blood - Keep going old mate :)

Rick Neal

Wednesday 22nd of March 2023

I like the way you explained the sketches as it was very helpful. I however, didn't understand how the sketch could work with just a CS lead. Pin #3. I was only able to get the sketches to work with line (14) disabled and lines (17-19) enabled. Maybe that's why it would work once and then had junk to display? Thanks, Rick