Guía de TFT_eSPI para pantallas a color con ESP32
Esta guía lleva paso a paso un proyecto TFT a color desde un lienzo vacío de Lopaka hasta una pantalla que funciona con un ESP32.
Aquí el reparto del trabajo importa más que en cualquier otra plataforma: Lopaka dibuja la imagen, tú configuras la biblioteca. TFT_eSPI se configura en tiempo de compilación mediante un archivo de ajustes, y Lopaka nunca toca ese archivo. Primero consigue que la biblioteca se comunique con tu panel y después deja que Lopaka genere el código de dibujo.
¿Qué es TFT_eSPI?
TFT_eSPI es una biblioteca rápida para pantallas SPI en ESP32, ESP8266, RP2040 y STM32. Admite los controladores de la mayoría de los módulos a color económicos (ILI9341, ST7735, ST7789, GC9A01, ILI9488 y muchos más) y te da una sola API de dibujo para todos ellos.
La plataforma TFT_eSPI, M5, Lovyan de Lopaka también cubre dos bibliotecas con API compatible:
| Biblioteca | Hardware típico | Objeto de pantalla en tu sketch |
|---|---|---|
| TFT_eSPI | ESP32/ESP8266/RP2040 genérico + panel | TFT_eSPI tft = TFT_eSPI(); |
| M5GFX (M5Unified) | M5Stack Core, StickC, Dial, Cardputer | M5.Display |
| LovyanGFX | Cualquiera de los anteriores, ESP32-S3 en paralelo | Tu propia subclase LGFX |
Las tres ofrecen las mismas llamadas de dibujo (fillRect, drawString, pushImage, …), así que el mismo código generado funciona en las tres en cuanto el objeto de pantalla se llama tft.
Lo que TFT_eSPI no es
No es un kit de herramientas de interfaz. No hay botones, ni motor de diseño, ni redibujado automático. Dibujas píxeles cuando tú decides dibujarlos. Si quieres widgets y manejo de eventos, mira LVGL.
Antes de empezar
Necesitas:
- Una placa ESP32 (o ESP8266 / RP2040 / STM32) y un módulo TFT a color.
- El nombre del controlador que aparece en la ficha o la hoja de datos de tu módulo, por ejemplo ILI9341, ST7789, GC9A01.
- La resolución (240×320, 240×240, 128×160, …) y los pines a los que conectaste la pantalla.
- Arduino IDE o PlatformIO, capaz de compilar y subir código a tu placa.
Advertencia
Lopaka no detecta tu controlador, no genera el cableado ni escribe la configuración de TFT_eSPI. Dos módulos con la misma resolución pueden necesitar drivers, asignaciones de pines, orden de colores y offsets completamente distintos. Esa parte siempre te corresponde a ti.
Paso 0: Instalar y configurar TFT_eSPI
Este es el paso que los principiantes se saltan para después pasar una tarde frente a una pantalla en blanco. Hazlo primero y no abras Lopaka hasta que un ejemplo de la biblioteca dibuje en tu panel.
Instalar la biblioteca
Arduino IDE: abre Tools → Manage Libraries, busca TFT_eSPI de Bodmer e instálala.
PlatformIO: agrégala a platformio.ini:
lib_deps = bodmer/TFT_eSPIIndicarle cuál es tu pantalla
TFT_eSPI lee su configuración de User_Setup.h en tiempo de compilación, no desde el constructor. Hay dos formas de configurarla y solo eliges una:
- Edita
User_Setup.hen la carpeta de la biblioteca (Arduino/libraries/TFT_eSPI/User_Setup.h). Quita el comentario del#definede tu driver y luego define los pines y la resolución. - Usa un archivo de configuración incluido. Abre
User_Setup_Select.h, comenta la línea#include <User_Setup.h>y quita el comentario de uno de los archivosUser_Setups/Setup*.hque corresponda a tu placa. Es el camino más fácil para placas conocidas como la ESP32 TTGO T-Display.
Un User_Setup.h mínimo para un panel ILI9341 en un ESP32 se ve más o menos así:
#define ILI9341_DRIVER // one driver, uncommented
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
#define LOAD_GLCD // built-in Adafruit 5x7 font
#define LOAD_GFXFF // Free Fonts — required for Lopaka font layers
#define SPI_FREQUENCY 40000000Mantén LOAD_GLCD y LOAD_GFXFF activados
LOAD_GLCD aporta la fuente integrada de 5×7. LOAD_GFXFF habilita setFreeFont(), que usan todas las capas de texto de Lopaka que no llevan la fuente predeterminada. Si LOAD_GFXFF está comentado, tu texto desaparece sin aviso o no compila.
Quienes usan PlatformIO pueden pasar los mismos defines como flags de compilación en lugar de editar los archivos de la biblioteca, y así sobreviven a las actualizaciones de la biblioteca:
build_flags =
-DUSER_SETUP_LOADED=1
-DILI9341_DRIVER=1
-DTFT_WIDTH=240
-DTFT_HEIGHT=320
-DTFT_MOSI=23
-DTFT_SCLK=18
-DTFT_CS=15
-DTFT_DC=2
-DTFT_RST=4
-DLOAD_GLCD=1
-DLOAD_GFXFF=1
-DSPI_FREQUENCY=40000000Comprobar que funciona
Abre File → Examples → TFT_eSPI → Test and Diagnostics → Colour_Test (o Generic → Free_Font_Demo) y súbelo. Deberías ver colores y texto. Si no los ves, corrígelo antes de seguir: mientras la configuración de la biblioteca esté mal, todos los problemas posteriores de esta guía serán imposibles de resolver.
Conserva ese ejemplo que funciona como sketch base. A partir de aquí solo reemplazas sus llamadas de dibujo por la salida de Lopaka.
Paso 1: Crear el proyecto de Lopaka
- Abre lopaka.app y crea un proyecto.
- Selecciona la plataforma TFT_eSPI, M5, Lovyan.
- Ajusta Tamaño de pantalla a la resolución que usa realmente tu sketch.
- Elige el color de fondo de la pantalla: se convierte en el argumento de
fillScreen()en el código generado.
Las coordenadas empiezan en (0, 0) en la esquina superior izquierda; X crece hacia la derecha e Y hacia abajo. Lopaka usa el mismo sistema, así que una capa en (10, 20) en el editor está en (10, 20) en el panel.
Rotación
Si tu sketch llama a tft.setRotation(1) en un panel de 240×320, la pantalla lógica pasa a ser de 320×240, así que el lienzo de Lopaka debe medir 320×240. Lopaka nunca genera setRotation(); ajusta el lienzo a la orientación que elegiste en el código.
Paso 2: Diseñar una pantalla
Coloca capas con la barra de herramientas, cambia su orden en el panel Capas y edita sus valores en el inspector. Las capas se dibujan en el orden de la lista, así que una capa posterior pinta encima de una anterior, exactamente como se ejecutarán las llamadas generadas.
Cambia el nombre de las capas antes de exportar. Los nombres se convierten en comentarios del código, nombres de arreglos de mapas de bits, nombres de funciones auxiliares de polígonos, encabezados de animaciones y nombres de variables.
Qué genera cada capa
| Capa de Lopaka | Llamada de TFT_eSPI generada |
|---|---|
| Punto | tft.drawPixel(x, y, color) |
| Línea | tft.drawLine(x1, y1, x2, y2, color) |
| Rectángulo | tft.drawRect(...) / tft.fillRect(...) |
| Rectángulo redondeado | tft.drawRoundRect(...) / tft.fillRoundRect(...) |
| Elipse | tft.drawEllipse(x, y, rx, ry, color) / tft.fillEllipse(...) |
| Triángulo | tft.drawTriangle(...) / tft.fillTriangle(...) |
| Arco | tft.drawSmoothArc(...) o tft.drawArc(...) |
| Polígono | Una función auxiliar void drawMyShape(void) generada con llamadas drawLine() |
| Texto | setTextColor(), setTextSize(), setFreeFont(), drawString() |
| Capa de pintura / ícono / imagen | tft.drawBitmap(...) (1 bit) o tft.pushImage(...) (RGB565) |
| Animación | Arreglos de fotogramas más las funciones auxiliares updateAnimations() / drawAnimations() |
En esta plataforma no hay herramienta Círculo: usa la herramienta Elipse con radios iguales; las primitivas de elipse de TFT_eSPI cubren ese caso.
Colores
Lopaka te deja elegir cualquier color RGB y luego lo empaqueta en el valor RGB565 de 16 bits que espera TFT_eSPI, así que #FF0000 se convierte en 0xF800. Son 5 bits de rojo, 6 de verde y 5 de azul: 65 536 colores, no 16 millones. Los degradados suaves mostrarán bandas. Los píxeles transparentes de una imagen RGB de origen se combinan de forma predeterminada con el fondo de la pantalla; marca Transparencia en el inspector para que sigan siendo transparentes mediante una máscara de un bit (consulta Imágenes más abajo).
Texto
Las capas de texto generan drawString(text, x, y), donde x, y es la esquina superior izquierda del texto, el TL_DATUM predeterminado de TFT_eSPI. Lopaka ajusta la coordenada Y según las métricas de la fuente seleccionada, así que no tienes que calcular la línea base a mano.
Tres propiedades se corresponden con el estado de la biblioteca, y Lopaka genera cada llamada solo cuando cambia de una capa a otra:
- Color →
setTextColor(fg), osetTextColor(fg, bg)si defines un color de fondo para el texto. Con un fondo, el texto redibujado sobrescribe sus píxeles anteriores en lugar de dejar rastros. - Tamaño →
setTextSize(n), un multiplicador entero de píxeles.2duplica cada píxel, así que el resultado se ve pixelado en lugar de suave. - Fuente →
setFreeFont(&FreeSans9pt7b)para una fuente GFX, osetFreeFont(NULL)para la fuente integrada de 5×7.
Advertencia
Si tu propio código cambia el datum del texto (tft.setTextDatum(MC_DATUM)), el texto generado queda en el lugar equivocado. Restablécelo con tft.setTextDatum(TL_DATUM) antes de llamar a la función de Lopaka.
Arcos
La herramienta Arco es exclusiva de esta plataforma. Los ángulos se miden en grados en sentido horario desde las 12 en punto, así que un indicador de 30 a 330 queda abierto por abajo. La opción Suave del inspector elige entre las dos llamadas de la biblioteca:
// Smooth: antialiased edges, rounded ends
tft.drawSmoothArc(120, 120, 100, 92, 30, 330, 0x07E0, 0x0000, true);
// Not smooth: hard pixel edges
tft.drawArc(120, 120, 100, 92, 30, 330, 0x07E0, 0x0000, false);Ambas reciben un color de fondo, porque los píxeles con antialiasing se mezclan con él. Ajusta el fondo del arco al color sobre el que realmente está, o sus bordes tendrán un halo. drawSmoothArc() requiere TFT_eSPI 2.4.x o posterior: actualiza la biblioteca si el compilador dice que no está definida.
Paso 3: Configurar el código generado
Abre Ajustes de código debajo del panel de código. Esta plataforma tiene dos plantillas de C++ y estas opciones:
Sintaxis elige el framework de destino. Arduino (C++) es la opción predeterminada. ESP-IDF (C++) genera las mismas llamadas de dibujo para un componente de ESP-IDF: los arreglos de imágenes, máscaras y animaciones son arreglos static const uint8_t / uint16_t simples sin PROGMEM, la temporización de las animaciones usa esp_timer_get_time() de esp_timer.h y no se genera setup() / loop(): llama a draw{ScreenName}() y drawAnimations() desde tu propio bucle de tarea. Los encabezados de imágenes y animaciones descargados siguen la plantilla seleccionada.
| Ajuste | Qué hace |
|---|---|
| Función contenedora | Envuelve la pantalla en void draw{ScreenName}(void) |
| Incluir fuentes | Genera #include "FontName.h" para las fuentes personalizadas (consulta Fuentes) |
| Declarar imágenes | Genera los arreglos de mapa de bits a los que hacen referencia las capas de imagen |
| Funciones auxiliares de animación | Genera los includes de los encabezados de animación y las funciones auxiliares de temporización y dibujo |
| Declarar variables | Genera declaraciones para las propiedades de capa que marcaste como variables |
| Comentarios, títulos de capas | Agrega un comentario // Layer name encima de las llamadas de cada capa |
| Borrar/rellenar pantalla | Empieza el bloque con tft.fillScreen(backgroundColor) |
En tu primera exportación, deja todo activado. El botón Copiar copia exactamente lo que muestra el panel.
El objeto debe llamarse tft
Cada línea generada empieza con tft.. La solución más sencilla es llamar tft al objeto de pantalla en tu sketch. En M5Stack, agrega una línea de alias: M5GFX& tft = M5.Display;
Paso 4: Fuentes, imágenes y animaciones
Fuentes
La fuente integrada Adafruit de 5×7 y las Free Fonts (FreeSans, FreeMono y FreeSerif en 9/12/18/24pt, con variantes en negrita y oblicua) no necesitan archivo de encabezado. TFT_eSPI ya compila las Free Fonts cuando LOAD_GFXFF está definido (consulta Indicarle cuál es tu pantalla), así que Lopaka no genera ningún #include para ellas ni las muestra en Ajustes de código → Fuentes.
Todas las demás fuentes sí necesitan un encabezado: las fuentes Adafruit más pequeñas (Org_01, Picopixel, Tiny3x3a2pt7b, Petme8x8) y cualquier fuente que subas. Para cada una de esas fuentes de la pantalla:
- Abre Ajustes de código y busca la sección Fuentes.
- Haz clic en el botón de descarga junto a la fuente para obtener su archivo
.h. - Coloca ese archivo en la misma carpeta que tu
.inoo.cpp. - Mantén activada Incluir fuentes para que la línea
#include "Picopixel.h"siga en la salida.
Lopaka puede convertir fuentes TrueType (.ttf, .otf, .woff) y BDF subidas al formato GFX. Consulta la guía de fuentes para ver las formas de importarlas.
Los datos de las fuentes se guardan en flash. Una fuente de 24pt con el juego de caracteres completo ocupa decenas de kilobytes, así que usa las fuentes grandes con moderación.
Imágenes
Usa la herramienta Imagen para importar y recortar las imágenes a su tamaño final en píxeles. Lo que se genera depende del modo de color de la capa:
- Monocromo → un arreglo
PROGMEMde 1 bit que se dibuja contft.drawBitmap(x, y, bits, w, h, color). Un solo color, píxeles no activados transparentes, 1 bit por píxel. Ideal para íconos. - RGB → un arreglo RGB565
uint16_t PROGMEMque se dibuja contft.pushImage(x, y, w, h, pixels). Color completo, 2 bytes por píxel. Una imagen importada rellena sus píxeles transparentes con el fondo de la pantalla. Marca Transparencia junto a Superposición en el inspector (aparece cuando la imagen tiene píxeles transparentes) y Lopaka también generará un arreglo de un bitimage_<Name>_masky dibujará contft.pushMaskedImage(...), de modo que esos píxeles conserven lo que ya muestra la pantalla.
Ajustes de código → Imágenes muestra cada imagen como image_<Name>_bits.h o image_<Name>_pixels.h, con exactamente los mismos bytes que el arreglo en línea. Activa Incluir archivos de imagen para generar #include "<symbol>.h" en lugar del arreglo y dejar los píxeles en el encabezado descargado.
Vigila el espacio en flash
Una imagen RGB de pantalla completa de 240×320 ocupa 153 600 bytes, aproximadamente el 12% de una partición de sketch estándar de ESP32, por una sola imagen. Recorta al máximo, reduce la escala y usa el modo monocromo para todo lo que sea de un solo color.
Si los colores de las imágenes salen mal mientras las formas se ven bien, consulta el orden de bytes en Solución de problemas.
La guía de importación de imágenes explica el cambio de tamaño, el recorte, el tramado y las estimaciones de tamaño.
Animaciones
Las capas de animación se exportan como fotogramas de 1 bit: un flipbook de dos colores, no un video. Cada fotograma se dibuja con setBitmapColor(foreground, background) seguido de pushImage().
Activar Funciones auxiliares de animación cambia bastante la forma de la salida:
#include "spinner.h"
void updateAnimations() {
animation_spinner_frame = millis() / 100 % 12;
}
void drawAnimation_spinner(void) {
tft.setBitmapColor(0xFFFF, 0x0);
tft.pushImage(80, 60, 32, 32, animation_spinner_frames[animation_spinner_frame], false, nullptr);
}
void drawAnimations() {
updateAnimations();
drawAnimation_spinner();
}
void drawMain(void) { /* static layers */ }
void loop(){
drawAnimations();
};
void setup() {
tft.begin();
drawMain();
}Combina, no pegues
Ese setup() y ese loop() generados son un esqueleto inicial. Tu sketch ya tiene los dos. Conserva un setup() y un loop(): toma los includes, los arreglos de fotogramas, updateAnimations() y las funciones auxiliares de dibujo, y luego llama a drawAnimations() desde tu bucle existente.
Descarga todos los archivos .h de la lista Ajustes de código → Animaciones y guárdalos junto al sketch. Consulta Animaciones para el flujo de trabajo en el editor.
Paso 5: Copiar e integrar
Llama Main a tu pantalla, agrega una capa de texto y un rectángulo, y haz clic en Copiar. Obtendrás algo como esto:
void drawMain(void) {
tft.fillScreen(0x0);
// Title
tft.setTextColor(0xFFFF);
tft.setTextSize(1);
tft.setFreeFont(&FreeSans9pt7b);
tft.drawString("Hello!", 8, 12);
// Border
tft.drawRect(0, 0, 240, 240, 0xFFFF);
}Dentro de un sketch completo:
#include <SPI.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
// ---- BEGIN LOPAKA GENERATED CODE ----
void drawMain(void) {
tft.fillScreen(0x0);
// Title
tft.setTextColor(0xFFFF);
tft.setTextSize(1);
tft.setFreeFont(&FreeSans9pt7b);
tft.drawString("Hello!", 8, 12);
// Border
tft.drawRect(0, 0, 240, 240, 0xFFFF);
}
// ---- END LOPAKA GENERATED CODE ----
void setup() {
tft.init();
tft.setRotation(0);
drawMain();
}
void loop() {}TFT_eSPI escribe directamente en el panel, así que no hay ningún búfer que volcar, nada parecido a la llamada display.display() que necesitan las bibliotecas monocromáticas.
M5Stack
M5GFX es la misma API con otro objeto. Basta una línea de alias:
#include <M5Unified.h>
M5GFX& tft = M5.Display; // now every generated tft.* call works
// Paste the Lopaka block here.
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
drawMain();
}
void loop() { M5.update(); }M5Unified configura automáticamente el panel de cada placa M5, así que te saltas User_Setup.h por completo. Sigue el ejemplo oficial de tu placa para M5.begin().
LovyanGFX
LovyanGFX necesita una clase LGFX que describa tu panel (su repositorio tiene configuraciones listas para las placas más comunes). Llama tft a la instancia y el código generado funciona sin cambios.
Paso 6: Datos en tiempo de ejecución y más pantallas
Hacer que los valores sean dinámicos
El texto estático sirve para una maqueta, pero no para un termómetro. Selecciona una capa, activa en el inspector el interruptor de variable de una propiedad compatible y mantén activada Declarar variables. Lopaka reemplaza el literal por una declaración con el nombre de la capa:
const char* temperature = "21.5 C";
void drawMain(void) {
// ...
tft.drawString(temperature, 8, 40);
}Actualiza la variable en tu código, vuelve a llamar a drawMain() y aparecerá el nuevo valor.
Evita el parpadeo de la pantalla completa
Llamar a drawMain() en un bucle cerrado vuelve a pintar todo y produce parpadeo. Para un valor que cambia a menudo, dale un color de fondo a su capa de texto y vuelve a dibujar solo la llamada de esa capa, o dibuja en un TFT_eSprite y envía el sprite. Los sprites son una función de TFT_eSPI que agregas tú; Lopaka no los genera.
Varias pantallas
Cada pantalla de Lopaka se exporta de forma independiente, y su título se convierte en el nombre de la función. Copia cada una, combina los includes y arreglos de mapas de bits duplicados y deja que tu código elija:
enum Screen { MAIN, SETTINGS };
Screen currentScreen = MAIN;
void drawCurrentScreen(void) {
if (currentScreen == MAIN) {
drawMain();
} else {
drawSettings();
}
}Importar código existente
El panel de código tiene un botón Importar código que lee un archivo .ino, .c, .cpp o .txt y convierte las llamadas tft.* que reconoce en capas editables. Es experimental y funciona mejor con código que generó el propio Lopaka: los sketches escritos a mano, con bucles, variables y funciones auxiliares, no se recuperarán por completo. Las capas importadas se agregan a la pantalla actual.
Qué hace Lopaka y qué haces tú
| Lopaka se encarga de | Tú te encargas de |
|---|---|
| Distribución de píxeles, orden de las capas y llamadas de dibujo | User_Setup.h, elección del driver, pines y frecuencia SPI |
| Empaquetado RGB → RGB565 para formas, texto e imágenes | Orden de colores, inversión y offsets del panel |
| Arreglos de mapas de bits, encabezados de fuentes GFX, fotogramas de animación | Presupuesto de flash y mantener los archivos .h descargados junto al sketch |
| Cálculo de la línea base del texto y llamadas de estado de fuente | El datum del texto si tu código lo cambia |
| Una función de dibujo con nombre por pantalla | Llamarla, el momento de redibujar, las entradas y la navegación |
| Declaraciones opcionales de variables | Actualizar esas variables con datos reales |
Compilar, subir e iterar
- Compila antes de subir y corrige primero los encabezados que falten o los símbolos sin definir.
- Sube el sketch y compara el panel con el lienzo de Lopaka.
- Ajusta el tamaño del lienzo, la rotación o la posición de las capas y vuelve a exportar.
- Cuando cambie el diseño, reemplaza todo el bloque generado. No edites a mano llamadas de dibujo sueltas: la siguiente exportación las sobrescribirá.
Marcar el bloque lo hace sencillo:
// ---- BEGIN LOPAKA GENERATED CODE ----
// Replace this entire block after exporting again.
// ---- END LOPAKA GENERATED CODE ----Solución de problemas
La pantalla está blanca, negra o vacía
Casi siempre se debe a la configuración de la biblioteca, no al código generado.
- Vuelve a ejecutar un ejemplo de TFT_eSPI. Si también queda vacío, el problema está en
User_Setup.h, el cableado o la alimentación. - Confirma que el
#definedel driver correcto no está comentado, y que es el único. - Revisa el pin de la retroiluminación: muchos módulos necesitan
TFT_BLen nivel alto. - Confirma que
tft.init()se ejecuta antes de tu función de dibujo. - Baja
SPI_FREQUENCYa27000000; los cables de puente largos no aguantan 40 MHz.
'tft' was not declared in this scope
El código generado llama a tft.*. Llama tft a tu objeto de pantalla o agrega un alias como M5GFX& tft = M5.Display;.
setFreeFont o drawSmoothArc no está definida
setFreeFont() necesita #define LOAD_GFXFF en User_Setup.h. drawSmoothArc() necesita TFT_eSPI 2.4.x o posterior: actualízala con el Library Manager.
El encabezado de una fuente no compila
Para una Free Font (FreeSans9pt7b y similares) no hay encabezado que agregar: comprueba que LOAD_GFXFF esté definido en User_Setup.h y que en el sketch no quede ningún #include "FreeSans9pt7b.h" de una exportación anterior. Para cualquier otra fuente, descarga el .h desde Ajustes de código → Fuentes, colócalo junto al sketch y mantén activada Incluir fuentes para que coincidan el nombre del archivo, el include y el símbolo &FontName.
Los colores salen mal en todas partes
Si el rojo y el azul están intercambiados en toda la pantalla, es un problema del orden de colores del panel: prueba TFT_RGB_ORDER TFT_BGR (o TFT_RGB) en User_Setup.h. Si la imagen parece invertida, la solución es #define TFT_INVERSION_ON / TFT_INVERSION_OFF. Corrígelo en el archivo de configuración, nunca cambiando todos los colores de tu diseño.
Los colores de las imágenes salen mal, pero las formas están bien
Lopaka escribe los datos RGB565 de las imágenes con los bytes intercambiados, la misma convención que usan la mayoría de los conversores de imágenes para TFT_eSPI. Indícale a la biblioteca que los vuelva a intercambiar antes de enviar las imágenes:
tft.setSwapBytes(true);Llámala una vez en setup(), después de tft.init(). Si las imágenes ya se veían bien y esto las estropea, ponla en false.
El texto aparece en el lugar equivocado
Restablece el datum con tft.setTextDatum(TL_DATUM) antes de la función generada: Lopaka supone el datum predeterminado de la esquina superior izquierda. Si en cambio todo aparece desplazado o recortado, el tamaño del lienzo no coincide con el de la pantalla después de setRotation().
El texto deja manchas al actualizarse
drawString() solo pinta los píxeles de los glifos; los anteriores se quedan. Dale un color de fondo a la capa de texto en Lopaka para que genere setTextColor(fg, bg), o limpia antes la zona con fillRect().
El diseño aparece girado, reflejado o desplazado unos píxeles
Ajusta el lienzo de Lopaka al tamaño lógico después de setRotation(). Un desplazamiento constante de unos pocos píxeles suele indicar una variante de driver equivocada: algunos paneles tienen una RAM de controlador mayor que el área visible y necesitan un define de offset específico del driver.
El sketch no cabe en la flash
Las imágenes RGB565 suelen ser las culpables, con 2 bytes por píxel. Recorta más, reduce la escala, convierte a monocromo las imágenes de un solo color y quita las fuentes grandes que no uses.
El código de animación choca con mi sketch
Conserva un solo setup() y un solo loop(). Toma de la salida generada los includes, los arreglos de fotogramas y las funciones auxiliares; conserva tu propia inicialización y llama a drawAnimations() desde tu bucle existente.
Preguntas frecuentes
¿Lopaka configura TFT_eSPI por mí?
No. User_Setup.h, la elección del driver, los pines y la frecuencia SPI son cosa tuya. Lopaka genera llamadas de dibujo y recursos que suponen un objeto de pantalla llamado tft, ya inicializado y funcionando.
¿Mi pantalla funciona con Lopaka?
Si TFT_eSPI, M5GFX o LovyanGFX la controlan, sí: Lopaka genera código para la API común, no para una lista de módulos. Comprueba primero el módulo con un ejemplo de la biblioteca.
¿Puedo exportar imágenes a todo color?
Sí: las capas de imagen RGB se convierten en arreglos RGB565 que se dibujan con pushImage(). Los fotogramas de animación siempre son de 1 bit, sin importar los colores que usen en el editor.
¿Lopaka genera sprites, DMA o redibujados parciales?
No. Genera llamadas de dibujo directas. TFT_eSprite, las transferencias DMA y el redibujado por rectángulos modificados son optimizaciones que agregas alrededor de la función generada.