Domine Matriz de LED 8×8 com MAX7219: Texto Scrolling e Controle Bluetooth Android
Neste tutorial Arduino, aprenderemos a controlar Matriz de LED 8×8 usando o driver MAX7219 e a placa Arduino. Você pode assistir ao vídeo a seguir ou ler o tutorial escrito abaixo para mais detalhes.
Visão Geral
Faremos três exemplos: no primeiro, explicaremos o princípio básico de funcionamento do MAX7219; no segundo, veremos como funciona o texto scrolling (rolante) na Matriz de LED 8×8; e no terceiro, controlaremos eles via Bluetooth e um aplicativo Android personalizado.
MAX7219
Vamos examinar mais de perto o driver MAX7219. O CI é capaz de acionar 64 LEDs individuais usando apenas 3 fios para comunicação com o Arduino, e mais: podemos conectar em cascata (daisy chain) múltiplos drivers e matrizes e ainda usar os mesmos 3 fios.

Os 64 LEDs são acionados por 16 pinos de saída do CI. A pergunta agora é: como isso é possível? Bem, o número máximo de LEDs acesos ao mesmo tempo é, na verdade, oito. Os LEDs são dispostos como um conjunto de 8×8 linhas e colunas. Então, o MAX7219 ativa cada coluna por um período muito curto e, ao mesmo tempo, também aciona cada linha. Ao alternar rapidamente pelas colunas e linhas, o olho humano só notará uma luz contínua.

Observe como os pinos de uma Matriz de LED 8×8 comum são organizados internamente. Se você estiver construindo uma matriz por conta própria, deve considerar isso.
Note também que uma placa breakout comum para o MAX7219 vem com um resistor entre o 5V e o pino 18 do CI. O resistor é usado para definir o brilho ou o fluxo de corrente para os LEDs.

A tabela a seguir, do datasheet do CI, mostra o valor do resistor que devemos usar de acordo com a queda de tensão direta dos nossos LEDs.

Esquema do Circuito
Agora, vamos conectar o módulo Matriz de LED 8×8 à Placa Arduino. Aqui está o esquema do circuito:

O VCC e GND do módulo vão para os pinos 5V e GND do Arduino e os outros três pinos, DIN, CLK e CS vão para qualquer pino digital da placa Arduino. Se quisermos conectar mais de um módulo, apenas conectamos os pinos de saída da placa breakout anterior aos pinos de entrada do novo módulo. Na verdade, esses pinos são todos iguais, exceto que o pino DOUT da placa anterior vai para o pino DIN da nova placa.
Você pode obter os componentes necessários para este tutorial Arduino nos links abaixo:
- Módulo Matriz de Pontos 8×8 LED MAX7219
- Módulo Bluetooth HC-05
- Placa Arduino
- Protoboard e Jumpers
Código Arduino Básico do MAX7219
Uma vez conectados os módulos, estamos prontos para analisar o código Arduino do primeiro exemplo. Usaremos a biblioteca MaxMatrix, que pode ser baixada do GitHub.
/* Matriz 8x8 LED MAX7219 Exemplo 01 por Dejan Nedelkovski, www.HowToMechatronics.com
Baseado na biblioteca: GitHub | riyas-org/max7219 https://github.com/riyas-org/max7219 */
#include <MaxMatrix.h>
int DIN = 7; // Pino DIN do módulo MAX7219
int CLK = 6; // Pino CLK do módulo MAX7219
int CS = 5; // Pino CS do módulo MAX7219
int maxInUse = 1;
MaxMatrix m(DIN, CS, CLK, maxInUse);
char A[] = {4, 8, B01111110, B00010001, B00010001, B01111110};
char B[] = {4, 8, B01111111, B01001001, B01001001, B00110110};
char smile01[] = {8, 8, B00111100, B01000010, B10010101, B10100001, B10100001, B10010101, B01000010, B00111100};
char smile02[] = {8, 8, B00111100, B01000010, B10010101, B10010001, B10010001, B10010101, B01000010, B00111100};
char smile03[] = {8, 8, B00111100, B01000010, B10100101, B10010001, B10010001, B10100101, B01000010, B00111100};
void setup() {
m.init(); // Inicialização do MAX7219
m.setIntensity(8); // Intensidade inicial da matriz de LED, 0-15
}
void loop() {
// Acendendo LEDs individuais na posição x,y ou linha,coluna
m.setDot(6, 2, true);
delay(1000);
m.setDot(6, 3, true);
delay(1000);
m.clear(); // Limpa o display
for (int i = 0; i < 8; i++) {
m.setDot(i, i, true);
delay(300);
}
m.clear();
// Exibindo o caractere na posição x,y (canto superior esquerdo do caractere)
m.writeSprite(2, 0, A);
delay(1000);
m.writeSprite(2, 0, B);
delay(1000);
m.writeSprite(0, 0, smile01);
delay(1000);
m.writeSprite(0, 0, smile02);
delay(1000);
m.writeSprite(0, 0, smile03);
delay(1000);
for (int i = 0; i < 8; i++) {
m.shiftLeft(false, false);
delay(300);
}
m.clear();
}
Descrição: Primeiro, precisamos incluir a biblioteca MaxMatrix.h, definir os pinos aos quais o módulo está conectado, definir quantos módulos usamos e definir o objeto MaxMatrix.
Para exibir caracteres, precisamos defini-los em um array de caracteres ou bytes. Aqui tenho vários exemplos. Podemos notar como os bits formam os caracteres, que na verdade são zeros e uns. Neste caso, eles estão rotacionados 90 graus, mas o exemplo da biblioteca sugere usá-los dessa forma para que seja mais fácil implementar a função personalizada shiftLeft para rolagem de texto.

Na seção setup, apenas inicializamos o módulo e definimos o brilho dos LEDs. Na seção loop, usando a função setDot(), podemos acender qualquer LED individual na posição X, Y ou Linha/Coluna e, usando a função clear(), podemos limpar o display.

Para exibir os caracteres predefinidos, usamos a função writeSprite(), e os dois primeiros argumentos são a posição X e Y do canto superior esquerdo do caractere. No final, usando a função shiftLeft(), movemos ou rolamos o caractere para a esquerda.
Código Arduino de Texto Scrolling na Matriz 8×8 LED
Em seguida, vamos analisar o exemplo de texto scrolling e ver o que é diferente. Abaixo do código, você encontrará sua descrição.
/* Matriz 8x8 LED MAX7219 Texto Scrolling Exemplo
Baseado na biblioteca: GitHub | riyas-org/max7219 https://github.com/riyas-org/max7219 */
#include <MaxMatrix.h>
#include <avr/pgmspace.h>
PROGMEM const unsigned char CH[] = {
3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // espaço
1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !
3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "
5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #
4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $
5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %
5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &
1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // '
3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (
3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )
5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // *
5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +
2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -
2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .
4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4
4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6
4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9
2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :
2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // <
3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // =
3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // >
4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @
4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A
4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B
4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C
4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D
4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E
4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F
4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G
4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H
3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I
4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J
4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K
4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L
5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M
5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O
4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P
4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R
4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S
5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T
4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U
5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V
5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W
5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X
5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [
4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash
2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // ^
4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _
2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `
4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a
4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b
4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c
4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // d
4, 8, B00111000, B01010100, B01010100, B01111111, B00000000, // e
3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g
4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h
3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i
4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j
4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k
3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l
5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m
4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n
4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o
4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p
4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q
4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r
3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // s
4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // t
5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // u
5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // v
5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // w
4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // x
3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // y
3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // z
3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {
1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |
3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }
4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~
};
int DIN = 7;
int CLK = 6;
int CS = 5;
int maxInUse = 2;
MaxMatrix m(DIN, CS, CLK, maxInUse);
byte buffer[10];
char text[] = "HowToMechatronics.com "; // Texto scrolling
void setup() {
m.init();
m.setIntensity(15); // Intensidade matriz de pontos 0-15
}
void loop() {
printStringWithShift(text, 100); // (texto, velocidade de rolagem)
}
// Exibe caracteres extraídos com rolagem
void printCharWithShift(char c, int shift_speed) {
if (c < 32) return;
c -= 32;
memcpy_P(buffer, CH + 7 * c, 7);
m.writeSprite(32, 0, buffer);
m.setColumn(32 + buffer[0], 0);
for (int i = 0; i < buffer[0] + 1; i++) {
delay(shift_speed);
m.shiftLeft(false, false);
}
}
// Extrai caracteres da string de texto
void printStringWithShift(char* s, int shift_speed) {
while (*s != 0) {
printCharWithShift(*s, shift_speed);
s++;
}
}
Descrição: Aqui precisamos incluir uma biblioteca adicional para o PROGMEM, que é um modificador de variável usado para armazenar dados na memória flash em vez de SRAM. Quando temos um banco de dados maior de variáveis estáticas, como neste caso definindo letras e caracteres, é melhor armazená-los na memória flash porque ela é muito maior, 32K bytes, comparada aos 2K bytes da SRAM.

Em seguida, com um array de caracteres, definimos o texto scrolling e, na seção loop, a função personalizada printStringWithShift imprime o texto scrolling na matriz de LED com uma velocidade de rolagem definida em milissegundos com o segundo argumento. A primeira coisa que essa função personalizada faz é extrair os caracteres da string de texto e, em seguida, exibir esses caracteres com rolagem na matriz de LED.
Aplicativo Android para Controlar Matriz 8×8 LED via Bluetooth
Uma vez que aprendemos como o MAX7219 funciona, agora podemos fazer o terceiro exemplo, que é um projeto prático Arduino onde construiremos um aplicativo Android personalizado para controlar a matriz de LED via comunicação Bluetooth. Antes de continuar, sugiro que você confira meus tutoriais detalhados sobre como usar o módulo Bluetooth HC-05 e como construir um aplicativo Android personalizado usando o aplicativo online MIT App Inventor.

Aqui está o código Arduino. Vamos ver as modificações em comparação com o exemplo anterior.
/* Matriz 8x8 LED MAX7219 Texto Scrolling Controle Android via Bluetooth
por Dejan Nedelkovski, www.HowToMechatronics.com
Baseado na biblioteca: GitHub | riyas-org/max7219 https://github.com/riyas-org/max7219 */
#include <MaxMatrix.h>
#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
// ... (mesmo array CH do exemplo anterior) ...
int dIn = 7;
int clk = 6;
int cs = 5;
int maxInUse = 2;
MaxMatrix m(dIn, cs, clk, maxInUse);
SoftwareSerial Bluetooth(8, 7); // Bluetooth
byte buffer[10];
char incomebyte;
int scrollSpeed = 100;
char text[100] = "HowToMechatronics.com "; // Mensagem de texto inicial
int brightness = 15;
int count = 0;
char indicator;
void setup() {
m.init();
m.setIntensity(brightness);
Bluetooth.begin(38400); // Taxa de comunicação padrão do módulo Bluetooth
}
void loop() {
printStringWithShift(text, scrollSpeed);
if (Bluetooth.available()) {
indicator = Bluetooth.read();
// Se pressionamos o botão "Send" do App Android, limpa o texto anterior
if (indicator == '1') {
for (int i = 0; i < 100; i++) {
text[i] = 0;
m.clear();
}
// Lê todos os dados/string vindos do telefone e coloca no array text[]
while (Bluetooth.available()) {
incomebyte = Bluetooth.read();
text[count] = incomebyte;
count++;
}
count = 0;
}
// Ajustando a Velocidade de Rolagem
else if (indicator == '2') {
String sS = Bluetooth.readString();
scrollSpeed = 150 - sS.toInt(); // Milissegundos, subtração porque valor menor = maior velocidade
}
// Ajustando o brilho
else if (indicator == '3') {
String sB = Bluetooth.readString();
brightness = sB.toInt();
m.setIntensity(brightness);
}
}
}
// ... (funções printCharWithShift, printStringWithShift, printString iguais ao exemplo anterior) ...
Descrição: Primeiro, precisamos incluir a biblioteca SoftwareSerial.h que habilitará a comunicação Bluetooth e definir algumas variáveis necessárias para o programa. Na seção setup, precisamos inicializar o Bluetooth em sua taxa de baud padrão de 38400 bits por segundo. Defini a mensagem de texto inicial como "HowToMechatronics.com" com velocidade de rolagem de 100 milissegundos de atraso.
Em seguida, na seção loop, usando a função Bluetooth.available(), verificamos se há dados de entrada da porta serial e, se for verdadeiro, usando a função Bluetooth.read(), começamos a ler a porta serial, um byte a cada iteração. O primeiro byte recebido será sempre armazenado na variável "indicator" e, de acordo com ele, escolheremos se mudaremos a mensagem de texto, a velocidade de rolagem ou o brilho da matriz de LED.

Se olharmos os blocos de código do aplicativo Android, notaremos que quando o botão "Send" é clicado, primeiro enviamos o byte de indicação, neste caso "1", que significa que queremos alterar a mensagem de texto. Para fazer isso, no lado do Arduino, limparemos todo o array de caracteres e também a exibição da matriz de LED. Em seguida, no loop "while", leremos o resto dos dados na porta serial, que é a mensagem digitada na caixa de texto do aplicativo Android.
Caso a variável de indicação seja "2", significa que alteramos a posição do controle deslizante de velocidade de rolagem, então leremos seu novo valor usando a função Bluetooth.readString() e ajustaremos a velocidade de rolagem. Da mesma forma, ajustamos o brilho dos LEDs.
Aqui você pode baixar o aplicativo Android:
Isso é praticamente tudo para este tutorial. Se você tiver alguma dúvida, pode usar a seção de comentários abaixo.
Processo de manufatura
- Mealheiro Inteligente: Controlar Aceitador de Moedas com Arduino Nano
- Construa um Console Pong 24×16 LED com Arduino Nano e MAX7219
- Controlar um LED via Bluetooth com Arduino – Guia DIY Simples
- Controle de LED Arduino com Cortana via Bluetooth no Windows 10
- Controlando Matriz de LED 8×8 com Arduino Uno: Guia Passo a Passo
- Controle Remoto de Carro com Arduino Uno e Bluetooth: Guia Passo a Passo
- Controle Braço Robótico Arduino via App Android Dedicado
- Matriz LED 8x8 com Bluetooth e Texto Rolante – Projeto Arduino
- Crie o Clássico Jogo Asteroids com Arduino Mega e Matriz LED MAX72XX
- Controle Múltiplo de Servos via Bluetooth: Arduino e App Android