Projeto 70 - Exibindo frases com efeito

Básico - Projeto 70

Efeito scroll em uma matriz de leds

Objetivo

O objetivo deste projeto é criar um algoritmo para gerar um efeito "scroll" na exibição de frases em uma matriz de leds 8 X 8. No Projeto 69 - Exibindo frases em uma matriz de LEDs 8 X 8 com Arduino - operadores bit a bit utilizamos o conceito de operadores bitwise (bit a bit) para gerar caracteres na matriz de leds. Utilizando o mesmo conceito, vamos criar o efeito "scroll", onde os caracteres são deslocados para a esquerda em uma velocidade definida.

Definições

Operadores Bitwise (bit a bit) são utilizados quando precisamos realizar operações a nível de bits com números inteiros, ou seja, trabalhar com sua representação binária. Para saber tudo sobre operadores bitwise, leia o artigo Operadores Bitwise (Bit-a-Bit) do blog Diogo Matheus.

Observação: É muito importante ler o artigo Operadores Bitwise acima para compreender melhor os códigos que apresentaremos neste tutorial. Vamos utilizar no nosso código os operadores bitwise: operador >> (Bitwise right shift), operador << (Bitwise left shift), operador & ( Bitwise AND ) e operador ~ (Bitwise NOT).

Matriz de leds é um componente eletrônico que possui 64 LEDs de 3mm ou 5mm distribuídos em 8 linhas e 8 colunas formando uma matriz quadrada. A matriz de leds é um componente muito utilizado no desenvolvimento de projetos com efeitos visuais, exibição de textos, imagens ou números.

Existem vários modelos de matizes de leds no mercado, mas para a montagem e programação precisamos saber basicamente qual é o tipo organização interna do componente, sendo eles:

1. Linhas (catodo comum) | Colunas (anodo comum) - imagem à esquerda

2. Linhas (anodo comum) | Colunas (catodo comum) - imagem à direita

Obs.: Para você saber qual é a organização interna da matriz de leds é necessário conhecer o datasheet do componente ou fazer um teste prático para identificação que mostraremos mais abaixo neste artigo.

Observações:

1. Neste projeto utilizamos uma matriz de leds 8 X 8, modelo 1088AS com organização interna Linhas (catodo comum) | Colunas (anodo comum).

2. Se você utilizar uma matriz com outro tipo organização interna, ou seja, Linhas (anodo comum) | Colunas (catodo comum), mostraremos como adaptar os códigos para o uso correto neste tipo de componente.

3. Você poderá utilizar no projeto matriz 8 X 8 com leds de 3 mm ou leds de 5 mm de qualquer cor ou dimensão.

4. Recomendamos que você leia o Projeto 68 - Usando uma matriz de LEDs 8 X 8 com Arduino  e Projeto 69 - Exibindo frases em uma matriz de LEDs 8 X 8 com Arduino - operadores bit a bit antes de fazer este tutorial.

Aplicação

Para fins didáticos e projetos com efeitos visuais, exibição de textos, imagens ou números.

Componentes necessários

Referência

Componente

Quantidade

Imagem

Observação

Protoboard Protoboard 830 pontos 1 Resultado de imagem para protoboard 830v

No mínimo utilizar protoboard com 830 pontos

Jumpers Kit cabos ligação macho / macho 1  
 Matriz de led Matrix de LED 8 X 8 modelo 1088AS  

Cor emissão do led: vermelha

Tipo: Linhas catodo / Colunas anodo

Tensão de operação: 2,1V - 2,5V

Corrente máxima: 20mA

Dimensão led: 3mm

(datasheet)

Poderá ser utilizado qualquer modelo de matriz 8 X 8

 Resistor

Resistor de 150Ω

 8   Resistor de 150Ω ou superior
Arduino UNO R3 Arduino UNO 1

Você poderá utilizar uma placa Arduino UNO original ou similar

Montagem do Circuito

Conecte os componentes no Protoboard como mostra a figura abaixo. Verifique cuidadosamente os cabos de ligação antes de ligar seu Arduino. Lembre-se que o Arduino deve estar totalmente desconectado da força enquanto você monta o circuito.

https://blogmasterwalkershop.com.br/wp-content/uploads/2017/02/img03_arduino_utilizando_matriz_de_led_5mm_8x8_matrix_64_leds_letreiro_cascata_max7219.png

imagem obtida do blog Master Walker Shop

Atenção

1. Para a montagem da matriz de leds 8 X 8 é necessário primeiro encontrar a posição correta da matriz. Geralmente a parte de baixo da matriz, onde estão os pinos de 1 a 8, está identificada com o modelo impresso e/ou alguma identificação no componente.

2. Após conhecer a posição correta da matriz faça as conexões com o Arduino, conforme tabela abaixo:

Obs1: Não esqueça de colocar resistores nas linhas da matriz, ou seja, pinos 9, 14, 8, 12, 1, 7, 2 e 5. O resistor deverá ser de 150Ω ou superior.

Obs2: Os pinos 14, 15, 16 e 17 do Arduino UNO são referentes aos pinos A0, A1, A2, A3 do microcontrolador. Lembre-se que os pinos analógicos também podem ser pinos digitais quando definidos pela programação, com exceção dos pino A6 e A7 das placas Arduino Nano, Pro Mini, e Mini, que podem ser usadas apenas como entradas analógicas.

Obs3: Não utilizamos os pinos 0 e 1 do Arduino UNO para evitarmos conflitos no upload e na comunicação serial.

PINO DO ARDUINO PINO DA MATRIZ LINHA OU COLUNA
2 4 (C3) COLUNA 3
3 3 (C2) COLUNA 2
4 2 (R7) LINHA 7
5 1 (R5) LINHA 5
6 16 (C8) COLUNA 8
7 15 (C7) COLUNA 7
8 14 (R2) LINHA 2
9 13 (C1) COLUNA 1
10 12 (R4) LINHA 4
11 11 (C6) COLUNA 6
12 10 (C4) COLUNA 4
13 9 (R1) LINHA 1
14 5 (R8) LINHA 8
15 6 (C5) COLUNA 5
16 7 (R6) LINHA 6
17 8 (R3) LINHA 3

3. Para facilitar a montagem da matriz de leds, recomendo que use 2 protoboards em paralelo, como mostra a figura abaixo:

4. Caso não tenha 2 protoboards, proceda da seguinte forma:

4.1. Conecte cabos para conectar os pinos da matriz com trilhas fora da matriz.

4.2. Após ter conectado os cabos, encaixe a matriz:

5. Conhecendo as características da matriz podemos calcular o valor dos resistores, como sendo:

5.1. Dados da matriz utilizada no projeto (valores retirados da datasheet do componente utilizado):

  • Tensão direta: 2,1 V (p/ segmento)
  • Corrente máxima: 20 mA (p/ segmento)

5.2. Desta forma, utilizando-se a tensão de 5,0V do Arduino, pela lei de Ohms temos:

R = (5,0V - 2,1V) / 0,02A => R = 145 Ω => Portanto, por segurança, utilizaremos um resistor de no mínimo 150 Ω.

5.3 . Se você não tiver os dados do componente, utilize um resistor maior que 150 Ω. Lembre-se, quanto maior o valor do resistor menor será a intensidade do brilho dos leds da matriz.

Atenção: Para evitar danos no componente, não utilize resistores menores que 150 Ω. Para saber mais como calcular o resistor, leia Teste 02 - Leds ligados em série e em paralelo.

Desenhando a letra "M"

1. Como vimos no projeto anterior, projeto 69, a matriz de leds funciona com o cruzamento entre colunas e linhas.

3. Vimos também que para identificar as linhas e colunas de cada led aceso, podemos utilizar o Led Matrix Editor.

Obs.: Também podemos utilizar o Generator for LED MATRIX 8x8 para a identificação dos leds acesos.

4. Veja o código abaixo, onde utilizamos a representação binária e operadores bit a bit para exibirmos a letra "M" em uma matriz de leds. Entretanto, para que este projeto fique mais bacana e a gente possa aprender mais, vamos inverter a posição das letras em relação ao projeto anterior:

a) Projeto anterior (projeto 69) - (posição vertical):

b) Projeto proposto - (posição horizontal)

NOTA: Tanto na a posição vertical ou horizontal das letras, a montagem da matriz de leds com o Arduino é a mesma. O que se altera é apenas a programação, onde mudamos a lógica nos cruzamentos entre linhas e colunas.

Veja abaixo o código para desenhar a letra "M" na nova posição:

/*******************************************************************************
*
*              Exibindo a letra "M" - Matriz de leds
*                      (Posição horizontal)
*                  http://squids.com.br/arduino
*
*******************************************************************************/
int linhas[8] = {13, 8, 17, 10, 5, 16, 4, 14}; // Pinos que controlam as linhas
int colunas[8] = {9, 3, 2, 12, 15, 11, 7, 6}; // Pinos que controlam as colunas

//  CATODO COMUM - LINHA | ANODO COMUM - COLUNA
byte ON = 1, OFF = 0;
// ANODO COMUM - LINHA | CATODO COMUM - COLUNA
//byte ON = 0, OFF = 1;

const byte M[] = {
  B10000001,
  B11100111,
  B10111101,
  B10011001,
  B10000001,
  B10000001,
  B10000001,
  B10000001
};

void setup() {
  for (int i = 2; i < 18; i++) { // Vai de 2 até 17 definindo os pinos do Arduino como saida
    pinMode(i, OUTPUT);
  }
}

void loop() {
  drawScreen(M);
}

void  drawScreen(byte buffer[]){ 
  // liga cada linha em série
  for (byte i = 0; i < 8; i++) {      
    for (byte a = 0; a < 8; a++) {
      digitalWrite(linhas[a], ON); //Desliga todas linhas  
    }
    for(int j = 0; j < 8; j++){  
      if(j == i){
        digitalWrite(colunas[j], ON); } // limpa colunas
      else{ 
        digitalWrite(colunas[j], OFF); } // liga as colunas
      }      
    for(int r = 0; r < 8; r++) { // incrementa r para r de 0 a 7 (row - linha)
      int bit = (buffer[i] >> r) & 1;
      if(bit == 1) { 
        digitalWrite(linhas[r], OFF); // Se o bit no mapa da matriz está definido, acende o led
      }
    }   
  }
}

4.1. Primeiro definimos os array's linhas[] e colunas[] onde definimos os pontos que controlam as linhas e colunas da matriz.

img02_arduino_utilizando_matriz_de_led_5mm_8x8_matrix_64_leds_letreiro_cascata_max7219

4.2. Agora defina o tipo de organização interna da matriz de leds que você estiver utilizando. O código apresentado acima foi criado para uma matriz tipo "linhas (catodo comum) | colunas (anodo comum)".

4.2.1. Se você tiver uma matriz de leds tipo "linhas (anodo comum) | colunas (catodo comum)" basta colocar as duas barras de comentários na linha 12 e retirar as barras de comentários da linha 14.

4.2.2. Se você não sabe qual o tipo da sua matriz de leds, teste o código acima para os dois tipos.

4.3. Definimos a constante M como um array que contém todos valores binários de cada linha da matriz de leds, sendo:

4.3.1. Lembre-se, o prefixo "B" deverá ser incluído em um número binário entre 0 (B0) e 255 (B11111111). Leia Constantes Inteiras - Documentação de Referência Arduino.

4.3.2. Cada componente do array "M" indica uma linha da matriz de leds. Veja o quadro abaixo:

4.3.3. Os valores indicados pelo número 1 são referentes ao sinal digital HIGH e indicam os leds que devem ficar acesos.

4.3. Através da função pinMode() definimos os pinos 2 ao 17 como OUTPUT. Desta forma, em um Arduino UNO, os pinos analógicos A0, A1, A2 e A3 passam a funcionar como pinos digitais 14, 15, 16 e 17.

4.4. Na estrutura void loop() vamos chamar a função drawScreen(M), onde passamos o array denominado M que contém os valores binários de cada linha da matriz de leds.

4.5. Continuando o programa, vamos criar agora a função drawScreen(byte buffer[]) que vai exibir os leds acesos na matriz, sendo:

4.5.1 Como passamos o array "M" para a função drawScreen(), definimos que o array buffer[] é igual a M[].

4.5.2. Através do comando for, vamos:

4.5.2.1. Criar um novo loop for de a= 0 até 7, onde através digitalWrite(colunas[a], ON) ligamos as colunas onde i = j.

4.5.2.1.1. Portanto para i = 0, ligamos a coluna 1, ou seja o pino 9 do Arduino.

4.5.2.1.1. Através do operador "else", definimos as demais colunas 2, 3, 4, 5, 6, 7 e 8 para ficaram desligadas, pois satisfazem o comando digitalWrite(colunas[a], OFF)

4.5.2.2. Criamos um outro loop for pra "r" de o a 7 para indicarmos o cruzamento da coluna 1, com as linhas de 1 a 8.

Nota: Observe que invertemos a forma de cruzamento entre linhas e coluna em relação ao projeto 69. No projeto 69 tínhamos o cruzamento da linha 1 com as colunas de 1 a 8. Desta forma, invertemos a posição de exibição da letras na matriz de leds.

4.5.2.2.1. A variável bit receberá os operadores bitwise, sendo:

Obs.: 1 corresponde a 0X01 na base hexadecimal e 00000001 na base binária. No Arduino devemos expressar um número hexadecimal com o prefixo "0X" e um número binário com o prefixo "B".

 Veja abaixo, onde demonstramos os deslocamentos bitwise para as linhas 1, 2, 3 e 8. Observe que teremos bit = 1 apenas para as linhas 1 e 8.

4.5.2.2.2. Se a variável bit = 1, acenderemos o led que cruza a coluna 1 com a linha 1, através da função digitalWrite(linhas[0], OFF) que envia um sinal LOW ou zero para o Arduino fazendo com que acenda o led.

4.5.2.2.3. Fazendo o mesmo nas demais linhas, teremos os leds acesos nas linhas 1 e 8 com a coluna 1.

Criando o header file "alfa.h" - biblioteca com letras e símbolos

1. Para facilitar nosso trabalho, criamos uma biblioteca com todas letras do nosso alfabeto e alguns símbolos. Você poderá utilizar a nossa biblioteca ou, se desejar, crie a sua própria biblioteca.

2. Para desenhar as letras e obtermos os valores binários utilizamos o Led Matrix Editor como mostrado na figura abaixo:

3. Obtenha o header file alfa.h abaixo e coloque na mesma pasta do sketch no IDE do Arduino:

   DOWNLOAD - alfa.h

Atenção: o arquivo alfa.h deverá estar na mesma pasta onde está o sketch principal:

Sketch do projeto

1. Agora que já vimos como utilizar uma matriz de leds com operadores bitwise e biblioteca com caracteres, vamos ao nosso projeto principal onde exibiremos a frase: "PROJETOS SQUIDS ARDUINO" com 'scroll'.

2. Faça o dowload e abra o arquivo projeto70.ino no IDE do Arduino:  DOWNLOAD - projeto70.ino

Ou se preferir, copie e cole o código abaixo no IDE do Arduino:

/*******************************************************************************
*
*             Projeto 70 - Exibindo frases em scroll através de uma matriz de leds
*             Adaptado por: Angelo Luis Ferreira
*             Referência: Blog MasterWalker Shop
*             Data: 10/12/2019 (dd/mm/AA)
*                  http://squids.com.br/arduino
*
*******************************************************************************/
#include "alfa.h" // incluimos a biblioteca alfa.h

int linhas[8] = {13, 8, 17, 10, 5, 16, 4, 14}; // Pinos que controlam as linhas
int colunas[8] = {9, 3, 2, 12, 15, 11, 7, 6}; // 14 corresponde ao A0 e 15 corresponde ao A1
  
char msg[] = "PROJETOS SQUIDS ARDUINO.";    // Coloque qualquer frase aqui

// Variáveis usadas para rolagem ambas começam em 0
int index = 0;  // Caractere atual a ser mostrado
int shift = 0; // Quantidade de colunas de deslocamento

// Array para armazenar o mapa de bists a ser mostrado 
byte bitsMap[] = {0,0,0,0,0,0,0,0};

// Vetor contendo a potência de 2 para calcular o que mostrar
const int twoPowers[] = {1,2,4,8,16,32,64,128};

byte timecount = 30; //altere para aumentar ou diminuir a velocidade de exibição
int charachter; 
int pause = 500;

//  CATODO COMUM - LINHA | ANODO COMUM - COLUNA
byte ON = 1, OFF = 0;
// ANODO COMUM - LINHA | CATODO COMUM - COLUNA
//byte ON = 0, OFF = 1;

void setup() {
  for (int i = 2; i < 18; i++) { // Vai de 2 até 17 definindo os pinos como saida
    pinMode(i, OUTPUT);;
  }
}

void loop() { 
   loadMatrix(); // carrega mapa de bits da matriz
   showMatrix(timecount);  // mostra mapa com velocidade definida pela variável timecount
}


// Carrega o mapa de bits da matriz
void loadMatrix(){
  getChar(msg[index]); // Lê o caracter corrente da frase
  int currentChar = charachter;
  getChar(msg[index+1]); // Lê o próximo caractere
  int nextChar = charachter;
  executeMatrix(currentChar, nextChar);
}

// Monta o mapa de bits da matriz
void executeMatrix(int currentBuffer[], int nextBuffer[]) { 
  for(int r=0; r < 8; r++){ // incrementa r para r de 0 a 7 (row - linha)
    bitsMap[r] = 0;  // resetar a linha
    for(int c=0; c < 8; c++){ // incrementa c para c de 0 a 7 (column - coluna)
     bitsMap[r] = bitsMap[r] + ((twoPowers[c] & (currentBuffer[r] << shift))); // Carrega o caractere atual compensado pelo deslocamento
     bitsMap[r] = bitsMap[r] + (twoPowers[c] & (nextBuffer[r] >> (8 - shift) ));  // Carrega o próximo caractere compensado pelo deslocamento
    }
  }
  shift++; // incrementa a variável shift responsável pelo deslocamento de um linha
  
  if(shift==8){
    shift = 0; 
    index++; 
    if(index == sizeof(msg)-2){
      index=0;
     }
  } // Se shift for igual a 8, carraga o próximo par de carcateres (currentChar e nextCahr)
}

// Exibe a frase em scroll
void showMatrix (int velShift){
 for(int j = 0; j < velShift; j++){ // incrementa j para j de 0 a velShift (veolocidade do scroll)
  for(int c = 0; c < 8; c++) { //incrementa c para c de 0 a 7 (column - coluna)
   for(int i = 0; i < 8; i++) {              
       digitalWrite(linhas[i], ON); //Desliga todas linhas
   }
   for(int i = 0; i < 8; i++){  
     if(i == c){
      digitalWrite(colunas[i], ON); } // limpa colunas
     else{ 
      digitalWrite(colunas[i], OFF); } // liga as colunas
   }
 
   for(int r = 0; r < 8; r++) { // incrementa r para r de 0 a 7 (row - linha)
    int bit = (bitsMap[c] >> r) & 1;
    if(bit == 1) { 
      digitalWrite(linhas[r], OFF); // Se o bit no mapa da matriz está definido, acende o led
    }
   }
   delayMicroseconds(pause); //INTERVALO DE 500MS                    
  } 
 }
}

void getChar(char msgChar) {
 switch(msgChar){
  case 'A': charachter = A; break;
  case 'a': charachter = A; break;
  case 'B': charachter = B; break;
  case 'b': charachter = B; break;
  case 'C': charachter = C; break;
  case 'c': charachter = C; break;
  case 'D': charachter = D; break;
  case 'd': charachter = D; break;
  case 'E': charachter = E; break;
  case 'e': charachter = E; break;
  case 'F': charachter = F; break;
  case 'f': charachter = F; break;
  case 'G': charachter = G; break;
  case 'g': charachter = G; break;
  case 'H': charachter = H; break;
  case 'h': charachter = H; break;
  case 'I': charachter = I; break;
  case 'i': charachter = I; break;
  case 'J': charachter = J; break;
  case 'j': charachter = J; break;
  case 'K': charachter = K; break;
  case 'k': charachter = K; break;
  case 'L': charachter = L; break;
  case 'l': charachter = L; break;
  case 'M': charachter = M; break;
  case 'm': charachter = M; break;
  case 'N': charachter = N; break;
  case 'n': charachter = N; break;
  case 'O': charachter = O; break;
  case 'o': charachter = O; break;
  case 'P': charachter = P; break;
  case 'p': charachter = P; break;
  case 'Q': charachter = Q; break;
  case 'q': charachter = Q; break;
  case 'R': charachter = R; break;
  case 'r': charachter = R; break;
  case 'S': charachter = S; break;
  case 's': charachter = S; break;
  case 'T': charachter = T; break;
  case 't': charachter = T; break;
  case 'U': charachter = U; break;
  case 'u': charachter = U; break;
  case 'V': charachter = V; break;
  case 'v': charachter = V; break;
  case 'W': charachter = W; break;
  case 'w': charachter = W; break;
  case 'X': charachter = X; break;
  case 'x': charachter = X; break;
  case 'Y': charachter = Y; break;
  case 'y': charachter = Y; break;
  case 'Z': charachter = Z; break;
  case 'z': charachter = Z; break;
  case ' ': charachter = _; break;
  case '3': charachter = B2; break;
  case '<': charachter = TEMP; break;
  case '*': charachter = FULL; break;
  case '|': charachter = LINE; break;  
  case '_': charachter = _; break;  
  case ':': charachter = COL; break;  
  case '-': charachter = DASH; break;  
  case ')': charachter = BRA2; break;  
  case '%': charachter = SMILE; break;  
  case '.': charachter = DOT; break;    
  case '^': charachter = COLDOT; break;      
  }
}

3. Não esqueça de incluir a biblioteca alfa.h no IDE como já mostramos anteriormente.

ATENÇÃO: Se a matriz de leds não acender verifique todas as conexões com o Arduino.

Vídeo

Como o projeto deve funcionar

1. Ao iniciar o programa, a matriz de leds irá exibir com efeito "scroll" os caracteres da frase "PROJETOS SQUIDS ARDUINO".

Desafios

Com base neste projeto, resolva o seguinte desafio: Desafio 57

O anúncio abaixo ajuda a manter o Squids Arduino funcionando

Comentários

×

Infomações do site / SEO








×

Adicionar Marcadores