18 de dezembro de 2011

Matriz de LEDs 8x8

E a experîencia dessa vez foi controlar uma matriz de LEDs.



Foi usado um microcontrolador ATmega328 com bootloader Arduino, dois registradores 74HC595 e uma matriz de LEDs 8x8 com anodo comum.
Pode-se fazer um letreiro e infinitas animações.

A ideia seria mostrar como ampliar o número de saídas do Arduino utilizando registradores de deslocamento. Para cada registrador, você ganha 8 saídas. Nesse caso, temos dois registradores para controlar os 16 pinos da matriz.
Para utilizar mais de uma matriz, o ideal é utilizar um driver de LEDs, mas isso fica para um próximo post.

Segue o código e o esquema elétrico.

Yippie ki-yay!


  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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
/*---------------------------------------------------------
Programa : MATRIZ DE LEDS 8X8
Autor : Fellipe Couto [ http://www.efeitonerd.com.br ]
Data : 17/12/2011
---------------------------------------------------------*/
#include <TimerOne.h> //http://www.arduino.cc/playground/Code/Timer1 int latchPin = 8; //Conectado ao pino 12 do 74HC595. int clockPin = 12; //Conectado ao pino 11 do 74HC595. int dataPin = 11; //Conectado ao pino 14 do 74HC595. byte led[8]; void setup(){ pinMode(latchPin,OUTPUT); pinMode(clockPin,OUTPUT); pinMode(dataPin,OUTPUT); Timer1.initialize(10000); //Timer de 10000 microssegundos (1/100 de um segundo). Timer1.attachInterrupt(screenUpdate); //Anexa a função screenUpdate ao timer de interrupção. } void loop(){ for (int i=0; i<2; i++){ linhaHorizontal(1); linhaVertical(1); linhaHorizontal(2); linhaVertical(2); } quadrados(); explode(); quadros(); coracao(); seta(); pisca(); piscaTudo(); randomico(); } void screenUpdate(){ //Função para exibir a imagem. byte row = B10000000; //Linha 1. for (byte k=0; k<9; k++){ digitalWrite(latchPin,LOW); //Abre o latch, para receber dados. shiftIt(~led[k]); //Envia o array LEDs (invertido). shiftIt(row); //Envia o número binário da linha. digitalWrite(latchPin,HIGH); //Fecha o latch, para enviar os dados do registrador para a matriz. row = row>>1; //Deslocamento para direita. } } void shiftIt(byte dataOut){ //Desloca 8 bits, com o menos significativo deslocado primeiro, durante o extremo ascendente do clock. boolean pinState; digitalWrite(dataPin,LOW); //Libera o registrador , deixando-o pronto para enviar dados. for (int i=0; i<8; i++){ //Para cada bit em dataOut, envia um bit. digitalWrite(clockPin,LOW); //Define clockPin como LOW, antes de enviar o bit. //Se o valor de dataOut e (E lógico) de uma mascara de bits forem verdadeiros, defina pinState como 1 (HIGH) if (dataOut & (1<<i)){ pinState = HIGH; } else{ pinState = LOW; } digitalWrite(dataPin,pinState); //Define dataPin como HIGH ou LOW, dependendo de pinState. digitalWrite(clockPin,HIGH); //Envia o bit no extremo ascendente do clock. digitalWrite(dataPin,LOW); } digitalWrite(clockPin,LOW); //Interrompe o deslocamento de dados. } void linhaHorizontal(int x){ switch (x){ case 1: //x = 1 (Desce) for (int j=0; j<8; j++){ for (int i=0; i<8; i++){ if (i==j){ led[i] = B11111111; } else{ led[i] = B00000000; } } delay(40); } break; case 2: //x = 1 (Sobe) for (int j=8; j>=0; j--){ for (int i=0; i<8; i++){ if (i==j){ led[i] = B11111111; } else{ led[i] = B00000000; } } delay(40); } break; } } void linhaVertical(int x){ switch (x){ case 1: //x = 1 (Direita) for (int j=0; j<8; j++){ for (int i=0; i<8; i++){ switch (j){ case 0: led[i] = B10000000; break; case 1: led[i] = B01000000; break; case 2: led[i] = B00100000; break; case 3: led[i] = B00010000; break; case 4: led[i] = B00001000; break; case 5: led[i] = B00000100; break; case 6: led[i] = B00000010; break; case 7: led[i] = B00000001; break; } } delay(40); } break; case 2: //x = 2 (Esquerda) for (int j=8; j>=0; j--){ for (int i=0; i<8; i++){ switch (j){ case 0: led[i] = B10000000; break; case 1: led[i] = B01000000; break; case 2: led[i] = B00100000; break; case 3: led[i] = B00010000; break; case 4: led[i] = B00001000; break; case 5: led[i] = B00000100; break; case 6: led[i] = B00000010; break; case 7: led[i] = B00000001; break; } } delay(40); } break; } } void quadrados(){ int tempo = 100; for (int i=0; i<20; i++){ //Quadro 1 for (int j=0; j<4; j++){ led[j] = B11110000; } for (int j=4; j<8; j++){ led[j] = B00000000; } delay(tempo); //Quadro 2 for (int j=0; j<4; j++){ led[j] = B00001111; } for (int j=4; j<8; j++){ led[j] = B00000000; } delay(tempo); //Quadro 3 for (int j=0; j<4; j++){ led[j] = B00000000; } for (int j=4; j<8; j++){ led[j] = B00001111; } delay(tempo); //Quadro 4 for (int j=0; j<4; j++){ led[j] = B00000000; } for (int j=4; j<8; j++){ led[j] = B11110000; } delay(tempo); tempo -= 5; } } void explode(){ int tempo = 80; for (int j=0; j<10; j++){ for (int i=0; i<8; i++){ led[i] = B00000000; } delay(tempo); //----------------- led[0] = B00000000; led[1] = B00000000; led[2] = B00000000; led[3] = B00011000; led[4] = B00011000; led[5] = B00000000; led[6] = B00000000; led[7] = B00000000; delay(tempo); //----------------- led[0] = B00000000; led[1] = B00000000; for (int i=3; i<6; i++){ led[i] = B00111100; } led[6] = B00000000; led[7] = B00000000; delay(tempo); //----------------- led[0] = B00000000; for (int i=1; i<7; i++){ led[i] = B01111110; } led[7] = B00000000; delay(tempo); //----------------- for (int i=0; i<8; i++){ led[i] = B11111111; } delay(tempo); } } void quadros(){ int tempo = 200; for (int j=0; j<10; j++){ led[0] = B11111111; led[1] = B10000001; led[2] = B10111101; led[3] = B10100101; led[4] = B10100101; led[5] = B10111101; led[6] = B10000001; led[7] = B11111111; delay(tempo); //----------------- for (int i=0; i<8; i++){ led[i] = ~led[i]; } delay(tempo); } } void coracao(){ int tempo = 300; for (int j=0; j<5; j++){ led[0] = B01100110; led[1] = B11111111; led[2] = B11111111; led[3] = B11111111; led[4] = B11111111; led[5] = B01111110; led[6] = B00111100; led[7] = B00011000; delay(tempo); //----------------- for (int i=0; i<8; i++){ led[i] = B00000000; } delay(tempo/2); } } void seta(){ int tempo = 200; for (int j=0; j<10; j++){ //Pra cima. led[0] = B00011000; led[1] = B00111100; led[2] = B01111110; led[3] = B00011000; led[4] = B00011000; led[5] = B00011000; led[6] = B00011000; led[7] = B00011000; delay(tempo); //----------------- //Pra esquerda. led[0] = B00000000; led[1] = B00100000; led[2] = B01100000; led[3] = B11111111; led[4] = B11111111; led[5] = B01100000; led[6] = B00100000; led[7] = B00000000; delay(tempo); //----------------- //Pra baixo. led[0] = B00011000; led[1] = B00011000; led[2] = B00011000; led[3] = B00011000; led[4] = B00011000; led[5] = B01111110; led[6] = B00111100; led[7] = B00011000; delay(tempo); //----------------- //Pra direita. led[0] = B00000000; led[1] = B00000100; led[2] = B00000110; led[3] = B11111111; led[4] = B11111111; led[5] = B00000110; led[6] = B00000100; led[7] = B00000000; delay(tempo); tempo -= 10; } } void pisca(){ int tempo = 200; for (int j=0; j<30; j++){ led[0] = B10101010; led[1] = B01010101; led[2] = B10101010; led[3] = B01010101; led[4] = B10101010; led[5] = B01010101; led[6] = B10101010; led[7] = B01010101; delay(tempo); for (int i=0; i<8; i++){ led[i] = ~led[i]; } delay(tempo); tempo -= 5; } } void piscaTudo(){ int tempo = 50; for (int j=0; j<30; j++){ for (int i=0; i<8; i++){ led[i] = B11111111; } delay(tempo); for (int i=0; i<8; i++){ led[i] = B00000000; } delay(tempo); } } void randomico(){ int tempo = 70; int p = 0; randomSeed(analogRead(0)); //Para o random ficar aleatorio, sem repetir a sequencia. for (int i=0; i<40; i++){ p = random(200); led[0] = p; p = random(200); led[1] = p; p = random(100); led[2] = p; p = random(200); led[3] = p; p = random(100); led[4] = p; p = random(200); led[5] = p; p = random(100); led[6] = p; p = random(200); led[7] = p; delay(tempo); } }

19 comentários:

  1. Olá. Muito bom seu blog!
    Poderia fazer uma função para exibir texto?
    Eu consegui esse exemplo mas ele nao usa o 74HC595.
    Mas voce pode adaptar a funcao e aproveitar o mapa das letras para o seu código.
    http://oomlout.com/8X8M/8X8M-ScrollMessage.txt
    Favor me comunicar por e-mail caso consiga: sharkpolo@hotmail.com
    Obrigado

    ResponderExcluir
  2. Amigo, dá uma ajuda pra outro amigo, já conseguir fazer as letras,
    mas não consigo fazer o scrool das mesma, dá uma luz. No aguardo meu email,
    domingosjff@gmail.com. obrigado e seu blog é nota 10, de grande ajuda pra iniciantes no arduino.

    ResponderExcluir
  3. DEU ERRO ?! eu baxei o TimerOne-v9.zip, até ai tudo certo ^^ ....

    Binary sketch size: 4.488 bytes (of a 32.256 byte maximum)
    avrdude: stk500_recv(): programmer is not responding


    Meu e-mail: engenheirogenio@hotmail.com

    ResponderExcluir
    Respostas
    1. Binary sketch size: 4.488 bytes (of a 32.256 byte maximum)
      avrdude: stk500_recv(): programmer is not responding

      Excluir
    2. Boa tarde, Luís Henrique!
      Esse erro costuma ser problema com a conexão entre Arduino e o pc. Você testou com outro pc?! Dei uma pesquisada aqui, e sobre esse erro, só encontrei duas coisas: Conexão serial entre Arduino e pc ou problema com o bootloader do Arduino. Nunca tive problemas com esse erro.
      Dá uma olhada se não é a conexão serial.
      Abraços!

      Excluir
    3. eu usando o arduino atmega2560 , fica a mesma coisa?!?!

      Excluir
    4. Desde que esteja usando as mesmas portas do arduino, o código poderia se manter o mesmo. Abraços!

      Excluir
  4. muinto bom mesmo show de bola ,como faço para ampliar mais com 4ci

    ResponderExcluir
    Respostas
    1. Boa tarde! Uma forma seria cascateando, assim como já estão o CI 1 e 2. Abraços!

      Excluir
  5. Este comentário foi removido pelo autor.

    ResponderExcluir
  6. NERD, como faço pra colocar 3- matrizes de leds com 6- 74hc595? aguardo retorno e obrigado pela atenção. tchau

    ResponderExcluir
  7. Fellipe, eu tenho o módulo de matriz montada com o MAX7219 - eu posso usar esse seu código?
    obrigado

    ResponderExcluir
  8. Boa noite, de cara eu quero te agradecer, seu blog me tirou muitas dúvidas e fez com que eu conseguisse fazer "funcionar" a minha matrix de LED 8x8 com driver 74HC595, na verdade 4 matrix. Estou tendo difuldades com o código para scrll de texto. Você poderia me enviar o sketch? com texto simples, como "FELIZ ANO NOVO".
    MEU E-MAIL: ROBERTOCARLOSALVARENGA@HOTMAIL.COM

    muito obrigado...

    ResponderExcluir
  9. Parabéns pelos projetos, você é fera Felipe!

    ResponderExcluir
  10. Oi Fellipe! Muito legal seus projetos;
    Uma sugestão: você fazer um projeto com rolagem de texto em várias matrizes de LED bicolor (verde & vermelha); obrigado

    ResponderExcluir
    Respostas
    1. Olá! Que bom que gostou dos projetos!
      Sugestão anotada!
      Abraços!!

      Excluir