



Já foram abordados, em nosso blog, três dos principais displays existentes no mercado: LCD, display de 7 segmentos e Display OLED. Neste post, abordaremos os três tipos de displays, suas diferenças e semelhanças, usos no dia a dia e, até mesmo, projetos individuais para você fazer em sua casa.
Neste guia, sempre falaremos do LCD 16x2 com Backlight Azul, quando falamos em LCD. Além disso, quando vamos usá-lo com o Arduino, o mais comum é vermos o 16x2. Mas, abaixo estão os links de outras versões.
Como dito antes, é possível ver, na imagem acima, que cada segmento do Display de 7 segmentos é formado por um LED. Quando acionamos cada segmento, é possível formar letras e números, mas com algumas limitações. Se pensarmos mais a fundo sobre como ele funciona, a explicação é bastante simples. Olhando a imagem acima, podemos ver que os segmentos são identificados de A a G, mais o DP como ponto decimal.
Com a tecnologia OLED é possível reproduzir imagens, vídeos, textos e muito mais, tornando-a uma tecnologia muito atraente e muito usada no mercado de entretenimento doméstico nos últimos anos. Para fazer essa análise, todos os dados serão extraídos da nossa loja https://www.eletrogate.com/ e do nosso Blog https://blog.eletrogate.com/.
O LCD, para funcionar, está com os seus LED's ligados a todo momento. Mas, o líquido dentro do Display só deixa passar luz se aplicarmos corrente elétrica, como disse anteriormente. Pensando no LCD com LED e Backlight ativos, seu consumo de energia dispara na frente dos demais. Apesar do display de 7 Segmentos emitir mais brilho que os demais, ele ainda fica atrás em consumo para o Display anterior, conforme explicado acima. Por último, temos o OLED. Pensando no exemplo anterior e, ainda, adicionando o fato de que, os displays OLED's não precisam de luz de fundo como o LCD, eles economizam bastante energia e se tornam mais econômicos dentre os três.
Se tiver alguma dúvida ou quiser ver as informações mais completas, acesse o post Jogo em LCD no Arduino.
A montagem deste projeto é muito simples. Lembrando que o display irá exibir o nosso jogo, o push botton irá realizar uma ação e o potenciômetro irá regular a intensidade luminosa do display.
#include <LiquidCrystal.h>
#define PIN_BUTTON 2
#define PIN_AUTOPLAY 1
#define PIN_READWRITE 10
#define PIN_CONTRAST 12
#define SPRITE_RUN1 1
#define SPRITE_RUN2 2
#define SPRITE_JUMP 3
#define SPRITE_JUMP_UPPER '.' // Use o caractere '.' para a cabea
#define SPRITE_JUMP_LOWER 4
#define SPRITE_TERRAIN_EMPTY ' '
#define SPRITE_TERRAIN_SOLID 5
#define SPRITE_TERRAIN_SOLID_RIGHT 6
#define SPRITE_TERRAIN_SOLID_LEFT 7
#define HERO_HORIZONTAL_POSITION 1 // Posição horizontal do jogador na tela
#define TERRAIN_WIDTH 16
#define TERRAIN_EMPTY 0
#define TERRAIN_LOWER_BLOCK 1
#define TERRAIN_UPPER_BLOCK 2
#define HERO_POSITION_OFF 0 // O jogador está invisível
#define HERO_POSITION_RUN_LOWER_1 1 // Jogador está correndo na linha de baixo (pose 1)
#define HERO_POSITION_RUN_LOWER_2 2 // (pose 2)
#define HERO_POSITION_JUMP_1 3 // Começando a pular
#define HERO_POSITION_JUMP_2 4 // Metado do caminha pra cima
#define HERO_POSITION_JUMP_3 5 // Pulo está na linha de cima
#define HERO_POSITION_JUMP_4 6 // Pulo está na linha de cima
#define HERO_POSITION_JUMP_5 7 // Pulo está na linha de cima
#define HERO_POSITION_JUMP_6 8 // Pulo está na linha de cima
#define HERO_POSITION_JUMP_7 9 // Metado do caminho pra baixo
#define HERO_POSITION_JUMP_8 10 // Quase aterrisando
#define HERO_POSITION_RUN_UPPER_1 11 // O jogador está correndo na linha de cima (pose 1)
#define HERO_POSITION_RUN_UPPER_2 12 // (pose 2)
LiquidCrystal lcd(11, 9, 6, 5, 4, 3);
static char terrainUpper[TERRAIN_WIDTH + 1];
static char terrainLower[TERRAIN_WIDTH + 1];
static bool buttonPushed = false;
void initializeGraphics(){
static byte graphics[] = {
// Run position 1
B01100,
B01100,
B00000,
B01110,
B11100,
B01100,
B11010,
B10011,
// Run position 2
B01100,
B01100,
B00000,
B01100,
B01100,
B01100,
B01100,
B01110,
// Jump
B01100,
B01100,
B00000,
B11110,
B01101,
B11111,
B10000,
B00000,
// Jump lower
B11110,
B01101,
B11111,
B10000,
B00000,
B00000,
B00000,
B00000,
// Ground
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
// Ground right
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
B00011,
// Ground left
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
};
int i;
// Skip using character 0, this allows lcd.print() to be used to
// quickly draw multiple characters
for (i = 0; i < 7; ++i) {
lcd.createChar(i + 1, &graphics[i * 8]);
}
for (i = 0; i < TERRAIN_WIDTH; ++i) {
terrainUpper[i] = SPRITE_TERRAIN_EMPTY;
terrainLower[i] = SPRITE_TERRAIN_EMPTY;
}
}
// Slide the terrain to the left in half-character increments
//
void advanceTerrain(char* terrain, byte newTerrain){
for (int i = 0; i < TERRAIN_WIDTH; ++i) {
char current = terrain[i];
char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1];
switch (current){
case SPRITE_TERRAIN_EMPTY:
terrain[i] = (next == SPRITE_TERRAIN_SOLID) ? SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY;
break;
case SPRITE_TERRAIN_SOLID:
terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID;
break;
case SPRITE_TERRAIN_SOLID_RIGHT:
terrain[i] = SPRITE_TERRAIN_SOLID;
break;
case SPRITE_TERRAIN_SOLID_LEFT:
terrain[i] = SPRITE_TERRAIN_EMPTY;
break;
}
}
}
bool drawHero(byte position, char* terrainUpper, char* terrainLower, unsigned int score) {
bool collide = false;
char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION];
char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION];
byte upper, lower;
switch (position) {
case HERO_POSITION_OFF:
upper = lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_LOWER_1:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_RUN1;
break;
case HERO_POSITION_RUN_LOWER_2:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_RUN2;
break;
case HERO_POSITION_JUMP_1:
case HERO_POSITION_JUMP_8:
upper = SPRITE_TERRAIN_EMPTY;
lower = SPRITE_JUMP;
break;
case HERO_POSITION_JUMP_2:
case HERO_POSITION_JUMP_7:
upper = SPRITE_JUMP_UPPER;
lower = SPRITE_JUMP_LOWER;
break;
case HERO_POSITION_JUMP_3:
case HERO_POSITION_JUMP_4:
case HERO_POSITION_JUMP_5:
case HERO_POSITION_JUMP_6:
upper = SPRITE_JUMP;
lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_UPPER_1:
upper = SPRITE_RUN1;
lower = SPRITE_TERRAIN_EMPTY;
break;
case HERO_POSITION_RUN_UPPER_2:
upper = SPRITE_RUN2;
lower = SPRITE_TERRAIN_EMPTY;
break;
}
if (upper != ' ') {
terrainUpper[HERO_HORIZONTAL_POSITION] = upper;
collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true;
}
if (lower != ' ') {
terrainLower[HERO_HORIZONTAL_POSITION] = lower;
collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true;
}
byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1;
// Draw the scene
terrainUpper[TERRAIN_WIDTH] = '\0';
terrainLower[TERRAIN_WIDTH] = '\0';
char temp = terrainUpper[16-digits];
terrainUpper[16-digits] = '\0';
lcd.setCursor(0,0);
lcd.print(terrainUpper);
terrainUpper[16-digits] = temp;
lcd.setCursor(0,1);
lcd.print(terrainLower);
lcd.setCursor(16 - digits,0);
lcd.print(score);
terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave;
terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave;
return collide;
}
// Handle the button push as an interrupt
void buttonPush() {
buttonPushed = true;
}
void setup(){
pinMode(PIN_READWRITE, OUTPUT);
digitalWrite(PIN_READWRITE, LOW);
pinMode(PIN_CONTRAST, OUTPUT);
digitalWrite(PIN_CONTRAST, LOW);
pinMode(PIN_BUTTON, INPUT);
digitalWrite(PIN_BUTTON, HIGH);
pinMode(PIN_AUTOPLAY, OUTPUT);
digitalWrite(PIN_AUTOPLAY, HIGH);
// Digital pin 2 maps to interrupt 0
attachInterrupt(0/*PIN_BUTTON*/, buttonPush, FALLING);
initializeGraphics();
lcd.begin(16, 2);
}
void loop(){
static byte heroPos = HERO_POSITION_RUN_LOWER_1;
static byte newTerrainType = TERRAIN_EMPTY;
static byte newTerrainDuration = 1;
static bool playing = false;
static bool blink = false;
static unsigned int distance = 0;
if (!playing) {
drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower, distance >> 3);
if (blink) {
lcd.setCursor(0,0);
lcd.print("Press Start");
}
delay(250);
blink = !blink;
if (buttonPushed) {
initializeGraphics();
heroPos = HERO_POSITION_RUN_LOWER_1;
playing = true;
buttonPushed = false;
distance = 0;
}
return;
}
// Shift the terrain to the left
advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
// Make new terrain to enter on the right
if (--newTerrainDuration == 0) {
if (newTerrainType == TERRAIN_EMPTY) {
newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK;
newTerrainDuration = 2 + random(10);
} else {
newTerrainType = TERRAIN_EMPTY;
newTerrainDuration = 10 + random(10);
}
}
if (buttonPushed) {
if (heroPos <= HERO_POSITION_RUN_LOWER_2) heroPos = HERO_POSITION_JUMP_1;
buttonPushed = false;
}
if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) {
playing = false; // The hero collided with something. Too bad.
} else {
if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) {
heroPos = HERO_POSITION_RUN_LOWER_1;
} else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) {
heroPos = HERO_POSITION_RUN_UPPER_1;
} else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) {
heroPos = HERO_POSITION_JUMP_5;
} else if (heroPos == HERO_POSITION_RUN_UPPER_2) {
heroPos = HERO_POSITION_RUN_UPPER_1;
} else {
++heroPos;
}
++distance;
digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 2] == SPRITE_TERRAIN_EMPTY ? HIGH : LOW);
}
delay(100);
}
Para este projeto, trouxe algo simples, mas que irá ajudar muito no seu aprendizado sobre este display. Abaixo, o post completo em nosso blog:
Projetos Arduino para Iniciantes
Neste projeto, utilizamos o Arduino Uno e o Display de 7 Segmentos para mostrar os números de 0 a 9. Este projeto não é complicado e ajuda na sua compressão sobre este componente eletrônico.
#define A 12 //
#define B 13 // define o pino respectivo
#define C 7 // a cada led
#define D 8 //
#define E 9 //
#define F 11 //
#define G 10 //
#define QTD_SEG 7 //quantidade de leds
#define QTD_CHAR 10 //quantidade de dígitos
int seg[] = {A, B, C, D, E, F, G}; //vetor referente aos pinos
int contador; //usado para definir qual dígito será mostrado
bool num[][10] = { {1, 1, 1, 1, 1, 1, 0}, // mapeia
{0, 1, 1, 0, 0, 0, 0}, // cada
{1, 1, 0, 1, 1, 0, 1}, // dígito
{1, 1, 1, 1, 0, 0, 1}, // à respectiva
{0, 1, 1, 0, 0, 1, 1}, // combinação
{1, 0, 1, 1, 0, 1, 1}, // de leds
{1, 0, 1, 1, 1, 1, 1}, // acesos
{1, 1, 1, 0, 0, 0, 0}, //
{1, 1, 1, 1, 1, 1, 1}, //
{1, 1, 1, 1, 0, 1, 1} }; //
void setup() {
contador = 0; //inicia o contador
for(int i = 0; i < QTD_SEG; i ++)
pinMode(seg[i], OUTPUT); //inicia os pinos
}
void loop() {
for(int i = 0; i < QTD_SEG; i ++)
digitalWrite(seg[i], num[contador][i]); //exibe os dígitos
contador = contador == 9 ? 0 : contador + 1; //trata o contador
delay(1000);
} Este projeto será 100% baseado em um post do nosso blog “Guia Completo do Display OLED (parte 2) – Como programar“. Então, fique à vontade para conferir este material completo nas referências no final deste post.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSerif12pt7b.h>
Adafruit_SSD1306 display(-1);
void setup()
{
// Inicializa com o I2C addr 0x3C
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}
void loop() {
// Limpa o display
display.clearDisplay();
// Texto no display
display.setTextSize(1); // Fonte do texto
display.setTextColor(WHITE); // Cor do texto
display.setCursor(0,28); // Posiciona o cursor
display.println("Display OLED"); // Imprime mensagem
display.display();
delay(2000);
display.clearDisplay();
// Mudar a fonte
display.setFont(&FreeSerif12pt7b); // Muda a fonte
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,38);
display.println("OLED");
display.display();
delay(2000);
display.clearDisplay();
display.setFont(); // Retorna para a fonte normal
// Texto invertido no display
display.setTextColor(BLACK, WHITE); // Cores do texto 'invertido'
display.setCursor(0,28);
display.println("Display OLED");
display.display();
delay(2000);
display.clearDisplay();
// Muda o tamanho da fonte
display.setTextColor(WHITE);
display.setCursor(0,20);
display.setTextSize(3); // Tamanho da fonte: 3
display.println("Arduino");
display.display();
delay(2000);
display.clearDisplay();
// Números no display
display.setTextSize(2);
display.setCursor(0,24);
display.println(314159265); // Números
display.display();
delay(2000);
display.clearDisplay();
// Imprime caractteres ASCII no display
display.setCursor(0,10);
display.setTextSize(3);
display.write(1); // Caracter ASCII
display.setCursor(20,10);
display.write(2);
display.setCursor(40,10);
display.write(3);
display.setCursor(60,10);
display.write(4);
display.setCursor(80,10);
display.write(5);
display.setCursor(100,10);
display.write(6);
display.setCursor(0,35);
display.write(7);
display.setCursor(20,35);
display.write(8);
display.setCursor(40,35);
display.write(9);
display.setCursor(60,35);
display.write(11);
display.setCursor(80,35);
display.write(12);
display.setCursor(100,35);
display.write(14);
display.display();
delay(4000);
display.clearDisplay();
// Movimenta o texto sobre a tela
display.setCursor(0,20);
display.setTextSize(1);
display.println("Texto");
display.println("em");
display.println("movimento!");
display.display();
display.startscrollright(0x00, 0x0f); // Movimenta texto para a direita
delay(7000);
display.stopscroll();
delay(1000);
display.startscrollleft(0x00, 0x0f); // Movimenta texto para a esquerda
delay(7000);
display.stopscroll();
delay(1000);
display.clearDisplay();
delay(500);
//-----------------------------------------------------------------------------------------------------------
// Pixel
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Pixel");
display.drawPixel(64, 32, WHITE); // Pixel: Coordenada X, coordenada Y, cor
display.display();
delay(2000);
display.clearDisplay();
// Linha
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Linha");
display.drawLine(0, 20, 127, 60, WHITE); // Linha: Coordenada x e y do começo da linha, coordenada x e y do final da linha, cor
display.display();
delay(2000);
display.clearDisplay();
// Retângulo
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Retangulo");
display.drawRect(0, 17, 60, 40, WHITE); // Retângulo vazio: Coordenada X, coordenada Y, largura, altura e cor
display.fillRect(64, 17, 60, 40, WHITE); // Retângulo cheio: Coordenada X, coordenada Y, largura, altura e cor
display.display();
delay(2000);
display.clearDisplay();
// Retângulo com borda arredondada
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Borda arredondada");
display.drawRoundRect(0, 17, 60, 40, 8, WHITE); // Retângulo com borda arredondada: mesmos parâmetros do retângulo
display.fillRoundRect(64, 17, 60, 40, 8, WHITE); // Retângulo com borda arredondada cheio: mesmos parâmetros do retângulo
display.display();
delay(2000);
display.clearDisplay();
// Círculo
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Circulo");
display.drawCircle(20, 37, 20, WHITE); // Círculo: Coordenada X do centro, coordenada Y do centro, raio e cor
display.fillCircle(84, 37, 20, WHITE); // Círculo cheio: Coordenada X do centro, coordenada Y do centro, raio e cor
display.display();
delay(2000);
display.clearDisplay();
// Triângulo
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Triangulo");
display.drawTriangle(30, 17, 0, 62, 60, 62, WHITE); // Triângulo: Pares de coordenadas X e Y nos vértices do topo, a esquerda e a direita, e por fim, a cor do triângulo
display.fillTriangle(94, 17, 64, 62, 124, 62, WHITE); // Triângulo cheio: Pares de coordenadas X e Y nos vértices do topo, a esquerda e a direita, e por fim, a cor do triângulo
display.display();
delay(2000);
display.clearDisplay();
// Cores invertidas
display.invertDisplay(true);
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Invertido");
display.drawCircle(30, 37, 20, WHITE); // Círculo: Coordenada X do centro, coordenada Y do centro, raio e cor
display.drawRoundRect(64, 17, 60, 40, 8, WHITE); // Retângulo com borda arredondada cheio: mesmos parâmetros do retângulo
display.display();
delay(3000);
display.clearDisplay();
display.invertDisplay(false);
}
Neste guia completo sobre os Displays, acabamos de rever posts anteriores e recapitular várias informações muito interessantes para um aprendizado maker. Vimos quais as vantagens e desvantagens, usos no dia a dia, aplicações e até mesmo top 3 projetinhos para você fazer na sua casa. Também fez estes projetos? Melhor ainda? Sinta-se à vontade para nos contar aqui nos comentários e até mesmo tirar as suas dúvidas. Siga-nos também no Instagram e nos marque quando fizer algum projeto nosso: @eletrogate.
Todas as informações necessárias para a escrita e fontes de projetos utilizados nestes post, estão disponíveis nos links abaixo: Guia Completo do Display LCD – Arduino Guia Completo dos Displays de 7 Segmentos – Arduino Guia Completo do Display OLED (parte 1) – O que é? Como funciona? Guia Completo do Display OLED (parte 2) – Como programar Tenha a Metodologia Eletrogate na sua Escola! Conheça nosso Programa de Robótica Educacional.
|
Neste post, abordaremos os três tipos de displays, suas diferenças e semelhanças, usos no dia a dia e, até mesmo, projetos individuais para você fazer em sua casa.
Encontre tudo na Loja Eletrogate com frete grátis para compras acima de R$ 200