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.