Skip to Content

Como configurar a biblioteca TFT_eSPI para ecrã TFT

Como configurar a biblioteca TFT_eSPI para ecrã TFT

Neste tutorial, vais aprender como configurar o TFT_eSPI Library dentro do Arduino IDE para controlar ecrãs TFT. Vou mostrar-te vários exemplos para diferentes ecrãs TFT.

A biblioteca TFT_eSPI simplifica o processo de interface com ecrãs TFT. Fornece uma API simples para desenhar formas, mostrar texto e gerir entrada tátil.

A biblioteca é direcionada para processadores de 32 bits e foi otimizada para desempenho no RP2040, STM32, ESP8266 e ESP32. Também funciona com placas Arduino, mas será mais lenta.

Além disso, suporta vários controladores de ecrãs TFT, incluindo ILI9341, ST7735, ST7789, ST7796 e outros. Para uma lista completa e mais informações, consulta o Readme da Biblioteca TFT_eSPI.

Instalar a Biblioteca TFT_eSPI

Para install a TFT_eSPI library abre o Library Manager, procura por “TFT_eSPI” e clica em “INSTALL”. Após a instalação, deverá ficar assim:

TFT_eSPI library in Library Manager
Biblioteca TFT_eSPI no Library Manager

Configurar a biblioteca TFT_eSPI via User_Setup.h

Antes de poderes usar a TFT_eSPI Library tens de a configurar especificamente para o ecrã TFT onde queres desenhar. Isso inclui o driver IC do ecrã, os pinos da interface e propriedades do ecrã como dimensões ou ordem dos canais RGB.

Estes parâmetros de configuração estão guardados num ficheiro chamado User_Setup.h, que faz parte da pasta da biblioteca TFT_eSPI. Normalmente, no Windows, estará num caminho semelhante ao seguinte

C:\Users\stefa\OneDrive\Documents\Arduino\libraries\TFT_eSPI

O caminho exato depende do teu nome de utilizador (no meu caso “stefa“) e do teu sistema operativo e se usas OneDrive ou não. Terás de o procurar, mas estará onde todas as tuas bibliotecas Arduino estão guardadas.

Se abrires o ficheiro User_Setup.h vais ver muitos parâmetros que precisam de ser definidos corretamente para fazer funcionar um ecrã TFT específico:

User_Setup.h
User_Setup.h

Podes editar este ficheiro, mas qualquer alteração afetará todos os teus projetos Arduino que usem a biblioteca TFT_eSPI, pois a biblioteca e User_Setup.h são partilhados entre projetos. Além disso, instalar uma nova versão da biblioteca TFT_eSPI irá sobrescrever as tuas alterações ao User_Setup.h.

Em vez disso, sugiro que cries um ficheiro chamado tft_setup.h que seja local a um projeto e afete apenas esse projeto. Como fazer isso é o tema da secção seguinte.

Configurar a biblioteca TFT_eSPI via tft_setup.h

Qualquer alteração ao User_Setup.h afeta todos os projetos. No entanto, se o projeto contiver um ficheiro com o nome tft_setup.h as definições no User_Setup.h serão ignoradas.

O ficheiro tft_setup.h contém essencialmente as mesmas definições, User_Setup.h sendo válidas apenas para o projeto específico. Isso significa que podes ter projetos diferentes com ecrãs diferentes, sem ter de alterar User_Setup.h sempre que usares um ecrã diferente.

Estrutura do Projeto

Aqui está um exemplo de como criar a estrutura necessária para o projeto. Primeiro cria um novo projeto Arduino e guarda-o como “tft_test“, por exemplo. Isso criará uma pasta tft_test com um ficheiro tft_test.ino dentro:

Arduino Project Folder tft_test
Pasta do Projeto Arduino tft_test

Nesta pasta, cria agora um ficheiro chamado “tft_setup.h” – exatamente com este nome! A tua pasta de projeto deverá ficar assim:

Pasta do Projeto Arduino com tft_setup.h

No teu Arduino IDE, agora deverás ver duas abas; tft_test.ino e tft_setup.h que podes clicar para editar os ficheiros.

Arduino IDE with tft_test.ino and tft_setup.h tabs
Arduino IDE com abas tft_test.ino and tft_setup.h

Exemplo de Definições

No ficheiro tft_setup.h copias (por exemplo, de User_Setup.h ou de um tutorial) todas as definições específicas para o teu ecrã. Abaixo está o ficheiro de definições para um 1.8″ ST7735 TFT Display, por exemplo:

// tft_setup.h
#define ST7735_DRIVER
#define ST7735_BLACKTAB
   
#define TFT_WIDTH  128
#define TFT_HEIGHT 160

#define TFT_RGB_ORDER TFT_RGB  

// pins
#define TFT_CS    5   
#define TFT_RST   16  
#define TFT_DC    17   
#define TFT_MOSI  23  // SDA // HW MOSI
#define TFT_SCLK  18  // SCL // HW SCLK
#define TFT_MISO  19  // not used
#define TFT_BL    22   // LED back-light
#define TFT_BACKLIGHT_ON HIGH

// fonts
#define LOAD_GLCD   
#define LOAD_FONT2  
#define LOAD_FONT4  
#define LOAD_FONT6  
#define LOAD_FONT7  
#define LOAD_FONT8  
#define LOAD_GFXFF
#define SMOOTH_FONT 

// SPI
#define SPI_FREQUENCY  27000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000

A definição mais importante é o driver do ecrã (ST7735_DRIVER), as dimensões do ecrã (320×240) e os pinos a que o ecrã está ligado.

Por vezes há variações do driver que podem ser definidas via flags especiais (por exemplo, ST7735_BLACKTAB). De forma semelhante, a ordem dos canais RGB pode variar entre ecrãs e podes especificar isso também (TFT_RGB_ORDER TFT_RGB).

As definições da frequência SPI normalmente não diferem muito entre ecrãs, mas se estiveres a ver padrões de ruído ou outras distorções, podes tentar baixar a SPI_FREQUENCY. Frequências mais altas tornam o ecrã mais rápido, e podes experimentar isso também.

Abaixo está um exemplo das distorções que podes encontrar se a frequência SPI for demasiado alta. O primeiro texto foi mostrado com uma SPI_FREQUENCY de 27000000 e o segundo com uma frequência de 40000000. Podes ver claramente as distorções no segundo texto.

TFT text output with different SPI frequencies
Saída de texto com diferentes frequências SPI

Normalmente não precisas de alterar a lista de fontes a carregar, mas se estiveres a ficar sem memória podes remover as fontes que não usas.

Podes encontrar muitas definições existentes para várias combinações de microprocessadores e drivers de ecrã na pasta UserSetups da biblioteca TFT_eSPI. Para uma visão geral de todas as definições, consulta o ficheiro User_Setup.h.

Encontrar pinos SPI de Hardware

A velocidade com que o ecrã TFT pode mostrar imagens depende muito da rapidez com que os dados são transferidos do microprocessador para o ecrã. Normalmente, o microprocessador e o ecrã comunicam via SPI (Serial Peripheral Interface), embora exista também uma interface paralela.

Microprocessadores como o Arduino, ESP8266 ou ESP32 suportam Hardware SPI, que é mais rápido que Software SPI. Vê um vídeo de comparação de velocidades here.

No entanto, o Hardware SPI exige que ligues o ecrã TFT aos pinos corretos. Dependendo do microprocessador, esses pinos são diferentes. Contudo, podes encontrá-los facilmente selecionando a tua placa no Arduino IDE e depois executando o código abaixo.

void setup() {
  Serial.begin(115200);
  Serial.print("MOSI: ");
  Serial.println(SDA / MOSI);
  Serial.print("MISO: ");
  Serial.println(MISO);
  Serial.print("SCL / SCLK: ");
  Serial.println(SCK);
  Serial.print("CS / SS: ");
  Serial.println(SS);  
}

void loop() { }

Este código imprime os pinos que precisas para o hardware SPI – especificamente MOSI e SCLK. Os restantes pinos, como TFT_CS, TFT_BL, TFT_DC, podes escolher livremente, e o MISO normalmente não é usado.

Níveis Lógicos

Finalmente, um aviso sobre Logic Levels. Ecrãs TFT normalmente operam com lógica CMOS de 3.3V e podes ligar as linhas SPI diretamente a um microprocessador que também use lógica CMOS de 3.3V, como o ESP32, por exemplo.

Placas Arduino, por outro lado, operam com lógica TTL de 5V e tu não deves ligar diretamente os seus pinos GPIO a um ecrã TFT que use lógica CMOS de 3.3V. Vais precisar de um divisor de tensão ou, melhor, de um logic level converter.

Alguns ecrãs TFT têm esse conversor de nível lógico incorporado, mas se não estiver explicitamente indicado na folha de dados ou na descrição do produto, não podes ter certeza. Se o ecrã for indicado para funcionar a 5V, pode ou não ter um conversor de nível. Se funcionar a 3.3V, provavelmente não tem.

Portanto, se o teu ecrã não estiver a funcionar corretamente (ecrã em branco, padrões de ruído, cintilação, …) com um Arduino, podes precisar de um conversor de nível lógico.

Exemplo de Ligação para TFT 1.8″ com Driver ST7735

Nesta secção, vou mostrar-te um exemplo de ligação. Vamos ligar um 1.8″ TFT Display que tem um driver ST7735S a um WEMOS Lolin32 lite. Vê a ligação completa na imagem abaixo:

Connecting TFT ST7735 Display with WEMOS Lolin ESP32 lite
Ligação do Ecrã TFT ST7735 com WEMOS Lolin ESP32 lite

E aqui, para tua conveniência, a ligação novamente em forma de tabela:

EcrãESP32
CS / SS5
RST16
DC17
SDA / MOSI23
SCL / SCLK18
BKL/BL22
GNDGND
VCC3.3V

O ecrã TFT neste exemplo é um ecrã de 3.3V sem conversor de nível lógico. Portanto, deves ligar o VCC do ecrã a 3.3V e não podes ligá-lo diretamente a um Arduino Uno.

Exemplo de Código para TFT 1.8″ com Driver ST7735

Nesta secção, vamos ver um pequeno exemplo de código que usa a biblioteca TFT_eSPI. Será útil para testar se as definições no ficheiro tft_setup.h estão corretas.

Copia o seguinte código para o ficheiro tft_test.ino. Este código mostra um quadrado verde, um círculo vermelho, um triângulo azul e o texto “Makerguides”.

// tft_test.ino
#include "tft_setup.h"
#include"TFT_eSPI.h"

TFT_eSPI tft = TFT_eSPI();

const int cw = tft.width()/2;
const int ch = tft.height()/2;
const int s = min(cw/3,ch/3);

void setup(void) {  
  tft.init();
  tft.fillScreen(TFT_BLACK);  
  tft.setRotation(1);

  tft.setTextFont(1);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextDatum(CC_DATUM);
  tft.drawString("Makerguides", ch, cw+s);

  tft.fillCircle(ch, cw/2+s/2, s/2, TFT_RED);
  tft.fillRect(1.5*ch-s, cw/2, s, s, TFT_GREEN);
  tft.fillTriangle(ch/2, cw/2, ch/2+s, cw/2, ch/2, cw/2+s, TFT_BLUE);
}

void loop() { }

Repara que tft_setup.h está incluído no topo do programa. O código em si é fácil de entender. Criamos um objeto TFT_eSPI e constantes para o centro (cw, ch) e o tamanho s dos objetos a desenhar.

Na função setup inicializamos o ecrã TFT, preenchemos o ecrã com preto e rodamos para modo retrato.

De seguida, definimos a fonte, o seu tamanho, cor e alinhamento, e escrevemos o texto “Makerguides” no ecrã. Nas três linhas seguintes desenhamos o círculo vermelho, o quadrado verde e o triângulo azul. A saída no teu ecrã TFT deverá ser semelhante a esta:

Output of test code on TFT
Saída do código de teste no TFT

Se não for, então algo está errado nas definições do tft_test.ino ou na ligação do ecrã TFT.

Exemplo de Ligação para TFT 1.3″ ST7789

No próximo exemplo, mostro-te como ligar o comum 1.3″ ST7789 TFT Display a um WEMOS Lolin32 lite (ESP32):

Connecting TFT ST7789 Display with WEMOS Lolin ESP32 lite
Ligação do Ecrã TFT ST7789 com WEMOS Lolin ESP32 lite

E aqui estão as ligações necessárias novamente em forma de tabela. Repara que este módulo de ecrã não tem chip select (CS) e, portanto, não é necessário pino para isso.

EcrãESP32
RST16
DC17
SDA / MOSI23
SCL / SCLK18
BKL/BL22
GNDGND
VCC3.3V

Certifica-te de ligar o VCC do ecrã a 3.3V! Não é compatível com 5V e não podes usá-lo diretamente com um Arduino UNO. Também deves usar os pinos hardware SPI. Dependendo do microcontrolador, os pinos hardware SPI serão diferentes.

Exemplo de Código para TFT 1.3″ ST7789

Aqui está a configuração e o código para o 1.3″ ST7789 TFT Display. Copia a seguinte configuração para o ficheiro tft_setup.h.

// 1.3" TFT Display (GMT130 V.10), 
// no CS pin
// 240x240, ST7789
// tft_setup.h
#define ST7789_DRIVER

#define TFT_WIDTH  240
#define TFT_HEIGHT 240

#define TFT_RGB_ORDER TFT_BGR

#define TFT_CS    -1   
#define TFT_RST   16  
#define TFT_DC    17  
#define TFT_MOSI  23  // SDA // HW MOSI
#define TFT_SCLK  18  // SCL // HW SCL
#define TFT_MISO  19  // not used
#define TFT_BL    22  // LED back-light
#define TFT_BACKLIGHT_ON HIGH


#define LOAD_GLCD   
#define LOAD_FONT2  
#define LOAD_FONT4  
#define LOAD_FONT6  
#define LOAD_FONT7  
#define LOAD_FONT8  
#define LOAD_GFXFF
#define SMOOTH_FONT 

#define SPI_FREQUENCY  27000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000

E o código de teste para o sketch vai para o ficheiro tft_test.ino:

// tft_test.ino
#include "tft_setup.h"
#include"TFT_eSPI.h"

TFT_eSPI tft = TFT_eSPI();

const int cw = tft.width()/2;
const int ch = tft.height()/2;
const int s = min(cw/4,ch/4);

void setup(void) {  
  tft.init();
  tft.fillScreen(TFT_BLACK);  
  tft.setRotation(1);

  tft.setTextFont(1);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextDatum(CC_DATUM);
  tft.drawString("Makerguides", ch, cw+s);

  tft.fillCircle(ch, cw/2+s/2, s/2, TFT_RED);
  tft.fillRect(1.5*ch-s, cw/2, s, s, TFT_GREEN);
  tft.fillTriangle(ch/2, cw/2, ch/2+s, cw/2, ch/2, cw/2+s, TFT_BLUE);
}

void loop() { }

Deverás ver a seguinte saída no teu ecrã:

Saída do código de teste no TFT

Exemplo de Ligação para TFT 2.8″ ILI9341 Touch Display

Neste último exemplo, mostro-te como ligar um 2.8″ TFT ILI9341 Touch Display a um WEMOS Lolin32 lite (ESP32):

Connecting the TFT ILI9341 Touch Display to ESP32
Ligação do TFT ILI9341 Touch Display ao ESP32

Há bastantes ligações a fazer e a tabela seguinte deverá ajudar. Repara que as linhas SDI(MOSI) e SCK da interface SPI são partilhadas entre o controlador tátil e o controlador do ecrã TFT:

ESP32TFTTouch
5CS
4T_CS
17RESET
16DC
23SDI(MOSI)T_DIN
18SCKT_CLK
19T_DO
22LED

Poderias ligar o pino 19 do ESP32 ao SDO(MISO) também, mas não precisamos e houve relatos de que, em alguns casos, isso causa problemas. Eu não liguei o pino 19 ao SDO(MISO) e o ecrã funcionou bem.

Exemplo de Código para TFT 2.8″ ILI9341 Touch Display

Aqui está a configuração e o código para o 2.8″ TFT ILI9341 Touch Display. Copia a seguinte configuração para o ficheiro tft_setup.h.

// tft_setup.h
// 2.8" TFT Touch Display
// 240x 320, Driver: ILI9341 

#define ILI9341_DRIVER      
//#define ILI9341_2_DRIVER  

#define TFT_WIDTH  240
#define TFT_HEIGHT 320
#define TFT_RGB_ORDER TFT_BGR  

// WEMOLS Lolin32 lite
#define TFT_CS    5   
#define TFT_RST   17  
#define TFT_DC    16   
#define TFT_MOSI  23  // SDA // HW MOSI
#define TFT_SCLK  18  // SCL // HW SCLK
#define TFT_MISO  19  // HW MISO
#define TFT_BL    22  // LED back-light
#define TFT_BACKLIGHT_ON HIGH

#define TOUCH_CS 4 
#define TOUCH_CLK TFT_SCLK
#define TOUCH_DIN TFT_MOSI
#define TOUCH_DO TFT_MISO

#define LOAD_GLCD   
#define LOAD_FONT2  
#define LOAD_FONT4  
#define LOAD_FONT6  
#define LOAD_FONT7  
#define LOAD_FONT8  
#define LOAD_GFXFF
#define SMOOTH_FONT 

#define SPI_FREQUENCY  27000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000

E aqui está algum código de teste para o ecrã que vai para o ficheiro tft_test.ino:

// tft_test.ino
#include "tft_setup.h"
#include "TFT_eSPI.h"

TFT_eSPI tft = TFT_eSPI();
uint16_t cal[5] = { 0, 0, 0, 0, 0 };

void calibrate_touch() {
  if (!cal[1]) {
    tft.fillScreen(TFT_BLACK);
    tft.calibrateTouch(cal, TFT_YELLOW, TFT_BLACK, 20);
    Serial.printf("cal[5] = {%d, %d, %d, %d, %d};\n",
                  cal[0], cal[1], cal[2], cal[3], cal[4]);
  }
}

void setup(void) {
  Serial.begin(115200);

  tft.init();
  tft.setRotation(1);
  calibrate_touch();
  tft.setTouch(cal);

  tft.fillScreen(TFT_BLACK);
  tft.setTextFont(1);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextDatum(CC_DATUM);
  tft.drawString("Makerguides", TFT_HEIGHT / 2, TFT_WIDTH / 2);
}

void loop() {
  uint16_t x, y;
  if (tft.getTouch(&x, &y)) {
    Serial.printf("%d %d\n", x, y);
    tft.fillCircle(x, y, 2, TFT_YELLOW);
  }
}

Este código permite calibrar o ecrã tátil e detetar toques no ecrã:

Touch input on TFT ILI9341 Touch Display
Entrada tátil no TFT ILI9341 Touch Display

Para informações mais detalhadas, vê o tutorial Interface TFT ILI9341 Touch Display with ESP32.

Conclusões

Neste tutorial aprendeste como configurar o TFT_eSPI Library dentro do Arduino IDE para controlar ecrãs TFT.

A TFT_eSPI Library é muito versátil e suporta muitos ecrãs TFT diferentes. No entanto, encontrar a definição correta para um novo ecrã TFT pode não ser fácil.

Começa por identificar o driver IC que o ecrã usa. Drivers comuns são o ST7735, ST7789, ST7796 e o ILI9341. Procura estes nomes na descrição do produto, na folha de dados e na PCB do próprio ecrã.

Depois, descobre a resolução (largura, altura) do ecrã em pixels, por exemplo 128×160. Novamente, deves conseguir encontrar esta informação na descrição do produto, na folha de dados ou na PCB do ecrã.

Depois liga o ecrã ao teu microcontrolador. Se houver um pino de backlight, certifica-te que está ligado a 3.3V (ou 5V, dependendo do ecrã). Se não souberes se o ecrã é compatível com 5V, não uses um Arduino, mas sim um ESP32 com 3.3V. Caso contrário, podes destruir o driver IC do ecrã.

Finalmente, carrega o código de teste e vê o que acontece. Existem alguns cenários comuns:

  • Ecrã preto: Verifica o pino do backlight e define #define TFT_BACKLIGHT_ON HIGH
  • Cores erradas: Tenta #define TFT_RGB_ORDER TFT_RGB ou TFT_BGR
  • Preto e branco invertidos: #define TFT_INVERSION_ON or TFT_INVERSION_OFF
  • Texto do código de teste não está centrado ou está cortado: Dimensões do ecrã estão erradas.
    Define TFT_HEIGHT e TFT_WIDTH corretamente.
  • Padrões de ruído, distorções ou cintilação: SPI_FREQUENCY está demasiado alta
  • Pinos em falta: Se não houver pino para reset (RST), chip select (CS) ou backlight (BL) no ecrã, define as constantes correspondentes para -1, por exemplo #define TFT_RST -1

Se tiveres algum comentário, sente-te à vontade para deixar na secção de comentários.

Boas experiências ; )