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:
- Ligar um display TFT SPI de 3.3V ao Arduino Nano ESP32.
- Desenhar formas e gráficos usando as funções do Adafruit GFX.
- Mostrar textos e números em tamanhos diferentes.
- Desenhar imagens bitmap da memória de programa (PROGMEM).
- Desenhar imagens bitmap carregadas de um cartão SD.
- Renderizar texto com uma fonte externa personalizada.
- Ler as coordenadas brutas de toque de um controlador de toque XPT2046.
- Desenhar na tela arrastando o dedo.
- Criar botões de toque interativos.
- Calibrar a tela de toque.
- Usar um barramento SPI secundário ou personalizado para o display.
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.

Hardware Necessário
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
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.

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) |

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) |

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
- Conecte o Arduino Nano ESP32 ao seu computador pela porta USB-C.
- Abra o Arduino IDE. Escolha Arduino Nano ESP32 na lista de placas e selecione a porta correta.
- Clique no ícone Libraries na barra lateral esquerda.
- Digite "DIYables_TFT_SPI" no campo de busca. Encontre a entrada da DIYables.
- Clique em Install. Instale todas as dependências quando solicitado.
- Search for DIYables TFT SPI created by DIYables.io and click the Install button.
Sketch Inicial
O código mínimo necessário para começar com a biblioteca DIYables_TFT_SPI:
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.
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.
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.
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ê.
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.
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.
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.
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.
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.
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.
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=*).