19 novembro 2017

Placar eletrônico com Arduino

No post de hoje vamos montar um placar eletrônico com Arduino, usando uma placa Nano e módulos matriz de leds 8x8 Max7219, fazendo o controle por meio de botões tipo push-button.

Placar eletrônico com Arduino e Max7219

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 8x8 com Max7219 é um módulo relativamente simples de usar, com 3 pinos de controle e alimentação de 5V.

módulo max7219 matriz de leds 8x8

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.

Módulo Max7219 - Detalhe pinagem


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 8x8.

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.

Circuito Arduino Nano e módulo Max7219


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.

Detalhe circuito

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:

Biblioteca Ledcontrol

Com a biblioteca instalada, carregue o programa abaixo no Arduino Nano:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
//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.

Nenhum comentário:

Postar um comentário