Neste tutorial, vamos aprender a controlar as matrices LED de 8×8 com Arduino, em concreto vamos usar os módulos que levam o driver MAX7219, e para controlá-los vamos usar um par de livrarias muito úteis que nos vão facilitar muito o trabalho.
O que faremos será mostrar um texto em scroll usando uma das livrarias, e a outra livraria vamos usar para mostrar um desenho ou um personagem que vamos desenhar nós mesmos. No final do tutorial, vai ver um link para descarregar uma aplicação desenhada para criar padrões (desenhos) para estas matrices de LEDs fizemos nós e é grátis.
Componentes necessários para o projeto
Para o desenvolvimento deste tutorial vamos precisar dos seguintes componentes:
- 1x Arduino UNO
- 2x Matriz LED de 8×8 MAX7219
- 10x Cabos para protoboard
Ligação dos módulos
A ligação dos módulos é muito fácil e realiza-se através de uma porta de série assíncrona SPI, os pinos estão marcados na placa. O pino VCC e GND são os cabos de alimentação e são ligados diretamente ao Arduino aos pinos 5V e GND respetivamente. O pino DIN do módulo é conectado ao pino 8 do Arduino, o pino CLK ao pino 10 e o pino CS ao pino 9 do Arduino.
Para ligar mais módulos, vamos usar a saída que há na parte superior de cada módulo para ligar com a entrada do outro módulo, para mais detalhes veja a imagem do esquema.
Como mostrar texto em scroll
Para começar vamos mostrar um texto em scroll lateral. Para comunicarmos com o módulo, vamos usar a livraria MaxMatrix.h, descarregámo-la usando o link em baixo e descomprimimos na pasta Livrarias da nossa instalação do IDE de Arduino.
O primeiro que fazemos é declarar todos os caracteres possíveis (A-Z e 0-9) como valores binários e, em vez de declará-los como variáveis e colapsar a SRAM, o que faremos é colocar esses dados na memória flash (memória de programa) usando o modificador de variável PROGMEM já que são dados fixos que não variam. A seguir mostramos o sketch que está ligado para que seja muito fácil de entender.
#include <maxmatrix.h> #include <pgmspace.h> // DEFINIMOS TODOS OS CARACTERES POSSIVEIS NUM ARRAY // CARREGAMO-LOS NA MEMÓRIA DE PROGRAMA COM PROGMEM PROGMEM const unsigned char CH[] = { 3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // espaço 1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // ! 3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // " 5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // # 4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $ 5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // % 5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // & 1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // ' 3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // ( 3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // ) 5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // * 5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // + 2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // , 4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // - 2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // . 4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // / 4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0 3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1 4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2 4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3 4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4 4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5 4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6 4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7 4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8 4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9 2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // : 2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ; 3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // < 3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // = 3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // > 4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ? 5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @ 4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A 4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B 4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C 4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D 4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E 4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F 4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G 4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H 3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I 4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J 4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K 4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L 5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M 5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N 4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O 4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P 4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q 4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R 4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S 5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T 4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U 5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V 5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W 5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X 5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y 4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z 2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [ 4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ 2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ] 3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // chapéu 4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _ 2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // ` 4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a 4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b 4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c 4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d 4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e 3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f 4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g 4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h 3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i 4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j 4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k 3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l 5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m 4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n 4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o 4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p 4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q 4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r 4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s 3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t 4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u 5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v 5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w 5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x 4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y 3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z 3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // { 1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // | 3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // } 4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~ }; // DEFINIMOS OS PINOS DO ARDUINO int data = 8; // Pino DIN do módulo MAX7219 int load = 9; // Pino CS do módulo MAX7219 int clock = 10; // Pino CLK do módulo MAX7219 // QUANTOS MÓDULOS TEMOS CONECTADOS NA SERIE? int maxInUse = 2; // DEFINIMOS A FUNÇÃO DE CADA PINO MaxMatrix m(data, load, clock, maxInUse); byte buffer[10]; // ESTA É A VARIÁVEL QUE CONTEM O TEXTO QUE APARECERÁ NOS DISPLAYS char string1[] = "Isto é um teste de texto em scroll "; void setup(){ m.init(); // INICIAMOS O MÓDULO m.setIntensity(5); // DEFINIMOS A INTENSIDADE DOS LEDs (0-15) } void loop(){ byte c; delay(100); // PAUSA ENTRE MOVIMENTOS m.shiftLeft(false, true); printStringWithShift(string1, 100); // ENVIAMOS O TEXTO AOS MÓDULOS } // FUNÇÕES PARA MOSTRAR OS CARACTERES NO DISPLAY DOS MÓDULOS void printCharWithShift(char c, int shift_speed){ if (c < 32) return; c -= 32; memcpy_P(buffer, CH + 7*c, 7); m.writeSprite(maxInUse*8, 0, buffer); m.setColumn(maxInUse*8 + buffer[0], 0); for (int i=0; i<buffer[0]+1; i++) { delay(shift_speed); m.shiftLeft(false, false); } } void printStringWithShift(char* s, int shift_speed){ while (*s != 0){ printCharWithShift(*s, shift_speed); s++; } }
Mostrar desenhos ou padrões
Usar matrices de leds no nosso projeto é uma boa forma de incorporar sinais de aviso, alertas de estado ou simplesmente animações engraçadas. Neste caso vamos ver como alterar imagens para criar uma animação simples de 2 frames usando a livraria LEDControl.h.
Tal como na outra livraria, descrregamo-la e descomprimimos na pasta Livrarias da inatalação do IDE do Arduino. O código está comentado para que seja fácil de entender. Aqui está o link para ser descarregado:
DESCARREGAR LIVRARIA LEDCONTROL
//Incluimos a livraria LedControl.h #include "LedControl.h" //Declaramos os pinos: DIN, CLK, CS y el nº de displays conectados em serie LedControl lc=LedControl(8,10,9,2); //Pausa entre frames unsigned long delayTime=900; //Codigo dos 2 frames que vamos mostrar: //Coração pequeno byte Heart1[] = { B00000000, B01100110, B11111111, B11111111, B01111110, B00111100, B00011000, B00000000}; //Coração grande byte Heart2[] = { B01100110, B11111111, B11111111, B11111111, B11111111, B01111110, B00111100, B00011000}; //Sub para transformar array #1 num padrão para a matriz void Heart1GO() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Heart1[i]); lc.setRow(1,i,Heart2[i]); } } //Sub para transformar array #2 num padrão para a matriz void Heart2GO() { for (int i = 0; i < 8; i++) { lc.setRow(0,i,Heart2[i]); lc.setRow(1,i,Heart1[i]); } } //Esta sub vai-se executar 1 só vez ao arrancar o Arduino void setup() { lc.shutdown(0,false); //Iniciamos a matriz led #1 lc.shutdown(1,false); //Iniciamos a matriz led #2 lc.setIntensity(0,5); //Intensidade dos led na matriz #1 lc.setIntensity(1,5); //Intensidade dos led na matriz #2 lc.clearDisplay(0); //Apagamos todos os led da matriz #1 lc.clearDisplay(1); //Apagamos todos os led da matriz #2 } //Esta sub vai-se executar num laço uma e outra vez enquanto o Arduino esteja alimentado. void loop() { Heart1GO(); //Mostramos o padrão #1 delay(delayTime); //Pequena pausa Heart2GO(); //Mostramos o padrão #2 delay(delayTime); //Pequena pausa }
Criando padrões em binário
Como já vimos nos exemplos anteriores, cada digito ou caracter é composto de um código em binário que define o estado de cada led da matriz. Para gerar estes códigos de forma fácil e rápida, desenhamos uma pequena aplicação para Windows baseada numa ferramenta online que descobrimos há algum tempo.
Como se pode ver na imagem, está formado por uma matriz de 8×8 checkboxes, cada checkbox define o estado de 1 led da matriz. Para gerar um padrão, marcamos os checkbox desejados até confirmar uma imagem ao estilo pixel art. Na seguinte imagem vê-se um coração gerado pelo programa.
Podemos gerar os nosso próprios padrões para integrá-los em qualquer sketch de forma fácil e lembre-se, se o checkbox está marcado o led vai estar ativado na matriz.
Todos os produtos utilizados neste artigo podem ser encontrados na Loja de Eletrónica e Robótica – ElectroFun.
Gostaram deste artigo? Deixem o vosso comentário no formulário a baixo e partilhem com os vossos amigos.
Não se esqueçam de fazer like na nossa Página no Facebook.
Podem ainda colocar as vossas dúvidas no nosso Forum da Comunidade Arduino em Portugal ou no nosso Grupo no Facebook Arduino Portugal – Qual o teu projeto?