Guia do Arduino com display de matriz de pontos LED MAX7219

Tempo de leitura: 19 minutes

Neste guia, você aprenderá como controlar um display de matriz de pontos de LED MAX7219 com o Arduino. Incluí um diagrama de fiação e muitos códigos de exemplo! O código neste guia pode ser usado para telas 8×8, 8×32 e até maiores.

Para este guia, usarei o MD_Parola em combinação com a biblioteca Arduino MD_MAX72XX. Essas bibliotecas tornam a exibição de texto de rolagem e outras animações muito fácil. Na primeira parte deste artigo, abordarei os fundamentos da impressão de texto no visor. A seguir, veremos o texto de rolagem e outras animações de texto. Por fim, mostrarei como usar sprites de texto.

Se você quiser saber mais sobre outros tipos de monitores, confira os artigos abaixo:

Artigos recomendados

Se você tiver alguma dúvida, deixe um comentário abaixo.

 

Suprimentos

Componentes de hardware

  • 8×32 MAX7219 Display de matriz de pontos LED (1)
  • 8×8 MAX7219-LED-dot-display (1)
  • Genérico 8 × 8 MAX7219 LED dot matrix display (1)
  • Arduino Uno Rev 3 ou genérico (1)
  • Fios de ligação (macho para fêmea) (4)
  • Cabo USB tipo A/B (1)
  • Fios (20)
  • Jumpers (20)

 

Sobre o driver MAX7219 LED

O driver MAX7219 LED pode ser usado para controlar telas de 7 segmentos de até 8 dígitos, telas de gráfico de barras ou 64 LEDs individuais. O driver se comunica com o Arduino por meio de SPI, portanto, você só precisa de três fios para controlar o display.

Como o MAX7219 pode controlar no máximo 64 LEDs, o tamanho máximo do display de matriz de pontos que ele pode controlar é de 8×8 pixels. No entanto, você pode conectar vários drivers e matrizes em série e controlar facilmente monitores muito maiores, como 8×32, 8×64 ou até maiores. Ainda assim, você só precisa de três fios para controlar todos os ICs, então você precisa de muito poucos pinos de I/O do Arduino.

Abaixo você pode encontrar as especificações de um display de matriz de pontos de LED MAX7219 8× 32 típico.

 

Especificações do display de matriz de pontos de LED MAX7219

Tensão operacional5 V
Driver de vídeoMAX7219 x 4
Níveis de brilho16
Dimensões de exibição32 x 128 x 15 mm
Píxeis8×32, ⌀ 3 mm
CustoCusto Aproximado de 40 a 60R$

Para mais informações, você pode verificar o datasheet aqui:

Quase todos os visores que usei no passado usavam uma matriz de LED 1088AS tipo 8 8. Você pode encontrar o datasheet de uma das empresas que os faz aqui:

 

Como conectar o display matricial ao Arduino

O driver de display LED MAX7219 se comunica com o Arduino por meio de SPI (Interface Periférica Serial). Para saber mais sobre esse protocolo de dados, consulte esta página no site do Arduino.

Com uma interface SPI, há sempre um dispositivo mestre (o Arduino) que controla os dispositivos periféricos (também conhecidos como escravos). Você pode controlar a exibição por meio da interface SPI de hardware do microcontrolador AVR do Arduino ou três pinos digitais arbitrários (software SPI).

Os pinos SPI de hardware (MOSI, MISO e SCK) estão em um local específico em cada placa Arduino. Essa interface é mais rápida do que usar o software SPI, mas você precisará usar os seguintes pinos de saída fixos:

 

Localizações de pinos de SPI de hardware

PlacaMOSIMISOSCKLevel
Arduino Uno11 or ICSP-412 or ICSP-113 or ICSP-35 V
Arduino Mega51 or ICSP-450 or ICSP-152 or ICSP-35 V
Arduino LeonardoICSP-4ICSP-1ICSP-35 V
Arduino DueSPI-4SPI1SPI-33.3 V
Arduino MKR100081093.3 V

Localizações de pinos SPI de hardware em diferentes placas Arduino.

Observe que os pinos MOSI, MISO e SCK também estão em um local físico consistente no cabeçalho ICSP de 6 pinos:

Para controlar monitores do MAX7219, você só precisa fazer três conexões:

  • MOSI (Master Out Slave In) conectado a DIN – A linha Master enviando dados para os periféricos.
  • SCK (Serial Clock) conectado ao CLK – Os pulsos de clock que sincronizam a transmissão de dados gerados pelo mestre.
  • SS (Slave Select) conectado a CS – O pino em cada dispositivo que o mestre pode usar para habilitar e desabilitar dispositivos específicos.

Você pode conectar vários monitores em série para criar um monitor grande conectando DOUT do primeiro monitor ao DIN do próximo monitor. VCC, GND, CLK e CS são compartilhados entre todos os visores.

Você pode selecionar qualquer um dos pinos digitais do Arduino para o pino SS/CS. Observe que para este guia eu usei o pino 3 (veja a tabela abaixo).

O diagrama de ligação abaixo mostra como conectar o display de matriz de pontos de LED MAX7219 ao Arduino. Observe que ao usar a biblioteca MD_Parola, você precisa orientar a tela com o conector DIN à direita, caso contrário, o texto será impresso de cabeça para baixo.

MAX7219 LED dot matrix display com diagrama de ligação Arduino

MAX7219 Conexões de display de matriz de pontos LED

MAX7219 DisplayArduino
VCC5 V
GNDGND
DIN11 (MOSI)
CS3 (SS)
CLK13 (SCK)

Se você deseja usar o software SPI em vez disso, pode conectar DIN, CS e CLK a qualquer um dos pinos digitais do Arduino. Você só precisa especificar os números dos pinos na configuração do código do Arduino (veja os exemplos abaixo).

 

Requerimentos Energia

A potência máxima que o Arduino Uno pode fornecer com segurança quando alimentado por USB é cerca de 400 mA a 5 V. Se você deseja controlar uma tela grande, é aconselhável usar uma fonte de alimentação externa.

 

Instalação das bibliotecas MD_Parola e MD_MAX72XX Arduino

Para controlar a exibição do MAX7219, usaremos duas bibliotecas Arduino incríveis criadas por Marco Colli da MajicDesigns. A biblioteca MD_Parola pode ser usada para criar muitas animações de texto diferentes, como rolagem e efeitos de texto sprite. Esta biblioteca depende da biblioteca MD_MAX72XX que implementa as funções de hardware da matriz de LED.

Estas são algumas funções e recursos da biblioteca:

  • Justificativa de texto à esquerda, direita ou centro
  • Rolagem de texto com efeitos de entrada e saída
  • Parâmetros de exibição de controle e velocidade de animação
  • Múltiplos visores virtuais (zonas) em cada string de módulos LED
  • Suporte para interface SPI de hardware
  • Fontes definidas pelo usuário e/ou substituições de caracteres individuais
  • Suporte para monitores de altura dupla
  • Suporte para misturar texto e gráficos na mesma tela

Marco trabalha nesta biblioteca há vários anos e escreveu alguns tutoriais excelentes em seu blog. O código-fonte e a documentação das bibliotecas podem ser encontrados aqui:

Você pode instalar as bibliotecas por meio do Library Manager do Arduino IDE. Vá para Tools > Manage Libraries… ou digite Ctrl + Shift + I no Windows. O Library Manager irá abrir e atualizar a lista de bibliotecas instaladas.

Pesquise por ‘MD_MAX72XX’ e procure as bibliotecas de majicDesigns. Selecione a versão mais recente e clique em instalar. Certifique-se de instalar a biblioteca MD_MAX72XX e a biblioteca MD_Parola.

 

Diferentes tipos de visores matriciais LED

Muitos tipos e tamanhos diferentes de visores matriciais LED MAX7219 estão disponíveis no mercado. A biblioteca MD_MAX72XX suporta quase todos esses monitores, mas você precisa configurar a biblioteca corretamente para o tipo de matriz que está sendo usado.

Abaixo você pode encontrar informações sobre como conectar e configurar os visores matriciais de LED MAX7219 mais comuns que você pode comprar no MercadoLivre, Amazon, AliExpress e eBay.

 

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

Este é provavelmente o display MAX7219 mais comum que você pode encontrar. Normalmente vem como uma matriz de LEDs de 8×8 ou 8×32 e você pode comprá-los com LEDs de cores diferentes.

 

Orientação do módulo e conexões

Você pode conectar facilmente vários módulos 8×8 ou 8×32 juntos para criar um display maior. Eu normalmente soldo conectores machos retos na parte de trás dos módulos e os conecto usando jumpers. Desta forma, você pode desmontá-los sem ter que desoldar nenhuma conexão.

O display é orientado com o lado DIN à direita. Observe que o texto impresso na tela na parte traseira do PCB pode estar de cabeça para baixo nesta orientação.

     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 
         +------------------------+

Configuração de hardware no código Arduino

Ao configurar o display em seu código Arduino, você precisa definir o HARDWARE_TYPE para FC16_HW e especificar o número de dispositivos conectados. Uma matriz 8×8 conta como 1 dispositivo, então se você deseja controlar um módulo 8×32, você precisa definir MAX_DEVICES para 4 (um display 8×32 contém 4 MAX7219 ICs).

// Hardware SPI:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 2
// Crie uma nova instância da classe MD_MAX72XX:
MD_Parola matrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Para software SPI, você também precisa especificar as conexões DATA_PIN e CLK_PIN:
// #define DATA_PIN 3
// #define CLK_PIN 4
// Crie uma nova instância da classe MD_MAX72XX:
// MD_Parola matrix = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

 

Módulo 8×8 genérico

Este é um módulo 8×8 montado em um PCB verde com o MAX7219 IC abaixo da matriz de LED. Eles são caracterizados pelos conectores de 5 pinos nas extremidades curtas do PCB retangular.

Orientação do módulo e conexões

O módulo genérico precisa ser orientado com o CI MAX7219 na parte superior. Você pode conectar vários módulos junto com alguns fios de jumper curto fêmea para fêmea. Simplesmente conecte todos os pinos do lado DOUT do primeiro módulo ao lado DIN do próximo 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

Configuração de hardware no código Arduino

Para os módulos de exibição genéricos, você precisa definir HARDWARE_TYPE para GENERIC_HW. O resto da configuração e MAX_DEVICES são iguais aos dos módulos FC-16.

// Hardware SPI:
#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW
#define MAX_DEVICES 1
#define CS_PIN 2
// Crie uma nova instância da classe MD_MAX72XX:
MD_Parola matrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Para software SPI, você também precisa especificar as conexões DATA_PIN e CLK_PIN:
// #define DATA_PIN 3
// #define CLK_PIN 4
// Crie uma nova instância da classe MD_MAX72XX:
// MD_Parola matrix = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

 

Códigos de exemplo do Arduino

Abaixo você encontrará vários códigos de exemplo que cobrem as funções básicas da biblioteca MD_Parola Arduino. Após cada exemplo, explico como o código funciona para que você possa modificá-lo para atender às suas necessidades. Você também pode encontrar mais exemplos acessando File > Examples > MD_Parola no IDE do Arduino, mas eles não incluem nenhuma explicação, portanto, podem ser um pouco difíceis de seguir.

 

Exemplo de código básico do Arduino para imprimir texto

Com o código de exemplo abaixo, você pode imprimir texto na tela sem animações.

Você pode fazer upload do código de exemplo para o seu Arduino por meio do IDE do Arduino. Para este guia, usei este display de matriz de pontos LED 8×32 padrão, mas você também pode usar outros tipos e/ou tamanhos (veja a explicação do código abaixo).

Você pode copiar o código clicando no botão no canto superior direito do campo do código.

/* Código de exemplo básico para display de matriz de pontos de LED MAX7219 com Arduino. */
// Incluir as bibliotecas Arduino necessárias:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// Defina o tipo de hardware, tamanho e pinos de saída:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
// Crie uma nova instância da classe MD_Parola com conexão SPI de hardware:
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Configuração do 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() {
  // Inicialize o objeto:
  myDisplay.begin();
  // Defina a intensidade (brilho) da tela (0-15):
  myDisplay.setIntensity(0);
  // Limpe a tela:
  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);
}

Você deve ver a seguinte saída:

 

Como funciona o código

A primeira etapa é incluir todas as bibliotecas Arduino necessárias. Como mencionei antes, a biblioteca MD_MAX72XX implementa as funções de hardware da matriz de LED e a biblioteca MD_Parola os efeitos de texto. Você também precisará incluir a biblioteca SPI, que vem pré-instalada no IDE do Arduino. Esta biblioteca é usada para a comunicação da Interface Periférica Serial entre o monitor e o Arduino.

// Incluir as bibliotecas Arduino necessárias:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

Em seguida, precisamos especificar qual hardware estamos usando. Como usei um display padrão 8×32 (também conhecido como FC-16), configurei HARDWARE_TYPE como FC16_HW. O número de CIs MAX7219 em um display 8×32 é 4, então eu defino MAX_DEVICES para 4. Por último, eu defini a qual pino o pino CS do display está conectado (pino de saída 3 neste caso). Consulte a seção sobre os tipos de tela para obter uma explicação mais detalhada sobre como configurar outros tipos de tela.

A instrução #define é usada para dar um nome a um valor constante. O compilador substituirá todas as referências a esta constante pelo valor definido quando o programa for compilado. Portanto, em todos os lugares que você mencionar CS_PIN, o compilador o substituirá pelo valor 3 quando o programa for compilado.

// Defina o tipo de hardware, tamanho e pinos de saída:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3

Depois disso, uma nova instância da classe MD_Parola é criada com a função MD_Parola(). Essa função precisa de três parâmetros, o primeiro é o tipo de hardware, o segundo o pino CS e o terceiro o número máximo de dispositivos conectados.

Observe que chamei o objeto MD_Parola de ‘myDisplay’, mas você também pode usar outros nomes. Você precisará alterar “myDisplay” para o novo nome no resto do esboço.

Quando você deseja usar o SPI de software em vez de SPI de hardware, também precisa definir os pinos de saída de dados e relógio e passá-los como parâmetros ao configurar o objeto de exibição.

// Crie uma nova instância da classe MD_Parola com conexão SPI de hardware:
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Configuração do software SPI:
// #define DATAPIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

Na seção de configuração do código, primeiro inicializamos o objeto com a função begin(). O brilho da tela pode ser definido com a função setIntensity(). Você pode inserir um valor entre 0 (brilho mínimo) e 15 (brilho máximo). A exibição é limpa com a função displayClear().

void setup() {
  // Inicialize o objeto:
  myDisplay.begin();
  // Defina a intensidade (brilho) da tela (0-15):
  myDisplay.setIntensity(0);
  // Limpe a tela:
  myDisplay.displayClear();
}

Na seção de loop do código, primeiro definimos o alinhamento do texto a ser impresso com a função setTextAlignment (). Você pode alinhar à esquerda, centralizar e direita o texto com PA_LEFT, PA_CENTER e PA_RIGHT respectivamente.

Em seguida, a string ‘Center’ é impressa com myDisplay.print("Center"). Observe que você precisa colocar aspas (”“) ao redor do texto, pois estamos imprimindo uma string de texto. Quando você deseja imprimir números, não são necessárias aspas. Por exemplo, myDisplay.print(1234). Você pode inverter a tela, ou seja, LEDs normalmente acesos desligam e vice-versa, com 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);
}

Texto de rolagem do código de exemplo do Arduino

Quando você deseja imprimir uma mensagem em um display de matriz de pontos, você frequentemente descobrirá que o display é muito pequeno para caber a mensagem inteira. A solução está na biblioteca MD_Parola, que torna muito fácil criar efeitos de texto de rolagem. Nos exemplos a seguir, mostrarei como configurar isso e também como usar alguns dos outros efeitos de texto disponíveis.

Você pode copiar o código abaixo clicando no botão no canto superior direito do campo do código.

/* Código de exemplo para efeito de texto de rolagem no display de matriz de pontos de LED MAX7219 com Arduino. */
// Incluir as bibliotecas Arduino necessárias:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// Defina o tipo de hardware, tamanho e pinos de saída:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
// Crie uma nova instância da classe MD_Parola com conexão SPI de hardware:
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Configuração para 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() {
  // Inicialize o objeto:
  myDisplay.begin();
  // Defina a intensidade (brilho) da tela (0-15):
  myDisplay.setIntensity(0);
  // Limpe a tela:
  myDisplay.displayClear();
  myDisplay.displayText("Texto de rolagem", PA_CENTER, 100, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
}
void loop() {
  if (myDisplay.displayAnimate()) {
    myDisplay.displayReset();
  }
}

 

Como funciona o código

A primeira parte do código até o final da seção de configuração é exatamente a mesma do exemplo anterior. No final da seção de configuração, especificamos como queremos exibir o texto com a função displayText(pText, align, speed, pause, effectIn, effectOut). Esta função leva 5 argumentos.

O primeiro parâmetro é a string de texto, neste caso “Texto de rolagem”.

O segundo argumento define o alinhamento do texto durante a pausa opcional. Você pode usar as mesmas opções de alinhamento do exemplo anterior, ou seja, PA_CENTER, PA_LEFT ou PA_RIGHT.

O terceiro e o quarto argumentos definem a velocidade da animação e o tempo de pausa, respectivamente. A velocidade de exibição é o tempo em milissegundos entre os quadros da animação. Quanto menor for o tempo, mais rápida será a animação. Se você deseja pausar o texto entre a animação de entrada e saída, pode definir o tempo de pausa em milissegundos. Defino como zero para que o texto role continuamente.

Em seguida, os efeitos de entrada e saída são especificados. Neste caso, usei PA_SCROLL_LEFT para ambos. Veja o exemplo abaixo para outros efeitos de texto.

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

Na seção de loop, você só precisa de duas funções para criar uma exibição de texto de rolagem.

Primeiro, usamos a função displayAnimate() em uma instrução if. Esta função anima a exibição usando os parâmetros de texto e animação especificados no momento e retorna true quando a animação termina. Quando a animação terminar, redefinimos a exibição com a função displayReset() para que o texto seja exibido em um loop.

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

 

Outros efeitos de texto

A biblioteca inclui vários outros efeitos de texto que você pode 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

O código de exemplo a seguir percorre os diferentes efeitos para que você possa ver como eles se parecem.

/* Código de exemplo para texto de rolagem e outros efeitos de texto no display MAX7219 de matriz de pontos LED com Arduino. */
// Incluir as bibliotecas Arduino necessárias:
#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
};
// Defina o tipo de hardware, tamanho e pinos de saída:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 3
// Crie uma nova instância da classe MD_Parola com conexão SPI de hardware:
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Configuração do 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("Olá", myDisplay.getTextAlignment(), myDisplay.getSpeed(), myDisplay.getPause(), texteffect[i], texteffect[i]);
    myDisplay.displayReset();
  }
}

 

Sprites de texto

Uma função relativamente nova da biblioteca MD_Parola são sprites de texto animados. Na computação gráfica, um sprite é um bitmap bidimensional integrado em uma cena maior (neste caso, a exibição de matriz).

Um sprite é composto de vários quadros que são executados sequencialmente para fazer a animação na tela. Assim que a animação atingir o último quadro, ela será reiniciada a partir do primeiro.

Observe que usei uma tela de matriz 8×64 para este exemplo conectando duas telas 8×32 (MAX_DEVICES está definido como 8).

/* Código de exemplo para efeito de texto sprite no display de matriz de pontos de LED MAX7219 com Arduino. */
// Incluir as bibliotecas Arduino necessárias:
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
// Defina o tipo de hardware, tamanho e pinos de saída:
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 8
#define CS_PIN 3
// Crie uma nova instância da classe MD_Parola com conexão SPI de hardware:
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Configuração do software SPI:
// #define DATAPIN 2
// #define CLK_PIN 4
// MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
// Definições de Sprite:
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] =  // homem caminhando
{
  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("Sprites parola", PA_CENTER, 50, 1000, PA_SPRITE, PA_SPRITE);
}
void loop() {
  if (myDisplay.displayAnimate()) {
    myDisplay.displayReset();
  }
}

Como funciona o código

Depois de configurar a exibição como antes, os sprites de texto são definidos.

Duas constantes são usadas para definir o sprite, uma para os dados de largura (número de bytes) de um sprite e a outra para o número de frames contidos na animação. O número total de bytes necessários é a largura * número de quadros. Observe que os dados do sprite são armazenados no PROGMEM para economizar espaço na RAM.

Cada linha do array é composta de números hexadecimais que definem quais LEDs precisam acender em cada coluna do sprite.

O exemplo inclui muitas definições de sprites diferentes, que você também pode encontrar em um dos exemplos que vêm com a biblioteca.

// Definições de Sprite:
const uint8_t F_PMAN1 = 6;
const uint8_t W_PMAN1 = 8;
const uint8_t PROGMEM pacman1[F_PMAN1 * W_PMAN1] =  // devorando animação pacman
{
  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,
};

Na configuração, a função setSpriteData(inData, inWidth, inFrames, outData, outWidth, outFrames) é usada para configurar os dados do usuário necessários para que a biblioteca possa exibir o sprite quando o tipo de animação PA_SPRITE for selecionado na função displayText().

Você pode selecionar qualquer um dos sprites predefinidos, neste caso eu usei pacman2 (pacman perseguido por um fantasma).

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

A seção de loop é a mesma de antes.

Conclusão

Neste artigo, mostrei como você pode usar um display de matriz de pontos de LED MAX7219 com o Arduino. Vimos os fundamentos da impressão de texto, texto de rolagem, outros efeitos de texto e sprites de texto. Ainda existem algumas funções usadas com menos frequência na biblioteca MD_Parola que não abordamos neste guia, mas você pode verificá-las na documentação do MD_Parola no GitHub.

Espero que você tenha achado este guia útil e informativo. Se sim, compartilhe com um amigo que também gosta de eletrônicos e de fazer coisas!

Eu adoraria saber quais projetos você planeja construir (ou já construiu) com este monitor. Se você tiver alguma dúvida, sugestão, ou se achar que falta alguma coisa neste guia, por favor, deixe um comentário abaixo.