Arduino Nano ESP32 - Interface SPI para Display TFT LCD Touch ILI9341 ILI9488 ST7789

Bem-vindo a este workshop prático em que conectamos um display TFT SPI a um Arduino Nano ESP32. O Nano ESP32 é construído em torno do chip ESP32-S3, que oferece processamento dual-core, Wi-Fi e Bluetooth Low Energy no já conhecido formato Nano com conector USB-C. Ele opera em 3.3V, que combina com o nível de tensão da maioria dos módulos TFT SPI, deixando a ligação simples.

Neste workshop você vai:

Este workshop cobre displays TFT LCD SPI com touch e sem touch. Ele funciona com painéis de 1.3, 1.54, 2.2, 2.4, 2.8, 3.2 e 3.5 polegadas controlados pelos chips ILI9341, ILI9488 ou ST7789.

Display TFT SPI do Arduino Nano ESP32

Hardware Necessário

1×Arduino Nano ESP32
1×Cabo USB Tipo-A para Tipo-C (para PC com USB-A)
1×Cabo USB Tipo-C para Tipo-C (para PC com USB-C)
1×SPI TFT display module
1×Fios Jumper
1×(Recomendado) Placa de Expansão com Bornes de Parafuso para Arduino Nano
1×(Recomendado) Placa de Expansão Breakout para Arduino Nano
1×(Recomendado) Divisor de Alimentação para Arduino Nano ESP32

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Divulgação: Alguns dos links desta seção são links de afiliado da Amazon. Podemos receber uma comissão pelas compras feitas por meio desses links, sem custo adicional para você. Agradecemos o seu apoio.

Sobre o Display TFT SPI

Os módulos TFT SPI usam um CI driver para gerenciar os dados dos pixels e responder aos comandos de desenho por um link SPI de alta velocidade. Três drivers são suportados:

  • ILI9341 - cor RGB565 de 16 bits, SPI de até 40 MHz.
  • ILI9488 - cor RGB666 de 18 bits via SPI, até 24 MHz.
  • ST7789 - cor RGB565 de 16 bits, SPI de até 40 MHz.

Recomendação: Se você ainda não comprou um display, recomendamos o driver ST7789. Ele é amplamente disponível, roda na velocidade total de SPI de 40 MHz e é a escolha mais simples para novos projetos.

A biblioteca é baseada no Adafruit GFX, então círculos, retângulos, texto, fontes personalizadas e bitmaps já estão prontos para usar.

Nota: O Arduino Nano ESP32 usa lógica de 3.3V. Conecte o VCC do TFT somente ao pino 3.3V.

Pinagem

A maioria dos displays TFT LCD SPI tem os seguintes pinos:

Pinos do display:

Pino Função
VCC Alimentação
GND Terra
CS Chip Select — colocado em nível baixo para selecionar o display no barramento SPI
DC / RS Seleção de Dados / Comando — alto para dados de pixel, baixo para comandos
RST Reset de hardware — opcional; ligue ao 3.3V se não for usado
MOSI / SDI / SDA Entrada de dados SPI (MCU → display)
SCK / CLK Clock SPI
MISO / SDO Saída de dados SPI (display → MCU) — opcional para uso apenas do display
LED / BL / BLK Alimentação da luz de fundo — ligue ao 3.3V ou a um pino PWM para controlar o brilho

Pinos do cartão SD (se sua aplicação precisar acessar o cartão SD):

Pino Função
SD_CS / TF_CS Chip Select do cartão SD
MOSI / SDI MOSI — dados do MCU para o cartão SD
SCK / CLK SCK — clock SPI
MISO / SDO MISO — dados do cartão SD para o MCU

Para displays TFT que suportam toque, existem pinos de toque adicionais (se sua aplicação usar a função de toque e o display a suportar):

Pino Função
T_CS Chip Select do controlador de toque
T_CLK SCK — clock SPI
T_DIN MOSI — dados do MCU para o controlador de toque
T_DO MISO — dados do controlador de toque para o MCU
T_IRQ Interrupção de toque — opcional; sinaliza quando a tela está sendo tocada

Nota: Alguns módulos de display sem touch também expõem os pinos T_CS, T_CLK, T_DIN, T_DO e T_IRQ. Eles não funcionam nessas placas — o CI do controlador de toque não está soldado. Eles aparecem porque a PCB reutiliza o mesmo layout da versão com touch para reduzir as variantes de fabricação.

Pinagem do Display TFT SPI

Diagrama de Ligação

Nota — SDO (MISO) é opcional: A linha SDO (MISO) só leva dados do display de volta para a placa. Nenhum dos códigos de exemplo deste tutorial lê dados do display, então este pino pode ficar desconectado. Em módulos onde o controlador de toque compartilha o mesmo barramento SPI, uma linha SDO conectada pode interferir na comunicação, por isso recomenda-se deixá-la desconectada.

Sem Touch

Conecte MOSI ao D11, SCK ao D13, MISO ao D12 no Nano ESP32. CS, DC e RST podem ser qualquer GPIO disponível — D10, D8, D9 são usados nos exemplos.

Display:

Pino do TFT Pino do Arduino Nano ESP32 Descrição
VCC 3.3V Alimentação (somente 3.3V)
GND GND Terra
CS D10 Chip Select
DC / RS D8 Seleção de Dados / Comando
RST D9 Reset (opcional)
MOSI / SDI D11 MOSI do SPI de hardware
SCK D13 Clock do SPI de hardware
MISO / SDO D12 MISO do SPI de hardware (opcional)
LED / BL 3.3V Alimentação da luz de fundo

Cartão SD (se sua aplicação precisar acessar o cartão SD):

Pino do SD Pino do Arduino Nano ESP32 Descrição
SD_CS / TF_CS qualquer GPIO livre Chip Select do cartão SD
MOSI / SDI D11 Compartilhado com o MOSI do display (D11)
SCK / CLK D13 Compartilhado com o SCK do display (D13)
MISO / SDO D12 Compartilhado com o MISO do display (D12)
Diagrama de ligação do display TFT SPI do Arduino Nano ESP32 sem touch

This image is created using Fritzing. Click to enlarge image

Com Touch

Conecte o controlador de toque XPT2046 ao barramento SPI do Arduino Nano ESP32, compartilhando D11, D13 e D12 com o display.

Display:

Pino do TFT Pino do Arduino Nano ESP32 Descrição
VCC 3.3V Alimentação (somente 3.3V)
GND GND Terra
CS D10 Chip Select
DC / RS D8 Seleção de Dados / Comando
RST D9 Reset (opcional)
MOSI / SDI D11 MOSI do SPI de hardware
SCK D13 Clock do SPI de hardware
MISO / SDO D12 MISO do SPI de hardware (opcional)
LED / BL 3.3V Alimentação da luz de fundo

Controlador de toque (se sua aplicação usar a função de toque e o display a suportar):

Pino de Toque Pino do Arduino Nano ESP32 Descrição
T_CS D2 Chip Select do toque
T_IRQ D6 Interrupção de toque (opcional)
T_DIN D11 Compartilhado com o MOSI do display (D11)
T_CLK D13 Compartilhado com o SCK do display (D13)
T_DO D12 Compartilhado com o MISO do display (D12)
Diagrama de ligação do display TFT SPI do Arduino Nano ESP32 com touch

This image is created using Fritzing. Click to enlarge image

Se o seu MCU tem duas ou mais interfaces SPI de hardware, você pode atribuir cada periférico (display, cartão SD, controlador de toque) ao seu próprio barramento SPI dedicado. Se o seu MCU tem apenas uma interface SPI de hardware, os três periféricos compartilham as mesmas três linhas de dados (MOSI, SCK, MISO) — no Nano ESP32 elas são D11, D13 e D12. Cada periférico tem seu próprio pino CS, então apenas um fica ativo por vez. A biblioteca DIYables_TFT_SPI gerencia tanto o display quanto o controlador de toque XPT2046 por uma única API — nenhuma biblioteca SPI separada é necessária para o lado do toque.

Instalação da Biblioteca

  1. Conecte o Arduino Nano ESP32 ao seu computador pela porta USB-C.
  2. Abra o Arduino IDE. Escolha Arduino Nano ESP32 na lista de placas e selecione a porta correta.
  3. Clique no ícone Libraries na barra lateral esquerda.
  4. Digite "DIYables_TFT_SPI" no campo de busca. Encontre a entrada da DIYables.
  5. Clique em Install. Instale todas as dependências quando solicitado.
  • Search for DIYables TFT SPI created by DIYables.io and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Nano ESP32
Library Manager
Type:
All
Topic:
All
DIYables TFT SPI by DIYables.io
Works with both touch and non-touch versions of the same SPI TFT modules. Supports ILI9341 (240x320, 16-bit RGB565), ILI9488 (320x480, 18-bit RGB666), and ST7789 (240x320, 16-bit RGB565) displays over SPI. Includes built-in driver for XPT2046 / HR2046 / ADS7843 SPI touch controllers and 4-wire resistive touch panels - no separate touch library required. Use the display-only API for non-touch panels, or add initTouchSPI() to enable touch on modules that include a touch controller. Extends Adafruit GFX for full graphics support. Works with any Arduino-compatible board that has SPI. More info
1.0.3
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
Arduino Nano ESP32 on COM15
1

Sketch Inicial

O código mínimo necessário para começar com a biblioteca DIYables_TFT_SPI:

#include <DIYables_TFT_SPI.h> #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Uncomment the line that matches your driver chip: // DIYables_ILI9341_SPI TFT_display(240, 320, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(320, 480, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(240, 320, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); void setup() { TFT_display.begin(); TFT_display.setRotation(1); } void loop() { // drawing code here }

Workshop - Desenhar Formas

O exemplo DrawShapes coloca em ação todas as primitivas de desenho do Adafruit GFX: círculos, retângulos, triângulos e linhas pela tela.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32) // --------------------------------------------- // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // MOSI and SCK use default hardware SPI pins // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define BLACK DIYables_TFT_SPI::colorRGB(0, 0, 0) #define BLUE DIYables_TFT_SPI::colorRGB(0, 0, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define GREEN DIYables_TFT_SPI::colorRGB(0, 255, 0) #define ORANGE DIYables_TFT_SPI::colorRGB(255, 165, 0) #define PINK DIYables_TFT_SPI::colorRGB(255, 192, 203) #define VIOLET DIYables_TFT_SPI::colorRGB(148, 0, 211) #define TURQUOISE DIYables_TFT_SPI::colorRGB(64, 224, 208) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) // Helper to draw a filled diamond void fillDiamond(int cx, int cy, int h, int v, uint16_t color) { int x0 = cx, y0 = cy - v; int x1 = cx + h, y1 = cy; int x2 = cx, y2 = cy + v; int x3 = cx - h, y3 = cy; TFT_display.fillTriangle(x0, y0, x1, y1, x2, y2, color); TFT_display.fillTriangle(x0, y0, x2, y2, x3, y3, color); } void setup() { TFT_display.begin(); TFT_display.setRotation(1); // Landscape } void loop() { TFT_display.fillScreen(WHITE); uint16_t w = TFT_display.width(); uint16_t h = TFT_display.height(); // Scale positions relative to screen size with better spacing int col1 = w / 8; int col2 = w * 3 / 8; int col3 = w * 5 / 8; int col4 = w * 7 / 8; int row1 = h / 4; int row2 = h / 2; int row3 = h * 3 / 4; // Outlined circle TFT_display.drawCircle(col1, row1, 30, RED); // Filled circle TFT_display.fillCircle(col2, row1, 30, RED); // Outlined triangle TFT_display.drawTriangle(col3 - 30, row1 + 25, col3 + 30, row1 + 25, col3, row1 - 25, BLUE); // Filled triangle TFT_display.fillTriangle(col4 - 30, row1 + 25, col4 + 30, row1 + 25, col4, row1 - 25, GREEN); // Outlined rectangle TFT_display.drawRect(col1 - 35, row2 - 20, 70, 40, ORANGE); // Filled rectangle TFT_display.fillRect(col2 - 35, row2 - 20, 70, 40, TURQUOISE); // Outlined round rectangle TFT_display.drawRoundRect(col3 - 35, row2 - 20, 70, 40, 10, VIOLET); // Filled round rectangle TFT_display.fillRoundRect(col4 - 35, row2 - 20, 70, 40, 10, PINK); // Outlined diamond (centered between col1 and col2) int diamond1_x = (col1 + col2) / 2; TFT_display.drawLine(diamond1_x, row3 - 30, diamond1_x + 25, row3, GREEN); TFT_display.drawLine(diamond1_x + 25, row3, diamond1_x, row3 + 30, GREEN); TFT_display.drawLine(diamond1_x, row3 + 30, diamond1_x - 25, row3, GREEN); TFT_display.drawLine(diamond1_x - 25, row3, diamond1_x, row3 - 30, GREEN); // Filled diamond (centered between col3 and col4) int diamond2_x = (col3 + col4) / 2; fillDiamond(diamond2_x, row3, 25, 30, BLUE); delay(10000); }

Mão na Massa

  • Ligue o módulo TFT ao Nano ESP32 usando a tabela acima. Lembre-se de usar 3.3V para o VCC.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • O display mostra um padrão rotativo de formas coloridas.

Referência de Métodos

Método Ação Sintaxe
begin() Inicializa e reinicia o display. TFT_display.begin();
setRotation(r) Define a orientação (0=retrato, 1=paisagem). TFT_display.setRotation(1);
fillScreen(color) Limpa a tela com uma única cor. TFT_display.fillScreen(BLACK);
colorRGB(r,g,b) Cria uma cor de 16 bits a partir de R, G, B. colorRGB(255,128,0)
fillCircle(x,y,r,color) Círculo preenchido. TFT_display.fillCircle(100,100,50,RED);
fillRoundRect(x,y,w,h,r,color) Retângulo arredondado preenchido. TFT_display.fillRoundRect(10,10,100,50,10,BLUE);
drawTriangle(x0,y0,x1,y1,x2,y2,color) Contorno de triângulo. TFT_display.drawTriangle(60,10,10,110,110,110,GREEN);

Workshop - Mostrar Texto e Número

O exemplo ShowTextAndNumber imprime textos e números usando o mecanismo de texto embutido do GFX com tamanho e cor ajustáveis.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32) // --------------------------------------------- // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define MAGENTA DIYables_TFT_SPI::colorRGB(255, 0, 255) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Show text and numbers")); TFT_display.begin(); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(WHITE); // Set text color and size TFT_display.setTextColor(MAGENTA); TFT_display.setTextSize(3); // Sample values float temperature = 23.5; float humidity = 78.6; // Display temperature TFT_display.setCursor(20, 20); TFT_display.print("Temperature: "); TFT_display.print(temperature, 1); TFT_display.print(char(247)); TFT_display.println("C"); // Display humidity TFT_display.setCursor(20, 60); TFT_display.print("Humidity: "); TFT_display.print(humidity, 1); TFT_display.print("%"); } void loop() { }

Mão na Massa

  • Ligue e faça o upload como acima.
  • O display imprime várias linhas de texto em cores e tamanhos diferentes.

Referência de Métodos

Método Ação Sintaxe
setTextColor(color) Define a cor de primeiro plano para a saída de texto. TFT_display.setTextColor(WHITE);
setTextSize(size) Escala o texto por um fator inteiro. Tamanho 1 = 6×8 px. TFT_display.setTextSize(2);
setCursor(x, y) Move o cursor de texto para a posição de pixel (x, y). TFT_display.setCursor(10, 20);
print(value) Imprime um texto ou número na posição do cursor. TFT_display.print("ESP32-S3!");
println(value) Imprime e move o cursor para a próxima linha. TFT_display.println(42);

Workshop - Desenhar Imagem

Nesta estação do workshop você vai carregar uma imagem bitmap RGB565 em cores completas no display. Os dados dos pixels são compilados no firmware como um array PROGMEM dentro do bitmap.h. No ESP32-S3, os dados PROGMEM ficam armazenados na flash e mapeados no espaço de endereços, então nenhuma SRAM é consumida pelos dados da imagem em si. Adicione o bitmap.h à pasta do sketch antes de compilar.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include "bitmap.h" // ============================================= // Wiring (Arduino Nano ESP32) // --------------------------------------------- // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) int img_width = 120; int img_height = 53; void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Draw Image")); TFT_display.begin(); uint16_t SCREEN_WIDTH = TFT_display.width(); uint16_t SCREEN_HEIGHT = TFT_display.height(); int x = (SCREEN_WIDTH - img_width) / 2; int y = (SCREEN_HEIGHT - img_height) / 2; TFT_display.fillScreen(WHITE); TFT_display.drawRGBBitmap(x, y, myBitmap, img_width, img_height); } void loop() { delay(2000); TFT_display.invertDisplay(true); delay(2000); TFT_display.invertDisplay(false); }

Mão na Massa

  • Coloque o bitmap.h na mesma pasta do sketch.
  • Ligue o módulo TFT ao Nano ESP32. Use 3.3V para o VCC.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • O display mostra a imagem bitmap da flash do programa.

Referência de Métodos

Método Ação Sintaxe
drawRGBBitmap(x,y,bitmap,w,h) Desenha um bitmap RGB565 PROGMEM com o canto superior esquerdo em (x, y). TFT_display.drawRGBBitmap(0, 0, myImage, 240, 320);
fillScreen(color) Limpa a tela com uma única cor antes de desenhar o bitmap. TFT_display.fillScreen(BLACK);

Workshop - Desenhar Imagem do Cartão SD

Nesta estação do workshop você envia um arquivo de imagem RGB565 bruto de um cartão micro SD diretamente para o display. O ESP32-S3 lida com o SD e o display no mesmo barramento SPI sem problemas, graças à sua arbitragem de SPI por hardware. Defina o pino CS do módulo SD como SD_CS_PIN no sketch.

Ligue o módulo SD aos mesmos pinos SPI do display (D11/D13/D12 no Nano ESP32). Conecte o CS do SD ao pino escolhido por você.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include <SD.h> // ============================================= // Wiring (Arduino Nano ESP32) // ============================================= // TFT + SD module pins // TFT + SD module Arduino Nano ESP32 // ----------------------- --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // TFT CS -> D10 (TFT_CS_PIN) // TFT RESET -> D9 (TFT_RST_PIN) // TFT DC / RS -> D8 (TFT_DC_PIN) // SD CS -> D4 (SD_CS) // SDI / MOSI (shared) -> D11 (hardware SPI MOSI) // SDO / MISO (shared) -> D12 (hardware SPI MISO) // SCK (shared) -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 #define SD_CS D4 // SD card chip select (must differ from TFT_CS_PIN) // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define BUFFPIXEL 20 File bmpFile; uint16_t SCREEN_WIDTH; uint16_t SCREEN_HEIGHT; // Helper functions to read BMP file header uint16_t read16(File &f) { uint16_t result; result = f.read(); result |= (f.read() << 8); return result; } uint32_t read32(File &f) { uint32_t result; result = f.read(); result |= ((uint32_t)f.read() << 8); result |= ((uint32_t)f.read() << 16); result |= ((uint32_t)f.read() << 24); return result; } int32_t readS32(File &f) { int32_t result; result = f.read(); result |= ((uint32_t)f.read() << 8); result |= ((uint32_t)f.read() << 16); result |= ((uint32_t)f.read() << 24); return result; } bool getBMPDimensions(const char *filename, uint32_t &w, uint32_t &h) { File f = SD.open(filename); if (!f) return false; if (read16(f) != 0x4D42) { f.close(); return false; } read32(f); // file size read32(f); // reserved read32(f); // image offset read32(f); // DIB header size w = read32(f); int32_t sh = readS32(f); h = (sh < 0) ? -sh : sh; f.close(); return true; } void drawBMP(const char *filename, int x, int y) { bmpFile = SD.open(filename); if (!bmpFile) { Serial.println("File not found"); return; } if (read16(bmpFile) != 0x4D42) { Serial.println("Not a BMP file"); bmpFile.close(); return; } uint32_t fileSize = read32(bmpFile); read32(bmpFile); // Reserved uint32_t imageOffset = read32(bmpFile); uint32_t dibHeaderSize = read32(bmpFile); uint32_t bmpWidth = read32(bmpFile); int32_t bmpHeight = readS32(bmpFile); bool topDown = false; if (bmpHeight < 0) { bmpHeight = -bmpHeight; topDown = true; } if (read16(bmpFile) != 1) { Serial.println("Invalid BMP file"); bmpFile.close(); return; } uint16_t depth = read16(bmpFile); if (depth != 24) { Serial.println("Only 24-bit BMP is supported"); bmpFile.close(); return; } if (read32(bmpFile) != 0) { Serial.println("Unsupported BMP compression"); bmpFile.close(); return; } bmpFile.seek(imageOffset); uint8_t sdbuffer[3 * BUFFPIXEL]; uint16_t color; uint32_t rowSize = (bmpWidth * 3 + 3) & ~3; if (x >= SCREEN_WIDTH || y >= SCREEN_HEIGHT) return; uint32_t maxRow = min((uint32_t)bmpHeight, (uint32_t)(SCREEN_HEIGHT - y)); uint32_t maxCol = min(bmpWidth, (uint32_t)(SCREEN_WIDTH - x)); for (uint32_t row = 0; row < maxRow; row++) { int32_t rowPos = topDown ? row : bmpHeight - 1 - row; uint32_t filePosition = imageOffset + rowPos * rowSize; bmpFile.seek(filePosition); for (uint32_t col = 0; col < maxCol; col += BUFFPIXEL) { uint32_t pixelsToRead = min((uint32_t)BUFFPIXEL, maxCol - col); bmpFile.read(sdbuffer, 3 * pixelsToRead); for (uint32_t i = 0; i < pixelsToRead; i++) { uint8_t b = sdbuffer[i * 3]; uint8_t g = sdbuffer[i * 3 + 1]; uint8_t r = sdbuffer[i * 3 + 2]; color = DIYables_TFT_SPI::colorRGB(r, g, b); if ((x + col + i) < SCREEN_WIDTH && (y + row) < SCREEN_HEIGHT) { TFT_display.drawPixel(x + col + i, y + row, color); } } } } bmpFile.close(); Serial.println("BMP drawn"); } void setup() { Serial.begin(9600); if (!SD.begin(SD_CS)) { Serial.println("SD card initialization failed!"); return; } Serial.println("SD card initialized."); TFT_display.begin(); TFT_display.setRotation(1); // Landscape SCREEN_WIDTH = TFT_display.width(); SCREEN_HEIGHT = TFT_display.height(); TFT_display.fillScreen(WHITE); uint32_t imgWidth, imgHeight; if (getBMPDimensions("diyables.bmp", imgWidth, imgHeight)) { int x = (SCREEN_WIDTH - imgWidth) / 2; int y = (SCREEN_HEIGHT - imgHeight) / 2; drawBMP("diyables.bmp", x, y); } else { Serial.println("Failed to get BMP dimensions"); } } void loop() { }

Mão na Massa

  • Ligue o módulo SD ao Nano ESP32. Compartilhe MOSI (D11), SCK (D13) e MISO (D12) com o display. Conecte o CS do SD ao pino definido como SD_CS_PIN.
  • Copie uma imagem binária RGB565 bruta para a raiz do cartão SD. As dimensões devem corresponder ao painel.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • O display renderiza a imagem enviada do cartão SD.

Referência de Métodos

Método Ação Sintaxe
startWrite() Abre uma sessão de escrita SPI bruta, ativando o CS do display. TFT_display.startWrite();
setAddrWindow(x0,y0,x1,y1) Define a região retangular de pixels que vai receber os dados. TFT_display.setAddrWindow(0, 0, 239, 319);
pushColors(buf, len) Escreve um buffer de valores de pixel RGB565 diretamente no painel. TFT_display.pushColors(buf, 512);
endWrite() Fecha a sessão SPI e libera o CS do display. TFT_display.endWrite();

Workshop - Usar Fonte Externa

Nesta estação do workshop você substitui a fonte raster padrão por uma fonte personalizada mais nítida, compatível com o Adafruit GFX. O descritor da fonte é incluído como um arquivo de cabeçalho. Trocar de fonte em tempo de execução exige apenas uma chamada de função, e você pode voltar para a fonte embutida com a mesma facilidade.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include <Fonts/FreeSansBold12pt7b.h> // ============================================= // Wiring (Arduino Nano ESP32) // --------------------------------------------- // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define MAGENTA DIYables_TFT_SPI::colorRGB(255, 0, 255) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Use external font")); TFT_display.begin(); TFT_display.setFont(&FreeSansBold12pt7b); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(WHITE); TFT_display.setTextColor(MAGENTA); TFT_display.setTextSize(1); float temperature = 23.5; float humidity = 78.6; TFT_display.setCursor(20, 30); TFT_display.print("Temperature: "); TFT_display.print(temperature, 1); TFT_display.print(char(247)); TFT_display.println("C"); TFT_display.setCursor(20, 70); TFT_display.print("Humidity: "); TFT_display.print(humidity, 1); TFT_display.print("%"); } void loop() { }

Mão na Massa

  • Ligue o módulo TFT ao Nano ESP32. Use 3.3V para o VCC.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • Observe a renderização da fonte personalizada na tela. Compare com a fonte embutida para ver a melhoria.

Referência de Métodos

Método Ação Sintaxe
setFont(&FontName) Troca para uma fonte personalizada compatível com GFX. Passar NULL restaura a fonte embutida 5×7. TFT_display.setFont(&FreeSans12pt7b);
setCursor(x, y) Posiciona o cursor de texto na coordenada de pixel indicada. TFT_display.setCursor(10, 40);
setTextColor(color) Define a cor de primeiro plano para toda a saída de texto seguinte. TFT_display.setTextColor(WHITE);
print(text) Imprime um texto na posição do cursor usando a fonte ativa. TFT_display.print("ESP32 Workshop");

Workshop - Toque: Obter Ponto

Nesta estação do workshop você lê a saída bruta do ADC do controlador de toque XPT2046 conectado ao Nano ESP32. Cada ponto de toque é impresso no Serial Monitor como valores brutos de X, Y e de pressão Z. Esses números mostram a faixa de ADC que o seu painel produz — uma informação essencial antes de aplicar a calibração.

Ligação: compartilhe o barramento SPI (D11/D13/D12) entre o XPT2046 e o display. T_CS→D7, T_IRQ→D6. Todos os sinais ficam em 3.3V.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Touch Get Point Example ----------------------- This example demonstrates how to read and display touch coordinates using a DIYables SPI TFT display with a 4-wire resistive touch panel. When you touch the screen, the sketch prints the mapped (screen) X and Y coordinates to the Serial Monitor and draws a red dot at the touched location. NOTE: Run the TouchCalibration example first and paste the calibration values into setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32) // ============================================= // TFT pins (always required) // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Nano ESP32 // ------------ --------------------------------- // T_CS -> D2 (TOUCH_CS_PIN) // T_IRQ -> D6 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // MOSI and SCK use default hardware SPI pins // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN D2 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 / HR2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment: //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); Serial.println("Touch the screen to see coordinates."); } void loop() { int x, y; if (TFT_display.getTouch(x, y)) { Serial.print("Touch at: "); Serial.print(x); Serial.print(", "); Serial.println(y); TFT_display.fillCircle(x, y, 4, RED); delay(200); } }

Mão na Massa

  • Ligue o XPT2046 ao Nano ESP32, compartilhando o barramento SPI com o display. T_CS→D7, T_IRQ→D6.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • Abra o Serial Monitor a 9600 baud. Pressione a tela para ver os valores brutos de X, Y e Z aparecerem.

Referência de Métodos

Método Ação Sintaxe
initTouchSPI(cs, irq) Inicializa o XPT2046 no barramento SPI compartilhado. Passe -1 em irq se o pino de interrupção não estiver conectado. TFT_display.initTouchSPI(7, 6);
readTouchRaw(x, y, z) Lê os valores brutos do ADC do controlador, ignorando a calibração. Retorna true quando pressionado. TFT_display.readTouchRaw(x, y, z);

Workshop - Toque: Desenhar

Nesta estação do workshop você cria um aplicativo de pintura por toque no Nano ESP32. O XPT2046 fornece coordenadas calibradas que são convertidas em posições de pixel, e um pequeno círculo preenchido é desenhado em cada ponto. Arraste o dedo para criar um traço pintado contínuo.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Touch Draw Lines Example ------------------------- Draws lines on the screen following the pen. - Touch and drag on the screen to draw. - Lift the pen to stop drawing. - Touch again to start a new line from the last point. NOTE: Run the TouchCalibration example and update setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32) // ============================================= // TFT pins (always required) // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Nano ESP32 // ------------ --------------------------------- // T_CS -> D2 (TOUCH_CS_PIN) // T_IRQ -> D6 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN D2 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 / HR2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define PEN_RADIUS 3 void setup() { TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment: //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); } void loop() { int x, y; if (TFT_display.getTouch(x, y)) { TFT_display.fillCircle(x, y, PEN_RADIUS, RED); } }

Mão na Massa

  • Ligue o XPT2046 ao Nano ESP32 como descrito na estação Toque: Obter Ponto acima.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • Toque e arraste o dedo pelo display para desenhar na tela.

Referência de Métodos

Método Ação Sintaxe
initTouchSPI(cs, irq) Inicia o XPT2046 no barramento SPI compartilhado. TFT_display.initTouchSPI(7, 6);
setTouchCalibration(minX,maxX,minY,maxY) Mapeia as leituras brutas do ADC para coordenadas de pixel da tela. Obtenha os quatro valores na estação TouchCalibration. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
setTouchInvertX(invert) / setTouchInvertY(invert) Inverte o eixo de toque quando X ou Y está espelhado no seu painel ou lote específico. Chame ANTES de setTouchCalibration(). TFT_display.setTouchInvertY(true);
getTouch(x, y) Retorna as coordenadas de toque calibradas em pixels da tela. Retorna true enquanto a tela está pressionada. if (TFT_display.getTouch(x, y)) { ... }
fillCircle(x, y, r, color) Desenha um ponto no local do toque, formando o traço pintado. TFT_display.fillCircle(x, y, 3, RED);

Workshop - Botão de Toque

Nesta estação do workshop você constrói botões interativos na tela que respondem a toques do dedo. Cada botão é um retângulo colorido, e as coordenadas de toque são comparadas com os limites de cada botão a cada ciclo de leitura. Quando um toque é detectado dentro de um botão, o estado do botão muda e a ação é disparada.

O T_IRQ é opcional aqui. Passe -1 como argumento irq para rodar em modo de polling, sem o pino de interrupção.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Touch Button Press/Release Example ------------------------------------ This example shows how to detect press and release events on a rectangular button using a DIYables SPI TFT display with a 4-wire resistive touch panel. When you touch inside the button, it changes colour and shows "PRESSED". When you release, it returns to its original state. NOTE: Run the TouchCalibration example and update setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32) // ============================================= // TFT pins (always required) // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Nano ESP32 // ------------ --------------------------------- // T_CS -> D2 (TOUCH_CS_PIN) // T_IRQ -> -1 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN D2 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 / HR2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define BLACK DIYables_TFT_SPI::colorRGB( 0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define GRAY DIYables_TFT_SPI::colorRGB(128, 128, 128) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define BUTTON_X 30 #define BUTTON_Y 100 #define BUTTON_W 180 #define BUTTON_H 60 #define DEBOUNCE_DELAY 50 bool lastPressed = false; bool stablePressed = false; unsigned long lastDebounceTime = 0; void drawButton(bool pressed) { uint16_t bg = pressed ? GRAY : RED; TFT_display.fillRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, bg); TFT_display.drawRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, BLACK); TFT_display.setTextColor(WHITE, bg); TFT_display.setTextSize(3); TFT_display.setCursor(BUTTON_X + 10, BUTTON_Y + 16); TFT_display.print(pressed ? "PRESSED" : " PRESS "); } void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment: //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); drawButton(false); } void loop() { int x, y; bool pressed = false; if (TFT_display.getTouch(x, y)) { if (x >= BUTTON_X && x < (BUTTON_X + BUTTON_W) && y >= BUTTON_Y && y < (BUTTON_Y + BUTTON_H)) { pressed = true; } } if (pressed != lastPressed) { lastDebounceTime = millis(); } lastPressed = pressed; if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { if (pressed != stablePressed) { stablePressed = pressed; drawButton(stablePressed); Serial.println(stablePressed ? "Button PRESSED" : "Button RELEASED"); } } }

Mão na Massa

  • Conecte o T_CS ao D7. O T_IRQ pode ficar desconectado.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • Toque em cada botão do display. Veja-o destacar e disparar sua ação.

Referência de Métodos

Método Ação Sintaxe
initTouchSPI(cs, irq) Inicializa o XPT2046. Passe -1 em irq para desativar o pino de interrupção. TFT_display.initTouchSPI(7, -1);
setTouchCalibration(minX,maxX,minY,maxY) Aplica a calibração para que getTouch() retorne coordenadas de tela precisas. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
setTouchInvertX(invert) / setTouchInvertY(invert) Inverte o eixo de toque quando X ou Y está espelhado no seu painel ou lote específico. Chame ANTES de setTouchCalibration(). TFT_display.setTouchInvertY(true);
getTouch(x, y) Obtém a posição de toque calibrada atual. Retorna true enquanto a tela está pressionada. if (TFT_display.getTouch(x, y)) { ... }
fillRect(x, y, w, h, color) Renderiza um botão como um retângulo sólido preenchido. TFT_display.fillRect(10, 10, 120, 60, BLUE);

Workshop - Calibração do Toque

Nesta estação do workshop você calibra o controlador de toque XPT2046 para o seu painel específico. Toque em cada canto da tela quando solicitado e anote os valores mínimo e máximo de X e Y impressos no Serial Monitor. Esses quatro números são as constantes de calibração a usar em todas as outras estações de toque.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Touch Screen Calibration Example --------------------------------- This example measures the raw touch coordinates at all four screen corners and prints ready-to-use calibration values to the Serial Monitor. It uses readTouchRaw() directly — it does NOT rely on getTouch() or any existing calibration values, so it works even when touch is completely broken. INSTRUCTIONS: 1. Upload this sketch to your board. 2. Open the Serial Monitor (Ctrl+Shift+M) and set baud rate to 9600. 3. The screen shows a blinking red dot in each corner, numbered 1-4: 1 = Top-left 2 = Top-right 3 = Bottom-right 4 = Bottom-left 4. Press and HOLD firmly on the blinking dot. Keep holding until the Serial Monitor prints "Captured!" for that corner. 5. Release, then wait for the next dot to appear and repeat. 6. After all 4 corners, the Serial Monitor prints the calibration values and a ready-to-use setTouchCalibration() call. Copy it into your sketch. NOTE: While waiting, the Serial Monitor continuously prints the live raw Z/X/Y readings so you can confirm that touch is being detected. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32) // ============================================= // TFT pins (always required) // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Nano ESP32 // ------------ --------------------------------- // T_CS -> D2 (TOUCH_CS_PIN) // T_IRQ -> D6 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN D2 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // Minimum pressure to count as a valid touch. #define TOUCH_Z_MIN 10 // How many consecutive valid samples required before a corner is accepted. #define SAMPLES_NEEDED 10 // Delay between samples (ms). #define SAMPLE_DELAY_MS 30 #define DOT_RADIUS 12 #define BLACK DIYables_TFT_SPI::colorRGB( 0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) // Corner pixel positions - filled in setup() once display size is known. // Order: 0=top-left, 1=top-right, 2=bottom-right, 3=bottom-left int cx[4], cy[4]; // Captured averaged raw values per corner. int cap_x[4], cap_y[4]; // ----------------------------------------------------------------------- void drawDot(int corner, bool on) { uint16_t color = on ? RED : WHITE; TFT_display.fillCircle(cx[corner], cy[corner], DOT_RADIUS, color); TFT_display.setTextSize(2); TFT_display.setTextColor(BLACK, color); TFT_display.setCursor(cx[corner] - 6, cy[corner] - 8); TFT_display.print(corner + 1); } void captureCorner(int corner) { const char* names[] = { "Top-left", "Top-right", "Bottom-right", "Bottom-left" }; Serial.println(); Serial.print("Corner "); Serial.print(corner + 1); Serial.print(" ("); Serial.print(names[corner]); Serial.println(")"); Serial.println(" Press and HOLD firmly on the blinking dot."); Serial.println(" Keep holding until you see 'Captured!'"); unsigned long lastBlink = 0; unsigned long lastPrint = 0; bool dotOn = false; int goodSamples = 0; long sumX = 0, sumY = 0; while (true) { // Blink the dot if (millis() - lastBlink > 400) { lastBlink = millis(); dotOn = !dotOn; drawDot(corner, dotOn); } int raw_x, raw_y, z; TFT_display.readTouchRaw(raw_x, raw_y, z); // Print live readings every 500 ms if (millis() - lastPrint > 500) { lastPrint = millis(); Serial.print(" Z="); Serial.print(z); Serial.print(" X="); Serial.print(raw_x); Serial.print(" Y="); Serial.println(raw_y); } if (z >= TOUCH_Z_MIN) { sumX += raw_x; sumY += raw_y; goodSamples++; if (goodSamples >= SAMPLES_NEEDED) { cap_x[corner] = sumX / goodSamples; cap_y[corner] = sumY / goodSamples; Serial.print(" Captured! raw_x="); Serial.print(cap_x[corner]); Serial.print(" raw_y="); Serial.println(cap_y[corner]); drawDot(corner, false); delay(500); return; } } else { goodSamples = 0; sumX = 0; sumY = 0; } delay(SAMPLE_DELAY_MS); } } // ----------------------------------------------------------------------- void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); // Always calibrate in rotation 0 TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment the line below // BEFORE calibrating (so the printed values match your panel): //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); int w = TFT_display.width(); int h = TFT_display.height(); int m = DOT_RADIUS + 4; cx[0] = m; cy[0] = m; cx[1] = w - m; cy[1] = m; cx[2] = w - m; cy[2] = h - m; cx[3] = m; cy[3] = h - m; Serial.println("=== Touch Calibration ==="); for (int i = 0; i < 4; i++) { captureCorner(i); } // Derive calibration values from the four corners int min_x = (cap_x[0] + cap_x[3]) / 2; // left edge int max_x = (cap_x[1] + cap_x[2]) / 2; // right edge int min_y = (cap_y[0] + cap_y[1]) / 2; // top edge int max_y = (cap_y[2] + cap_y[3]) / 2; // bottom edge Serial.println(); Serial.println("=== Calibration Results ==="); Serial.print(" Left X (min_x): "); Serial.println(min_x); Serial.print(" Right X (max_x): "); Serial.println(max_x); Serial.print(" Top Y (min_y): "); Serial.println(min_y); Serial.print(" Bot Y (max_y): "); Serial.println(max_y); Serial.println(); Serial.println("Copy this line into your sketch:"); Serial.print(" TFT_display.setTouchCalibration("); Serial.print(min_x); Serial.print(", "); Serial.print(max_x); Serial.print(", "); Serial.print(min_y); Serial.print(", "); Serial.print(max_y); Serial.println(");"); TFT_display.fillScreen(WHITE); TFT_display.setTextColor(BLACK); TFT_display.setTextSize(2); TFT_display.setCursor(10, 10); TFT_display.println("Done! Check"); TFT_display.setCursor(10, 35); TFT_display.println("Serial Monitor"); } void loop() {}

Mão na Massa

  • Ligue o XPT2046 ao Nano ESP32 como descrito na estação Toque: Obter Ponto.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • Abra o Serial Monitor a 9600 baud. Toque em cada canto conforme solicitado.
  • Anote os quatro valores impressos e use-os em setTouchCalibration() em todas as outras estações de toque.

Referência de Métodos

Método Ação Sintaxe
initTouchSPI(cs, irq) Inicializa o controlador XPT2046. TFT_display.initTouchSPI(7, 6);
readTouchRaw(x, y, z) Lê os valores brutos do ADC para medir a faixa de calibração. TFT_display.readTouchRaw(x, y, z);
setTouchCalibration(minX,maxX,minY,maxY) Armazena as constantes de calibração para que getTouch() mapeie os valores brutos para coordenadas de pixel. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
setTouchInvertX(invert) / setTouchInvertY(invert) Inverte o eixo de toque quando X ou Y está espelhado no seu painel ou lote específico. Chame ANTES de executar a calibração para que os valores armazenados correspondam ao seu painel. TFT_display.setTouchInvertY(true);

Workshop - SPI Personalizado

Nesta estação do workshop você direciona o display para um barramento SPI que não é o padrão. O Nano ESP32 é construído sobre o ESP32-S3, que suporta vários controladores SPI de hardware. Passar uma instância personalizada de SPIClass ao construtor permite atribuir o display a qualquer periférico SPI disponível — útil quando o barramento padrão é compartilhado com um sensor que exige configurações de modo SPI diferentes.

/* * Este código de Arduino Nano ESP32 foi desenvolvido por pt.newbiely.com * Este código de Arduino Nano ESP32 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io This example demonstrates how to use a custom (non-default) SPI bus with the DIYables TFT SPI library. This is useful on boards that have multiple SPI interfaces, such as: - ESP32: HSPI / VSPI - Arduino Giga / Portenta: SPI1 - Raspberry Pi Pico: SPI1 */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Nano ESP32 - default SPI bus) // --------------------------------------------- // NOTE: The Arduino Nano ESP32 exposes one hardware SPI bus on the Nano // header pins (D11=MOSI, D13=SCK, D12=MISO). MY_SPI must remain &SPI // and the wiring uses the standard hardware SPI mapping below. // // TFT module Arduino Nano ESP32 // ------------ --------------------------------- // VCC -> 3.3V (NOT 5V!) // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D9 (TFT_RST_PIN) // DC / RS -> D8 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN D10 #define TFT_DC_PIN D8 #define TFT_RST_PIN D9 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Select SPI bus // ============================================= // --- Default SPI (D11/D13/D12 on Nano ESP32) --- #define MY_SPI &SPI // ============================================= // Create display object with custom SPI bus // (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); #define BLACK DIYables_TFT_SPI::colorRGB(0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define GREEN DIYables_TFT_SPI::colorRGB(0, 255, 0) #define BLUE DIYables_TFT_SPI::colorRGB(0, 0, 255) void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(BLACK); uint16_t w = TFT_display.width(); uint16_t h = TFT_display.height(); // Draw a simple test pattern TFT_display.fillRect(0, 0, w / 3, h, RED); TFT_display.fillRect(w / 3, 0, w / 3, h, GREEN); TFT_display.fillRect(w * 2 / 3, 0, w / 3, h, BLUE); TFT_display.setTextColor(WHITE); TFT_display.setTextSize(2); TFT_display.setCursor(10, h / 2 - 10); TFT_display.print("Custom SPI bus OK"); } void loop() { // Nothing to do }

Mão na Massa

  • Remova o comentário do construtor SPIClass no sketch que corresponde ao barramento SPI que você quer usar e ligue o display aos pinos correspondentes.
  • Conecte o Nano ESP32 ao seu computador via USB-C.
  • No Arduino IDE, escolha a placa e a porta, cole o código e clique em Upload.
  • O display inicia no barramento SPI selecionado e renderiza um padrão de barras de cores para confirmar o sucesso.

Referência de Métodos

Método Ação Sintaxe
DIYables_ILI9341_SPI(w,h,cs,dc,rst,spi) Construtor que aceita um ponteiro SPIClass explícito como último argumento. O padrão é &SPI quando omitido. DIYables_ILI9341_SPI tft(240, 320, 10, 9, 8, &SPI);
begin() Inicializa o display no barramento SPI configurado. TFT_display.begin();

Solução de Problemas

Problema Causa Possível Solução
Tela preta VCC em 5V, ou CS/DC não conectados Use 3.3V para o VCC; verifique a ligação do CS e do DC
Lixo na tela Construtor do driver errado ativo Deixe apenas um construtor sem comentário
Imagem deslocada ou ausente Largura ou altura erradas no construtor Ajuste os valores ao tamanho físico do seu painel
Toque sem resposta Calibração ausente Execute o exemplo TouchCalibration e copie os valores de saída
Falha no upload Placa no modo errado Mantenha o BOOT pressionado enquanto pressiona o RESET e tente o upload novamente

Suporte a Plataformas

A biblioteca é construída inteiramente sobre as APIs padrão do Arduino e suporta todas as plataformas compatíveis com Arduino (architectures=*).

※ NOSSAS MENSAGENS

  • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!