Início
/
Projetos Arduino
/
Projetos Squids
/
Básico
/
Projeto 69 - Exibindo frases em uma matriz de LEDs 8 X 8 com Arduino - operadores bit a bit
Projeto 69 - Exibindo frases em uma matriz de LEDs 8 X 8 com Arduino - operadores bit a bit
Angelo Luis Ferreira | 18/10/2019
Acessos: 10.365
Básico - Projeto 69
Otimizando códigos em uma matriz de leds 8 X 8
Objetivo
Mostraremos neste projeto como otimizar códigos para a utilização de uma matriz de leds 8 X 8. Para isto, vamos utilizar a representação binária para cada linha da matriz e através de operadores bitwise (bit a bit) podemos otimizar a programação para facilitar a exibição de letras e símbolos no componente. No projeto anterior, projeto 68, utilizamos muitos códigos para representar a letra "M", por exemplo. Neste tutorial você verá como fazer isso de um forma bem mais simples.
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 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 (anodo comum) | Colunas (catodo comum) - imagem à esquerda
2. Linhas (catodo comum) | Colunas (anodo 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 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 |
|
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.
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 68, a matriz de leds funciona com o cruzamento entre colunas e linhas.
2.Também vimos no projeto anterior que precisávamos utilizar muitas linhas de código para desenhar a letra "M". No exemplo a seguir, vamos demonstrar como exibir a letra "M" em uma matriz de leds de forma otimizada, trabalhando com a representação binária e operadores bitwise.
3. Para identificar as linhas e colunas de cada led aceso, utilizei o Led Matrix Editor.
Obs.: Você poderá utilizar também o Generator for LED MATRIX 8x8.
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.
/*******************************************************************************
*
* Exibindo a letra "M" - Matriz de leds
* 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++) {
digitalWrite(linhas[i], OFF); // liga as linhas
// liga cada coluna em série
for (byte a = 0; a < 8; a++) {
// if You set (~buffer[i] >> a) para inverter para positivo
digitalWrite(colunas[a], (buffer[i] >> 7-a) & 0X01); // liga a coluna com a linha
delayMicroseconds(200); // para alterar a intensidade dos leds (0 a 200)
digitalWrite(colunas[a], OFF); // reset - desliga as colunas
}
digitalWrite(linhas[i], ON); // reset - desliga as linhas
}
}
4.1. Primeiro definimos os array's linhas[] e colunas[] onde definimos os pontos que controlam as linhas e colunas da matriz.
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 11 e retirar a barra de comentários da linha 13.
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 ligar as linhas de 1 a 8, onde:
4.5.3.1. Para i = 0, ligamos a primeira linha através da função digitalWrite(linhas[0], OFF). Desta forma informamos ao Arduino que o pino 13 terá sinal LOW ou zero.
4.5.3.2. Criamos um loop for de o a 7 para indicarmos o cruzamento da linha 1, com as colunas de 1 a 8.
4.5.3.2.1. Através da função digitalWrite(), acionamos a primeira coluna. Vamos fazer os cruzamentos com a linha 1 utilizando os operadores bitwise.
4.5.3.2.1.1. Vamos entender os operadores bitwise utilizados: (buffer[0] >> 7-0) & 0X01:
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".
-> buffer[0] >> 7 => 10000001 >> 7 = 00000001 (na linha 1, deslocamos 7 colunas para a direita, passando o valor da primeira coluna para a última)
-> 00000001 & 0X01 = 00000001 => Portanto na coluna 1 com a linha 1 o sinal é HIGH (00000001) e o led acenderá. Veja abaixo:
4.5.3.2.1.2. Fazendo o mesmo nas demais colunas, teremos os leds acesos nas colunas 1 e 8 com a linha 1.
4.5.3.2.2. Utilizamos a função delay(200) para evitarmos interferências durante multiplexação entre linhas e colunas.
Obs.: Utilize valores entre 20 e 200. Valores maiores poderão gerar um efeito pulsante nos leds.
4.5.3.2.3. Através da função digitalWrite(buffer[a], OFF) desligamos a coluna para a próximo cruzamento entre linha e colunas.
Obs.: Como vimos no projeto anterior, para criarmos novos cruzamentos entre linha e colunas é necessário desligar todas as linhas e colunas da matriz.
4.5.3.3. Utilizando a função digitalWrite(linhas[i], ON) desligamos a linha para os próximos cruzamentos entre linha e colunas.
5. Agora que entendemos como funciona nosso sistema otimizado, vamos construir o nosso projeto para exibir a frase "PROJETOS SQUIDS ARDUINO".
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:
4. No IDE do Arduino, faça a verificação e o upload para o microcontrolador.
Atenção: Observe que deverá aparecer uma aba com o header file alfa.h, como mostra a figura acima. Para visualizar ou alterar o código no IDE basta clicar sobre a aba alfa.h.
5. Para verificar o alfabeto criado pela biblioteca alfa.h, rode o código Arduino abaixo:
/*******************************************************************************
*
* Ler Alfabeto - Matriz de leds 8X8
* 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
const int letters[] = {A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
COL,DASH,BRA2,_,FULL,CHECK,B2,TEMP,LINE,SMILE,DOT,COLDOT};
// CATODO COMUM - LINHA | ANODO COMUM - COLUNA
byte ON = 1, OFF = 0;
// ANODO COMUM - LINHA | CATODO COMUM - COLUNA
//byte ON = 0, OFF = 1;
byte count = 0;
byte timecount = 40; //altere para aumentar ou diminuir a velocidade de exibição
void setup() {
for (int i = 2; i < 18; i++) { // Vai de 2 até 17 definindo os pinos como saida
pinMode(i, OUTPUT);
}
}
void loop() {
while(letters[count] && count<38) {
for (byte a =0; a<=timecount; a++) {
drawScreen(letters[count]);
}
count += 1;
}
count = 0;
}
void drawScreen(int buffer[])
{
// Turn on each row in series
for (byte i = 0; i < 8; i++) { // conta a próxima coluna
digitalWrite(linhas[i], OFF); // liga linhas
for (byte a = 0; a < 8; a++) { // conta a próxima coluna de 0 a 8
// if You set (~buffer[i] >> a) quando querer utilizar invertido
digitalWrite(colunas[a], (buffer[i] >> 7-a) & 0x01); // cruza linha com coluna
delayMicroseconds(200); // teste valores - depende de cada componente
digitalWrite(colunas[a], OFF); // limpa colunas
}
digitalWrite(linhas[i], ON); // limpa linhas
// otherwise last row will intersect with next row
}
}
6. Veja o vídeo abaixo que mostra como deve ficar a exibição do nosso alfabeto criado pela biblioteca alfa.h:
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.".
2. Faça o dowload e abra o arquivo projeto69.ino no IDE do Arduino: DOWNLOAD - projeto69.ino
Ou se preferir, copie e cole o código abaixo no IDE do Arduino:
/*******************************************************************************
*
* Projeto 69 - Usando uma matriz de leds - código otimizado
* Autor: Angelo Luis Ferreira
* Referência: Blog MasterWalker Shop
* Data: 31/10/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
byte timecount = 40; //altere para aumentar ou diminuir a velocidade de exibição
int charachter;
// 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() {
for (byte i = 0; i < sizeof(msg) - 1; i++) {
getChar(msg[i]);
for (byte a =0; a<=timecount; a++) {
drawScreen(charachter);
}
}
delay(1000); // espera 1 segundo
}
void drawScreen(int buffer[]) {
// Turn on each row in series
for (byte i = 0; i < 8; i++) { // conta a próxima coluna
digitalWrite(linhas[i], OFF); // liga linhas
for (byte a = 0; a < 8; a++) { // conta a próxima coluna de 0 a 8
// if You set (~buffer[i] >> a) quando querer utilizar invertido
digitalWrite(colunas[a], (buffer[i] >> 7-a) & 0x01); // cruza linha com coluna
delayMicroseconds(200); // teste valores - depende de cada componente
digitalWrite(colunas[a], OFF); // limpa colunas
}
digitalWrite(linhas[i], ON); // limpa linhas
// otherwise last row will intersect with next row
}
}
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 repetidamente os caracteres da frase "PROJETOS SQUIDS ARDUINO".
Desafios
Com base neste projeto, resolva o seguinte desafio: Desafio 56
O anúncio abaixo ajuda a manter o Squids Arduino funcionando
Comentários