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!
/*---------------- MATRIZ DE LED 8x8 Fellipe Couto 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); } }
Olá. Muito bom seu blog!
ResponderExcluirPoderia 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
Amigo, dá uma ajuda pra outro amigo, já conseguir fazer as letras,
ResponderExcluirmas 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.
DEU ERRO ?! eu baxei o TimerOne-v9.zip, até ai tudo certo ^^ ....
ResponderExcluirBinary sketch size: 4.488 bytes (of a 32.256 byte maximum)
avrdude: stk500_recv(): programmer is not responding
Meu e-mail: engenheirogenio@hotmail.com
Binary sketch size: 4.488 bytes (of a 32.256 byte maximum)
Excluiravrdude: stk500_recv(): programmer is not responding
Boa tarde, Luís Henrique!
ExcluirEsse 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!
eu usando o arduino atmega2560 , fica a mesma coisa?!?!
ExcluirDesde que esteja usando as mesmas portas do arduino, o código poderia se manter o mesmo. Abraços!
Excluirmuinto bom mesmo show de bola ,como faço para ampliar mais com 4ci
ResponderExcluirBoa tarde! Uma forma seria cascateando, assim como já estão o CI 1 e 2. Abraços!
ExcluirEste comentário foi removido pelo autor.
ResponderExcluirNERD, como faço pra colocar 3- matrizes de leds com 6- 74hc595? aguardo retorno e obrigado pela atenção. tchau
ResponderExcluirFellipe, eu tenho o módulo de matriz montada com o MAX7219 - eu posso usar esse seu código?
ResponderExcluirobrigado
Boa noite! Esse código ta pro 595 mesmo.
ExcluirEntão, o que teria que ser mudado no código?
ExcluirObrigado
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".
ResponderExcluirMEU E-MAIL: ROBERTOCARLOSALVARENGA@HOTMAIL.COM
muito obrigado...
Parabéns pelos projetos, você é fera Felipe!
ResponderExcluirObrigado!!! Abraços!!
ExcluirOi Fellipe! Muito legal seus projetos;
ResponderExcluirUma sugestão: você fazer um projeto com rolagem de texto em várias matrizes de LED bicolor (verde & vermelha); obrigado
Olá! Que bom que gostou dos projetos!
ExcluirSugestão anotada!
Abraços!!