Skip to Content

Interfaz de pantalla táctil TFT ILI9341 con ESP32

Interfaz de pantalla táctil TFT ILI9341 con ESP32

En este tutorial aprenderás a controlar una pantalla táctil TFT ILI9341 de 2.8 pulgadas y resolución 240×320 con un WEMOS Lolin32 lite (ESP32) usando la biblioteca TFT_eSPI.

Las instrucciones y el código funcionarán con algunos cambios menores para otros ESP32 y pantallas TFT, siempre que la pantalla use el ILI9341 controlador de pantalla y el XPT2046 controlador táctil.

Partes necesarias

Necesitarás un ESP32 y una pantalla táctil TFT de 2.8 pulgadas con resolución 240×320 píxeles y un controlador de pantalla ILI9341. También pueden ser útiles algunos cables y una protoboard.

Pantalla táctil TFT ILI9341 de 2.8 pulgadas

ESP32 lite Lolin32

ESP32 lite

USB data cable

Cable USB de datos

Dupont wire set

Juego de cables Dupont

Half_breadboard56a

Protoboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Módulo de pantalla táctil TFT ILI9341 de 2.8″

Existen algunas variaciones y clones de este módulo de pantalla de 2.8 pulgadas, pero suelen ser muy similares y la mayoría debería funcionar. La pantalla TFT tiene una resolución de 240×320 píxeles con 65K colores RGB y se controla vía SPI usando el ILI9341 chip controlador de pantalla.

Además, la pantalla tiene una pantalla táctil resistiva con un XPT2046 chip controlador táctil. También cuenta con un socket para tarjeta MicroSD en la parte trasera, que podrías usar para almacenar imágenes, por ejemplo. La imagen a continuación muestra el frente y la parte trasera del módulo de pantalla.

Front and back of 2.8" TFT ILI9341 Touch Display Module
Frontal y trasera del módulo de pantalla táctil TFT ILI9341 de 2.8″ (source)

El módulo de pantalla tiene un regulador de voltaje incorporado y puede alimentarse con 3.3V … 5V en VCC. Sin embargo, no hay un conversor de nivel lógico, lo que significa que no puedes conectar directamente un Arduino Uno que funciona con lógica de 5V a la interfaz SPI del módulo que opera a 3.3V.

Conectar el módulo de pantalla TFT ILI9341 a Arduino

Si quieres usar la pantalla con un Arduino necesitarás un conversor de nivel. Puedes usar divisores de voltaje o un level shifter module adecuado. Como solución rápida, Techtonics sugiere añadir resistencias de 10k en las líneas SPI:

Connect Arduino Uno to TFT Display using 10K resistors
Conectar Arduino Uno a pantalla TFT usando resistencias de 10K (source)

Probablemente esto funcione (no lo he probado), pero usar un level shifter module adecuado sería una solución más fiable y segura. Alternativamente, simplemente usa un microcontrolador que opere a lógica de 3.3V, como el ESP32 que usaremos aquí.

Ejecutar el módulo de pantalla táctil TFT ILI9341 a 3.3V

Si sabes que vas a alimentar el módulo a 3.3V (VCC=3.3V), puedes saltarte el regulador de voltaje (U1) cerrando (soldando) los pads jumper etiquetados J1 en la parte trasera del módulo. Mira la imagen a continuación:

Jumper J1 para saltar el regulador de voltaje

Esto puede hacer que la pantalla funcione más estable al evitar la caída de voltaje del regulador y también reducirá un poco el consumo de energía. Mira el esquema del regulador de voltaje y cómo afecta el jumper J1 a la conexión:

Schematic for Voltage Regulator and Bypass Jumper J1
Esquema del regulador de voltaje y jumper de bypass J1 (source)

Yo no cerré J1 (lo dejé abierto como viene) y la pantalla funcionó bien, pero si tienes problemas de estabilidad, puedes probar a cerrar J1.

Sin embargo, una vez que soldes (cierres) J1 ya no podrás alimentar con 5V en VCC. ¡Debes usar 3.3V en VCC!

Pinout del módulo de pantalla táctil TFT ILI9341

La imagen a continuación muestra la parte trasera del módulo con los pines de conexión. Puedes ver dos grupos: los pines para el controlador táctil y los pines SPI para la pantalla, abajo:

Pinout of TFT ILI9341 Touch Display Module
Pinout del módulo de pantalla táctil TFT ILI9341

La siguiente tabla tomada de lcdwiki lista los pines individuales y sus funciones:

NúmeroEtiqueta del pinDescripción
1VCCEntrada de alimentación 5V/3.3V
2GNDTierra
3CSSeñal de selección del chip LCD, activo en nivel bajo
4RESETSeñal de reset del LCD, activo en nivel bajo
5DC/RSSeñal de selección registro/dato del LCD, nivel alto: registro, nivel bajo: dato
6SDI(MOSI)Señal de escritura de datos del bus SPI
7SCKSeñal de reloj del bus SPI
8LEDControl de retroiluminación, si no se controla, conectar a 3.3V
9SDO(MISO)Señal de lectura de datos del bus SPI, si no necesitas la función de lectura, no lo conectes
10T_CLKSeñal de reloj SPI del táctil
11T_CSSeñal de selección del chip táctil, activo en nivel bajo
12T_DINEntrada SPI del táctil
13T_DOSalida SPI del táctil
14T_IRQSeñal de interrupción táctil, nivel bajo cuando se detecta toque

Conexión de la pantalla táctil TFT ILI9341 al ESP32

La siguiente imagen muestra cómo conectar el módulo de pantalla táctil a un WEMOS Lolin32 lite (ESP32):

Connecting the TFT ILI9341 Touch Display to ESP32
Conexión de la pantalla táctil TFT ILI9341 al ESP32

Hay bastantes conexiones que hacer y la siguiente tabla debería ayudar. Nota que las líneas SDI(MOSI) y SCK de la interfaz SPI se comparten entre el controlador táctil y el controlador de la pantalla TFT:

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

Podrías conectar el pin 19 del ESP32 a SDO(MISO) también, pero como no leemos datos del controlador TFT no lo necesitaremos y se han reportado casos donde esto causa problemas. Yo no conecté el pin 19 a SDO(MISO) y la pantalla funcionó bien.

Ten en cuenta que también dejamos T_IRQ del módulo de pantalla sin conectar. Este pin indica si se detectó un toque en la pantalla y podrías usarlo para despertar el ESP32 del deep-sleep, por ejemplo. Sin embargo, en este tutorial no implementamos esta funcionalidad.

El cableado es bastante complejo y conecté dos protoboards para colocar el ESP32 y la pantalla TFT. La buena noticia es que, aparte de tierra (GND), todas las conexiones están en un lado del ESP32, lo que simplifica un poco el cableado. La imagen a continuación muestra mi montaje:

Wiring of TFT ILI9341 Touch Display with ESP32 on breadboard
Cableado de la pantalla táctil TFT ILI9341 con ESP32 en protoboard

Control de retroiluminación para la pantalla táctil TFT ILI9341

Ten en cuenta que el LED de retroiluminación del módulo se conmuta mediante un transistor, por lo que podemos controlarlo directamente vía un GPIO; en nuestro caso usamos el pin 22 del ESP32. Mira el esquema del circuito de control del LED a continuación:

Schematic for LED backlight
Esquema para el control de retroiluminación LED (source)

Controlador táctil para la pantalla táctil TFT ILI9341

Como se mencionó antes, el controlador táctil del módulo de pantalla es un XPT2046. El esquema a continuación muestra cómo está conectado el controlador dentro del módulo de pantalla.

Schematic for Touch Controller
Esquema del controlador táctil (source)

Socket para tarjeta SD en la pantalla táctil TFT ILI9341

Finalmente, el módulo de pantalla tiene un socket para tarjeta SD. La imagen a continuación muestra el esquema de este socket. Internamente solo está conectado a VCC y GND.

Schematic for SD Card Socket
Esquema del socket para tarjeta SD (source)

La interfaz SPI (SD_CS, SD_MOSI, SD_CLK) es accesible mediante pines externos en la parte trasera del módulo. Pero ten en cuenta que SD_MISO no está conectado:

Pines SPI para el socket de tarjeta SD

Sin embargo, no usaremos el socket de tarjeta SD en este tutorial.

Código para la pantalla táctil TFT ILI9341 con la biblioteca TFT_eSPI

En esta sección vamos a utilizar la TFT_eSPI library para controlar la pantalla y la interfaz táctil. Para install esta biblioteca, abre el Library Manager, busca «TFT_eSPI» y presiona «INSTALL». Tras una instalación exitosa debería verse así:

TFT_eSPI library in Library Manager
Biblioteca TFT_eSPI en el Library Manager

Luego necesitamos crear la estructura correcta de carpetas para el proyecto. Abre tu Arduino IDE y crea un proyecto llamado «tft_test» y guárdalo (Guardar como …). Esto creará una carpeta «tft_test» con el archivo «tft_test.ino» dentro. En esta carpeta crea otro archivo llamado «tft_setup.h«. Tu carpeta de proyecto debería verse así

Project Folder Structure
tft_test

Si quieres aprender más sobre esta configuración y otras opciones para configurar una pantalla TFT con la biblioteca TFT_eSPI, echa un vistazo al tutorial How to configure TFT_eSPI Library for TFT display.

tft_setup.h para la pantalla táctil TFT ILI9341

Después de crear la carpeta del proyecto con los dos archivos, copia el siguiente código de configuración para la pantalla TFT en el archivo 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

La parte más importante de este archivo de configuración es seleccionar el controlador de pantalla correcto. En nuestro caso es el ILI9341. Ten en cuenta que hay una definición alternativa:

#define ILI9341_DRIVER      
//#define ILI9341_2_DRIVER  

Si tienes problemas con tu pantalla, prueba el ILI9341_2_DRIVER en lugar del ILI9341_DRIVER.

También son importantes las constantes para el ancho y alto de la pantalla y el orden de los canales de color.

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

Si tu contenido aparece cortado o los colores son incorrectos, asegúrate de que tienes las dimensiones (TFT_WIDTH, TFT_HEIGHT) y el TFT_RGB_ORDER correctos. El TFT_RGB_ORDER puede ser TFT_BGR o TFT_RGB.

Ten en cuenta que también hay una definición para invertir blanco y negro (#define TFT_INVERSION_ON), en caso de que tengas ese problema. Para todas las configuraciones posibles, consulta el archivo User_Setup.h.

Luego tenemos las definiciones de pines. Estoy usando un WEMOS Lolin32 lite (ESP32) y los pines para SPI por hardware son (MOSI=23, MSIO=19, SCK=18):

#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

Dependiendo de tu microcontrolador estos pines pueden variar. Debes encontrar y usar los pines para SPI por hardware, ya que permiten una comunicación más rápida y por tanto una pantalla más rápida. Los otros pines puedes elegirlos libremente.

Las constantes para las fuentes usualmente no necesitas cambiarlas. Sin embargo, si te quedas sin memoria, puedes eliminar fuentes no usadas de la lista.

#define LOAD_GLCD   
...
#define SMOOTH_FONT 

Las constantes para SPI_FREQUENCY y SPI_TOUCH_FREQUENCY son algo críticas. Si son demasiado altas verás contenido distorsionado y el reconocimiento táctil será inestable. Los valores aquí funcionaron para mí, pero para otro microcontrolador o pantalla puede que tengas que bajarlos.

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

Código de prueba para la pantalla táctil TFT ILI9341

En esta sección te mostraré un código de prueba que puedes usar para probar la pantalla y la detección táctil. Simplemente copia el siguiente código en el archivo 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);
  }
}

El código comienza incluyendo la biblioteca requerida y el archivo de configuración.

#include "tft_setup.h"
#include "TFT_eSPI.h"

Luego creamos el objeto de la pantalla TFT y un array para almacenar los parámetros de calibración de la pantalla táctil:

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

Función calibrate_touch

Inicialmente los parámetros de calibración están en cero, pero los completaremos más adelante. La función calibrate_touch() se usa para obtener estos parámetros de calibración:

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]);
  }
}

Si aún no están establecidos (!cal[1]), la función limpia la pantalla y luego llama a tft.calibrateTouch(), que llena el array cal. Esta función dibuja flechas (en color amarillo con fondo negro y tamaño de 20 píxeles) en las esquinas de la pantalla y el usuario debe tocar las esquinas para calibrar la pantalla. Más sobre esto después. Una vez que tenemos los parámetros cal, los imprimimos en el Monitor Serial.

Función setup

En la función setup() inicializamos el Monitor Serial y la pantalla TFT, calibramos la pantalla táctil si es necesario y luego mostramos el texto «Makerguides» en la pantalla:

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

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

  tft.fillScreen(TFT_BLACK);
  ...
  tft.drawString("Makerguides", TFT_HEIGHT / 2, TFT_WIDTH / 2);
}

Función loop

En la función loop() llamamos a getTouch para comprobar si se detectó un toque. Si es así, imprimimos las coordenadas del toque en el Monitor Serial y dibujamos un pequeño círculo amarillo en el punto tocado:

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

Control de retroiluminación

Finalmente, si quieres apagar el LED de retroiluminación de la pantalla para reducir el consumo cuando no se usa, puedes poner el pin TFT_BL a LOW:

pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, LOW);    // Switch off Backlight  

No uso esto en este código, pero funciona. Podría ser útil para ahorrar energía al poner el ESP32 en deep-sleep y solo despertarlo cuando se detecte un toque.

En la siguiente sección aprenderemos a calibrar la pantalla táctil.

Calibración de la pantalla táctil TFT ILI9341

Si subes y ejecutas el código, la pantalla arrancará en modo calibración. Esto es necesario para calibrar la pantalla táctil y que la función tft.getTouch(&x, &y) devuelva las coordenadas correctas en pantalla para un toque.

En modo calibración, la pantalla muestra primero una flecha amarilla en la esquina superior izquierda. Usa un bolígrafo y toca la pantalla en la esquina a la que apunta la flecha. Nota que si quieres flechas más grandes/pequeñas, o de otro color o fondo, puedes cambiar los parámetros de la función tft.calibrateTouch():

tft.calibrateTouch(cal, TFT_YELLOW, TFT_BLACK, 20);

Si el toque se registró correctamente, la pantalla mostrará una flecha en la esquina superior derecha. Toca esa esquina y repite el proceso hasta que se hayan tocado las cuatro esquinas. La imagen a continuación muestra las cuatro flechas durante los cuatro pasos del proceso de calibración:

Calibración de la pantalla táctil TFT ILI9341

Después del cuarto toque, la pantalla mostrará el texto «Makerguides» en el centro (sin flechas):


End of calibration of TFT ILI9341 Touch Display
Fin de la calibración de la pantalla táctil TFT ILI9341

Lo más importante es que el código también imprimirá los parámetros de calibración cal en el Monitor Serial. Deberías ver una impresión similar a la siguiente:

cal[5] = {397, 3495, 294, 3495, 7};

Copia estos valores y reemplaza los parámetros de calibración en cero para la constante cal (cal[5] = { 0, 0, 0, 0, 0 }) en el sketch tft_test.ino por los valores que viste en el Monitor Serial:

// tft_test.ino

...

uint16_t cal[5] = {397, 3495, 294, 3495, 7};

void calibrate_touch() {
...

Luego compila y sube el código de nuevo.

Detección de toques con la pantalla táctil TFT ILI9341

Cuando los parámetros cal están configurados, el código saltará el paso de calibración, mostrará directamente «Makerguides» y estará listo para detectar entradas táctiles. Usa un bolígrafo y debería aparecer un punto amarillo donde toques la pantalla. Abajo una foto de la pantalla mientras pruebo las entradas táctiles:

Touch input on TFT ILI9341 Touch Display
Entrada táctil en la pantalla táctil TFT ILI9341

Si los puntos amarillos aparecen desplazados del lugar donde tocaste la pantalla, la calibración es incorrecta. Puedes rehacer la calibración poniendo los parámetros cal a cero (cal[5] = { 0, 0, 0, 0, 0 }).

Ten en cuenta que el Monitor Serial imprimirá las coordenadas táctiles detectadas una vez completada la calibración. Puedes usar esto para verificar la calibración o para añadir botones que reaccionen al toque, por ejemplo.

241 51
240 54
240 53
241 47
243 46
...

Consulta el tutorial Digital Clock with CrowPanel 3.5″ ESP32 Display para un ejemplo.

Conclusiones

En este tutorial aprendiste a controlar una pantalla táctil TFT ILI9341 de 2.8 pulgadas y resolución 240×320 con un WEMOS Lolin32 lite (ESP32) usando la biblioteca TFT_eSPI.

Si tienes dificultades con la biblioteca TFT_eSPI, nuestro How to configure TFT_eSPI Library for TFT display puede ayudarte. También hay una larga discusión here sobre problemas con esta pantalla específica.

Si tienes una pantalla diferente con un controlador ST7735 o quieres aprender a usar la biblioteca Adafruit, el Interface TFT ST7735 Display with ESP32 tutorial puede ser útil para ti.

Y para pantallas TFT redondas, echa un vistazo al tutorial Digital Clock on CrowPanel 1.28″ Round Display.

Si tienes algún comentario, no dudes en dejarlo en la sección de comentarios.

¡Feliz bricolaje ; )