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

Cable USB de datos

Juego de cables Dupont

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.

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:

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:

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:

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:

La siguiente tabla tomada de lcdwiki lista los pines individuales y sus funciones:
| Número | Etiqueta del pin | Descripción |
|---|---|---|
| 1 | VCC | Entrada de alimentación 5V/3.3V |
| 2 | GND | Tierra |
| 3 | CS | Señal de selección del chip LCD, activo en nivel bajo |
| 4 | RESET | Señal de reset del LCD, activo en nivel bajo |
| 5 | DC/RS | Señal de selección registro/dato del LCD, nivel alto: registro, nivel bajo: dato |
| 6 | SDI(MOSI) | Señal de escritura de datos del bus SPI |
| 7 | SCK | Señal de reloj del bus SPI |
| 8 | LED | Control de retroiluminación, si no se controla, conectar a 3.3V |
| 9 | SDO(MISO) | Señal de lectura de datos del bus SPI, si no necesitas la función de lectura, no lo conectes |
| 10 | T_CLK | Señal de reloj SPI del táctil |
| 11 | T_CS | Señal de selección del chip táctil, activo en nivel bajo |
| 12 | T_DIN | Entrada SPI del táctil |
| 13 | T_DO | Salida SPI del táctil |
| 14 | T_IRQ | Señ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):

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:
| ESP32 | TFT | Táctil |
|---|---|---|
| 5 | CS | – |
| 4 | – | T_CS |
| 17 | RESET | – |
| 16 | DC | – |
| 23 | SDI(MOSI) | T_DIN |
| 18 | SCK | T_CLK |
| 19 | – | T_DO |
| 22 | LED | – |
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:

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:

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.

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.

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:

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í:

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í

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:

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

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:

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

