No post de hoje vamos montar um placar eletrônico com Arduino, usando uma placa Nano e módulos matriz de leds 8×8 Max7219, fazendo o controle por meio de botões tipo push-button.
Serão dois displays e três botões de controle, e neste tutorial você encontra todo o esquema de ligação dos componentes, assim como os arquivos necessários para montar uma estrutura semelhante à da imagem acima.
O módulo Max7219
O módulo matriz de led 8×8 com Max7219 é um módulo relativamente simples de usar, com 3 pinos de controle e alimentação de 5V.
Uma das vantagens desse módulo é que ele já vem com os pinos de saída para você interligar outros módulos Max7219 (na imagem abaixo, no lado direito). Dessa maneira, você controla vários deles usando as mesmas 4 portas do microcontrolador. É essa ligação que vamos usar para montar o placar eletrônico.
Se quiser conhecer outros projetos aqui do Arduino e Cia com o módulo Max7219, confira os posts Painel de led com módulo Max7219 e Módulo Max7219 matriz de leds 8×8.
Circuito do placar eletrônico
O controle do placar eletrônico vai ser feito por um Arduino Nano, que vai se comunicar com os módulos Max7219 através das portas 10 (pino DataIn do módulo), 11 (pino CS) e 12 (pino CLK).
Os botões serão ligados nas portas 6, 7 e 8 do Arduino, e vão utilizar os resistores pull-up internos, dispensando assim o uso desse componente na protoboard.
Por fim, os leds serão conectados nas portas 3 e 4, e servem para indicar qual display está ativo, mas vamos explicar isso com mais detalhes logo abaixo.
Programa de controle do placar eletrônico
Para o programa do placar eletrônico, vamos utilizar a biblioteca LedControl, que pode ser instalada através da própria IDE do Arduino, no menu Sketchs -> Incluir Biblioteca -> Gerenciar Bibliotecas e procurar por ledcontrol:
Dúvidas na instalação da biblioteca? Confira o post Como instalar uma biblioteca na IDE Arduino.
Com a biblioteca instalada, carregue o programa abaixo no Arduino Nano:
//Programa: Placar Eletronico com Arduino e Max7219
//Autor: Arduino e Cia
#include "LedControl.h"
//Conexoes do modulo Max7219
//DataIn = Pino 11
//CLK = Pino 12
//CS = Pino 11
LedControl lc = LedControl(10, 12, 11, 2);
//Armazenam o valor dos botoes
int v_but1, v_but2, v_but3;
//Brilho dos displays
int brilho = 15;
//Numero do display selecionado
int j = 0;
//Array do placar atual
int placar[2] = {0, 0};
//Array do placar anterior
int placar_ant[2] = {0, 0};
unsigned long delaytime = 200;
void setup()
{
Serial.begin(9600);
//Inicializa pinos botoes
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(8, INPUT_PULLUP);
//Inicializa pinos leds
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
digitalWrite(3, HIGH);
//Inicializa os displays
lc.shutdown(0, false);
lc.shutdown(1, false);
//Ajusta o brilho de cada display
lc.setIntensity(0, brilho);
lc.setIntensity(1, brilho);
//Apaga os displays
lc.clearDisplay(0);
lc.clearDisplay(1);
//Mostra 0 (zero) nos dois displays
writeOnMatrix(0, 0);
writeOnMatrix(0, 1);
}
void loop()
{
//Verifica se o botao de alternar
//displays foi acionado
v_but1 = digitalRead(6);
if (v_but1 == 0)
{
j = !j;
//Acende o led correspondente
if (j == 0)
{
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
}
else
{
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
}
while (digitalRead(6) == 0)
{delay(50);}
}
//Verifica se o botao de aumentar
//contador foi acionado
v_but2 = digitalRead(7);
if (v_but2 == 0)
{
placar[j] = placar[j] + 1;
if (placar[j] <= 0 || placar[j] >= 10)
{
placar[j] = 0;
}
if (placar_ant[j] != placar[j])
{
//Chama a rotina que atualiza o display
writeOnMatrix(placar[j], j);
v_but3 = digitalRead(8);
placar_ant[j] = placar [j];
}
while (digitalRead(7) == 0)
{delay(50);}
}
//Verifica se o botao de diminuir
//contador foi acionado
v_but3 = digitalRead(8);
if (v_but3 == 0)
{
placar[j] = placar[j] - 1;
if (placar[j] <= 0 || placar[j] >= 10)
{
placar[j] = 0;
}
if (placar_ant[j] != placar[j])
{
//Chama a rotina que atualiza o display
writeOnMatrix(placar[j], j);
v_but3 = digitalRead(8);
placar_ant[j] = placar [j];
}
while (digitalRead(8) == 0)
{delay(50);}
}
}
void writeOnMatrix(int numero, int tela)
{
//O array abaixo forma o numero 0
byte N0[8] = {B00000000, B00000000, B00111110, B01000001,
B01000001, B00111110, B00000000, B00000000
};
//numero 1
byte N1[8] = {B00000000, B00000000, B00000000, B01000010,
B01111111, B01000000, B00000000, B00000000
};
//numero 2
byte N2[8] = {B00000000, B00000000, B01100010, B01010001,
B01001001, B01000110, B00000000, B00000000
};
//numero 3
byte N3[8] = {B00000000, B00000000, B00100010, B01000001,
B01001001, B00110110, B00000000, B00000000
};
//numero 4
byte N4[8] = {B00000000, B00000000, B00001100, B00001010,
B00001001, B01111111, B00000000, B00000000
};
//numero 5
byte N5[8] = {B00000000, B00000000, B00100111, B01000101,
B01000101, B00111001, B00000000, B00000000
};
//numero 6
byte N6[8] = {B00000000, B00000000, B00111110, B01001001,
B01001001, B00110000, B00000000, B00000000
};
//numero 7
byte N7[8] = {B00000000, B00000000, B01100001, B00010001,
B00001001, B00000111, B00000000, B00000000
};
//numero 8
byte N8[8] = {B00000000, B00000000, B00110110, B01001001,
B01001001, B00110110, B00000000, B00000000
};
//numero 9
byte N9[8] = {B00000000, B00000000, B00001110, B01001001,
B01001001, B00111110, B00000000, B00000000
};
//Mostra no display selecionado o numero correspondente
switch (numero)
{
case 0:
lc.setRow(tela, 1, N0[0]);
lc.setRow(tela, 1, N0[1]);
lc.setRow(tela, 2, N0[2]);
lc.setRow(tela, 3, N0[3]);
lc.setRow(tela, 4, N0[4]);
lc.setRow(tela, 5, N0[5]);
lc.setRow(tela, 6, N0[6]);
lc.setRow(tela, 7, N0[7]);
break;
case 1:
lc.setRow(tela, 1, N1[0]);
lc.setRow(tela, 1, N1[1]);
lc.setRow(tela, 2, N1[2]);
lc.setRow(tela, 3, N1[3]);
lc.setRow(tela, 4, N1[4]);
lc.setRow(tela, 5, N1[5]);
lc.setRow(tela, 6, N1[6]);
lc.setRow(tela, 7, N1[7]);
break;
case 2:
lc.setRow(tela, 1, N2[0]);
lc.setRow(tela, 1, N2[1]);
lc.setRow(tela, 2, N2[2]);
lc.setRow(tela, 3, N2[3]);
lc.setRow(tela, 4, N2[4]);
lc.setRow(tela, 5, N2[5]);
lc.setRow(tela, 6, N2[6]);
lc.setRow(tela, 7, N2[7]);
break;
case 3:
lc.setRow(tela, 1, N3[0]);
lc.setRow(tela, 1, N3[1]);
lc.setRow(tela, 2, N3[2]);
lc.setRow(tela, 3, N3[3]);
lc.setRow(tela, 4, N3[4]);
lc.setRow(tela, 5, N3[5]);
lc.setRow(tela, 6, N3[6]);
lc.setRow(tela, 7, N3[7]);
break;
case 4:
lc.setRow(tela, 1, N4[0]);
lc.setRow(tela, 1, N4[1]);
lc.setRow(tela, 2, N4[2]);
lc.setRow(tela, 3, N4[3]);
lc.setRow(tela, 4, N4[4]);
lc.setRow(tela, 5, N4[5]);
lc.setRow(tela, 6, N4[6]);
lc.setRow(tela, 7, N4[7]);
break;
case 5:
lc.setRow(tela, 1, N5[0]);
lc.setRow(tela, 1, N5[1]);
lc.setRow(tela, 2, N5[2]);
lc.setRow(tela, 3, N5[3]);
lc.setRow(tela, 4, N5[4]);
lc.setRow(tela, 5, N5[5]);
lc.setRow(tela, 6, N5[6]);
lc.setRow(tela, 7, N5[7]);
break;
case 6:
lc.setRow(tela, 1, N6[0]);
lc.setRow(tela, 1, N6[1]);
lc.setRow(tela, 2, N6[2]);
lc.setRow(tela, 3, N6[3]);
lc.setRow(tela, 4, N6[4]);
lc.setRow(tela, 5, N6[5]);
lc.setRow(tela, 6, N6[6]);
lc.setRow(tela, 7, N6[7]);
break;
case 7:
lc.setRow(tela, 1, N7[0]);
lc.setRow(tela, 1, N7[1]);
lc.setRow(tela, 2, N7[2]);
lc.setRow(tela, 3, N7[3]);
lc.setRow(tela, 4, N7[4]);
lc.setRow(tela, 5, N7[5]);
lc.setRow(tela, 6, N7[6]);
lc.setRow(tela, 7, N7[7]);
break;
case 8:
lc.setRow(tela, 1, N8[0]);
lc.setRow(tela, 1, N8[1]);
lc.setRow(tela, 2, N8[2]);
lc.setRow(tela, 3, N8[3]);
lc.setRow(tela, 4, N8[4]);
lc.setRow(tela, 5, N8[5]);
lc.setRow(tela, 6, N8[6]);
lc.setRow(tela, 7, N8[7]);
break;
case 9:
lc.setRow(tela, 1, N9[0]);
lc.setRow(tela, 1, N9[1]);
lc.setRow(tela, 2, N9[2]);
lc.setRow(tela, 3, N9[3]);
lc.setRow(tela, 4, N9[4]);
lc.setRow(tela, 5, N9[5]);
lc.setRow(tela, 6, N9[6]);
lc.setRow(tela, 7, N9[7]);
break;
}
}
O funcionamento é bem simples: utilize o botão da esquerda para selecionar qual dos dois displays será atualizado. O led correspondente ao display selecionado será aceso. Utilize então o botão do meio para aumentar o valor do contador, e o botão da direita para diminuir o valor. Confira no vídeo abaixo o projeto em funcionamento:
Se você quiser uma estrutura como essa para o seu placar eletrônico, disponibilizei os arquivos para impressão 3D no Thingiverse, neste link.
