Como utilizar o display IPS LCD 0.96″ colorido 4

Olá pessoal! Já ouviram falar no display IPS LCD 0.96″ colorido? No artigo de hoje faremos uso de um display desse tipo exibindo imagens e textos coloridos. Vamos lá?

Display IPS LCD 0.96" colorido piscando
Display IPS LCD 0.96″ colorido.

Introdução

In-Planne Switching ou comutação no plano (tradução livre) é a sigla IPS. Usada em telas LCD, moléculas de cristal líquido giram em plano horizontal. A imagem é definida em uma taxa de atualização de 200 Hz a 240 Hz, contra 60 Hz em telas tradicionais. Isto faz com que a imagem seja atualizada sem perdas.

Esta tecnologia é usada em TVs LCD, monitores, displays em smartphones e também há versões que podemos utilizar em plataformas como Arduino, STM32 e afins.

Existem displays IPS de diversos tamanhos, totalmente coloridos. São divididos em tamanho (em polegadas) ou por resolução. A conexão com Arduino e afins é dada através de comunicação SPI. Seguem alguns exemplos:

Display IPS LCD 0.96" de 80 x 160 pixels ao lado de um Display IPS LCD de 240x240 pixels
Comparativo entre dois displays IPS coloridos.

Importante ressaltar que alguns modelos também diferem no controlador de display, que pode ser: ST7735, ST7789 ou ILI9341. Neste experimento faremos uso da versão com ST7735 para aparecer mensagens e imagens.

Materiais necessários

Montagem do circuito do display IPS LCD 0.96″ colorido

Faremos o circuito conforme mostrado na figura abaixo:

Esquema de conexão do Arduino Uno com o Display e protoboard no fritizing.
Esquema de conexão do Arduino Uno com o Display e protoboard no fritizing.

Onde:

Arduino Display
GND GND
5V ou 3.3V VCC
13 SCL
11 SDA
9 RES
8 DC
10 CS
Não usa BLK

OBS: O display pode ser 3.3V ou 5V. Ao carregar o programa veja como a sua versão se comporta. Nesta imagem o display está conectado ao pino de alimentação 5V.

Foto da conexão do Arduino Uno com o Display e protoboard.
Foto da conexão do Arduino Uno com o Display e protoboard.

Instalação de bibliotecas

Usaremos duas bibliotecas a serem instaladas, chamadas Adafruit_GFX.h e Adafruit_ST7735.h. Para a instalação, vá na IDE Arduino no menu Sketch => Incluir biblioteca => Gerenciar bibliotecas.

Na barra de busca do Gerenciador de biblioteca, procure por gfx e pressione Enter. Clique no botão Instalar e aguarde o carregamento. Depois faça o mesmo para a outra biblioteca digitando ST7735.

Janela do aplicativo de instalação das bibliotecas Adafruit_GFX.h e Adafruit_ST7735.h.
Instalação das bibliotecas Adafruit_GFX.h e Adafruit_ST7735.h.

OBS: A opção para biblioteca contempla – CD3F794HR8 – os dois tipos de controladores principais para displays TFT/IPS.

Código

Este código é uma adaptação do original escrito por Limor Fried da Adafruit. Realiza testes gráficos com várias cores, além de testes de escrita.

/**************************************************************************
  Escrito por Limor Fried/Ladyada para Adafruit Industries.
  Modificado por Gedeane Kenshima
  Data: 04/07/2021
 **************************************************************************/
 
#include <Adafruit_GFX.h>	// Biblioteca gráfica Adafruit
#include <Adafruit_ST7735.h> // Biblioteca específica para ST7735
#include <Adafruit_ST7789.h> // Biblioteca específica para ST7789
#include <SPI.h>         	// Biblioteca para comunicação SPI
 
// Definição dos pinos SPI
#define TFT_CS        10
#define TFT_RST        9
#define TFT_DC         8
// Pinos SDA em 11 e SCL em 13
 
// Criação do objeto tft para displays com ST7735:
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
 
// Variável p com valor de pi
float p = 3.1415926;
 
void setup(void) {
  // Início da comunicação Serial com 9600 bits por segundo
  Serial.begin(9600);
  // Mensagem inicial exibida no Monitor Serial
  Serial.println(F("Ola! Teste para TFT ST77xx"));
 
  // Inicialização do display IPS LCD 0.96" 160x80:
  tft.initR(INITR_MINI160x80);
 
  Serial.println(F("Inicializado"));
 
  // Usa millis para contagem de tempo
  uint16_t time = millis();
  // Preenche a tela com a cor preta
  tft.fillScreen(ST77XX_BLACK);
  // Realiza contagem de tempo atual
  time = millis() - time;
 
  // Exibe tempo atual em decimal
  Serial.println(time, DEC);
  // Aguarda 500 ms
  delay(500);
 
  // Gira tela para melhor exibição
  // Valores podem ser 0 (default), 1, 2 ou 3
  tft.setRotation(3);
  // Preenche a tela com a cor preta
  tft.fillScreen(ST77XX_BLACK);
  // Escreve texto longo com letras em cor branca
  testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE);
  // Aguarda 2s
  delay(2000);
 
  // Chama função tftPrintTest
  tftPrintTest();
  // Aguarda 4s
  delay(4000);
  // Gira tela para posição inicial
  tft.setRotation(0);
  // Desenha um pixel na tela em verde
  tft.drawPixel(tft.width()/2, tft.height()/2, ST77XX_GREEN);
  // Aguarda 500 ms
  delay(500);
 
  // Teste de linhas
  testlines(ST77XX_YELLOW);
  delay(1000);
 
  // Linhas otimizadas
  testfastlines(ST77XX_RED, ST77XX_BLUE);
  delay(1000);
 
  testdrawrects(ST77XX_GREEN);
  delay(1000);
 
  testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
  delay(1000);
 
  // Preenche a tela com a cor preta
  tft.fillScreen(ST77XX_BLACK);
  // Teste de círculos preenchidos em azul
  testfillcircles(10, ST77XX_BLUE);
  // Teste de círculos desenhados em branco
  testdrawcircles(10, ST77XX_RED);
  delay(1000);
 
  testroundrects();
  delay(1000);
 
  testtriangles();
  delay(1000);
 
  mediabuttons();
  delay(1000);
 
  // Exibe mensagem de Fim no Monitor Serial
  Serial.println("Fim");
  // Aguarda 1s
  delay(1000);
}
 
void loop() {
  // Inverte cores no display
  tft.invertDisplay(true);
  // Aguarda 500 ms
  delay(500);
  // Volta às cores originais no display
  tft.invertDisplay(false);
  // Aguarda 500 ms
  delay(500);
}
 
// Sub-rotina testlines
void testlines(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
	tft.drawLine(0, 0, x, tft.height()-1, color);
	delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
	tft.drawLine(0, 0, tft.width()-1, y, color);
	delay(0);
  }
 
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
	delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, 0, 0, y, color);
	delay(0);
  }
 
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
	tft.drawLine(0, tft.height()-1, x, 0, color);
	delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
	tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
	delay(0);
  }
 
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
	delay(0);
  }
  for (int16_t y=0; y < tft.height(); y+=6) {
    tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
	delay(0);
  }
}
 
// Sub-rotina testdrawtest com texto e cor como parâmetros
void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}
 
// Sub-rotina testfastlines com color1 e color2 como parâmetros
void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t y=0; y < tft.height(); y+=5) {
    tft.drawFastHLine(0, y, tft.width(), color1);
  }
  for (int16_t x=0; x < tft.width(); x+=5) {
    tft.drawFastVLine(x, 0, tft.height(), color2);
  }
}
 
void testdrawrects(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=0; x < tft.width(); x+=6) {
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
  }
}
 
void testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x=tft.width()-1; x > 6; x-=6) {
    tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
    tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
  }
}
// Sub-rotina testfillcircles com radius (raio) e cor como parâmetros
void testfillcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=radius; x < tft.width(); x+=radius*2) {
	for (int16_t y=radius; y < tft.height(); y+=radius*2) {
      tft.fillCircle(x, y, radius, color);
	}
  }
}
 
// Sub-rotina testdrawcircles com radius (raio) e cor como parâmetros
void testdrawcircles(uint8_t radius, uint16_t color) {
  for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
	for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
      tft.drawCircle(x, y, radius, color);
	}
  }
}
 
// Sub-rotina testtriangles
void testtriangles() {
  tft.fillScreen(ST77XX_BLACK);
  uint16_t color = 0xF800;
  int t;
  int w = tft.width()/2;
  int x = tft.height()-1;
  int y = 0;
  int z = tft.width();
  for(t = 0 ; t <= 15; t++) {
    tft.drawTriangle(w, y, y, x, z, x, color);
	x-=4;
	y+=4;
	z-=4;
	color+=100;
  }
}
 
// Sub-rotina testroundrects
void testroundrects() {
  tft.fillScreen(ST77XX_BLACK);
  uint16_t color = 100;
  int i;
  int t;
  for(t = 0 ; t <= 4; t+=1) {
	int x = 0;
	int y = 0;
	int w = tft.width()-2;
	int h = tft.height()-2;
	for(i = 0 ; i <= 16; i+=1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
  	x+=2;
  	y+=3;
  	w-=4;
  	h-=6;
  	color+=1100;
	}
	color+=100;
  }
}
//Sub-rotina tftPrintTest
void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi?");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST77XX_WHITE);
  tft.println("Sketch has been");
  tft.println("running for: ");
  tft.setTextColor(ST77XX_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST77XX_WHITE);
  tft.print(" seconds.");
}
//Sub-rotina mediabuttons
void mediabuttons() {
  // play
  tft.fillScreen(ST77XX_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}

Carregue o código para seu Arduino Uno. Caso tenha conectado VCC em 3.3V verifique as cores em seu display. Caso estejam com manchas ou foscas, troque o VCC de 3.3V para 5V. As imagens do display devem aparecer como mostrado a seguir.

Gif do display IPS LCD 0.96" colorido em funcionamento.
Gif do display IPS LCD 0.96″ colorido em funcionamento.

Você pode utilizar os conceitos semelhantes do artigo sobre display OLED para converter e gerar imagens em seu display IPS. Veja no artigo Como criar imagens no display OLED.

Gostou de conhecer o display IPS LCD e como realizar os testes nele? Amplia muito as possibilidades de exibição de imagens coloridas ou textos personalizados.


Se você tiver dúvidas, sugestões ou experiências para compartilhar, fique a vontade para deixar um comentário abaixo. E para não perder nenhum conteúdo como este, não deixe de nos seguir no Instagram.

Faça seu comentário

Acesse sua conta e participe

4 Comentários

  1. Olá, tudo bem? Me chamo Junior.
    Gostei muito do artigo. E pretendo fazer uns testes usando esse display. Mas, possuo uma dúvida: esse display pode ser usado para exibição de vídeo (como se fosse uma microtv)? Só para clarear um pouco as ideias, a minha intenção seria montar um óculos para exibir jogos a partir de um console, como se fosse um óculos vr. Isso seria possível? Esse display suporta esse tipo de aplicação (mesmo usando outra plataforma que não seja o Arduino)?

    Desde já, muito obrigado.
    Parabéns pelo trabalho.

    1. Olá Junior!

      Acredito que seja possível sim, mas não com o Arduino. Seria necessária uma plataforma que consiga processar o sinal de vídeo e transformar na interface SPI que o display necessita.
      Pelo que observei no datasheet, acredito que seria possível uma taxa da atualização de 30 a 40 FPS.

      Abraços!
      Vinícius – Equipe MakerHero

      1. Olá Vinícius!
        Maravilha, muito obrigado pela orientação. Ajudou muito.

        Abraços, tudo de bom para toda a equipe MakerHero
        Boas Festas.

        1. Olá!

          De nada!

          Abraços e boas festas pra você também!
          Vinícius – Equipe MakerHero