Ir al contenido

Guía de U8g2 para pantallas OLED y LCD con Arduino ​

Esta guía lleva un proyecto U8g2 nuevo desde un lienzo vacío de Lopaka hasta un sketch de Arduino que funciona. Lopaka crea el código de dibujo; tú conectas e inicializas la pantalla, eliges cómo se gestiona el búfer y decides cuándo se muestra cada pantalla.

¿Qué es U8g2? ​

U8g2 es una biblioteca gráfica para pantallas OLED y LCD monocromáticas. Admite muchos controladores, primitivas de dibujo, mapas de bits y una gran colección de fuentes. Lopaka genera código para la API gráfica de U8g2, no para la API U8x8, que solo maneja texto.

Usa el tutorial de configuración y la lista de constructores oficiales para confirmar que U8g2 es compatible con tu pantalla exacta.

Antes de empezar ​

Necesitas:

  • Un microcontrolador y una pantalla monocromática compatibles con U8g2.
  • El nombre del controlador de la pantalla, la resolución y la interfaz: por ejemplo, SSD1306, 128×64, I2C por hardware.
  • La hoja de datos de la pantalla o la guía de cableado del fabricante.
  • Un proyecto compatible con Arduino que pueda compilar y subir un sketch básico.

Advertencia

Lopaka no detecta tu hardware. Dos módulos que parecen iguales pueden usar controladores, direcciones, asignaciones de pines u offsets de pantalla distintos.

Paso 0: Instalar y probar U8g2 ​

En Arduino IDE, abre Tools → Manage Libraries, busca U8g2 e instala la biblioteca de olikraus. Este es el método de instalación que documenta el repositorio oficial de U8g2.

Para una instalación manual en Arduino, descarga la distribución oficial de U8g2 para Arduino y agrega su ZIP con Sketch → Include Library → Add .ZIP Library. Otras toolchains pueden usar la misma distribución oficial mediante su sistema de dependencias de bibliotecas. Prefiere una versión publicada, salvo que necesites específicamente un cambio que todavía no se haya publicado.

Antes de agregar código de Lopaka, compila y sube uno de los ejemplos de U8g2 para tu pantalla. Si el ejemplo funciona, el constructor, el cableado y la instalación de la biblioteca son correctos.

Paso 1: Elegir el constructor de la pantalla ​

El nombre del constructor define cuatro aspectos importantes:

ParteEjemploSignificado
Controlador y pantallaSSD1306_128X64_NONAMEFamilia de hardware y resolución
BúferF, 1 o 2Búfer de pantalla completa o de página
InterfazHW_I2C, SW_I2C, 4W_HW_SPI, etc.Bus e implementación
ArgumentosU8G2_R0, pines de reset y del busRotación y cableado

Por ejemplo:

cpp
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(
    U8G2_R0,
    U8X8_PIN_NONE
);

Este es solo un constructor de ejemplo para una pantalla SSD1306 de 128×64 con I2C por hardware. Reemplázalo por el constructor y los argumentos exactos de la lista de configuración para C++ oficial.

¿Búfer completo o búfer de página? ​

  • Un constructor que contiene _F_ guarda la imagen completa de la pantalla en la RAM. Dibuja entre clearBuffer() y sendBuffer().
  • Un constructor que contiene _1_ o _2_ usa un búfer de página más pequeño. Coloca la función de dibujo completa dentro del bucle de imagen firstPage() / nextPage().

El modo de búfer completo es más simple y rápido, pero usa más RAM. Para una imagen de 128×64 a un bit, el búfer de píxeles ocupa por sí solo 1024 bytes. El modo de página usa menos RAM, pero vuelve a dibujar la misma imagen para cada página. Consulta la guía de modos de búfer de U8g2.

Paso 2: Crear el proyecto de Lopaka ​

  1. Abre lopaka.app y crea un proyecto.
  2. Selecciona U8g2 como plataforma.
  3. Ajusta Tamaño de pantalla al ancho y alto lógicos de la pantalla. Para una pantalla de 128×64 sin rotar, usa 128 × 64.
  4. Mantén el fondo negro predeterminado. La salida de U8g2 es de un bit por píxel, así que los diseños de Lopaka distinguen entre primer plano y fondo en lugar de usar colores RGB.

El tamaño del lienzo de Lopaka define la superficie de diseño y la referencia de coordenadas; no elige un constructor de U8g2 ni configura la pantalla física.

Paso 3: Diseñar una pantalla ​

Usa el editor para colocar texto, imágenes y primitivas de dibujo. La posición (0, 0) es la esquina superior izquierda del lienzo. Cambia el nombre de las capas antes de exportar: los nombres se convierten en comentarios, identificadores de imágenes, encabezados de animaciones y nombres opcionales de variables.

Los proyectos U8g2 de Lopaka generan estos elementos:

Capa de LopakaSalida de U8g2 para Arduino
LíneadrawLine()
RectángulodrawFrame() / drawBox()
Rectángulo redondeadodrawRFrame() / drawRBox()
ElipsedrawEllipse() / drawFilledEllipse()
TriángulodrawTriangle(); siempre relleno en el inspector de U8g2 de Lopaka
PolígonoUna función auxiliar hecha con llamadas drawLine() cerradas; solo contorno
TextosetFont() más drawStr() o drawUTF8()
Capa de pintura, ícono o imagen importadaUn arreglo XBM monocromático más drawXBM() o drawXBMP()
AnimaciónDatos o encabezado de fotogramas más funciones auxiliares para elegir y dibujarlos

Primer plano, fondo e inversión ​

El proyecto U8g2 es monocromático, así que el inspector no muestra un selector de color RGB. Las capas normales encienden píxeles; las capas con Invertido (XOR) usan el color de dibujo 2 (XOR) de U8g2. Lopaka también genera modos transparentes de fuente y de mapa de bits, para que los píxeles vacíos del texto y de las imágenes no borren las capas que están debajo.

U8g2 advierte que no todas las primitivas admiten XOR, incluidas las de elipse. Comprueba las formas invertidas en la pantalla real; consulta setDrawColor.

Posición y línea base del texto ​

Las coordenadas de las formas usan los orígenes habituales de U8g2. El texto usa la línea base de la fuente, no el borde superior de las letras visibles. Por eso, cambiar de fuente puede alterar la alineación vertical aparente aunque la capa de texto mantenga la misma posición.

El texto puede girarse 0°, 90°, 180° o 270°. Lopaka genera setFontDirection() cuando hace falta. Consulta la referencia de la API de U8g2 para los detalles de las coordenadas.

Paso 4: Configurar el código generado ​

Abre Ajustes de código y elige Arduino (Cpp) para un sketch de Arduino. U8g2 también tiene la opción de sintaxis ESP-IDF (C) para proyectos que ya usan la interfaz en C de U8g2; no es una aplicación ESP-IDF completa ni un port de hardware.

AjusteQué cambia en U8g2
Función contenedoraEnvuelve la pantalla activa en void draw{ScreenName}(void)
Declarar como PROGMEMUsa U8X8_PROGMEM y drawXBMP() en las declaraciones de mapas de bits para Arduino
Incluir fuentesIncluye los encabezados descargados de las fuentes personalizadas; las fuentes integradas de U8g2 no necesitan encabezado
Declarar imágenesGenera los arreglos de mapa de bits que usan las capas de pintura y de imagen
Incluir archivos de imagenGenera #include "image_<Name>_bits.h" en lugar de los arreglos de mapa de bits en línea
Funciones auxiliares de animaciónIncluye los encabezados de animación descargados y genera funciones auxiliares de temporización y dibujo
Declarar variablesGenera declaraciones para las propiedades de capa marcadas como variables
Comentarios, títulos de capasAgrega comentarios con el nombre de cada capa a la salida estática
Borrar/rellenar pantallaEmpieza el bloque de dibujo con u8g2.clearBuffer() (Arduino) o u8g2_ClearBuffer() (ESP-IDF); consulta la nota de más abajo

En Arduino, mantén activadas todas las opciones excepto Borrar/rellenar pantalla.

Borrar/rellenar pantalla en Arduino

En la plantilla de Arduino, Borrar/rellenar pantalla está desactivada de forma predeterminada. Si la activas, draw{ScreenName}() empieza con u8g2.clearBuffer(), que borra todo lo que tu sketch haya dibujado en el búfer antes de llamarla. Déjala desactivada si tu loop() ya limpia el búfer o dibuja otro contenido antes. Se omite cuando Funciones auxiliares de animación está activada, porque el bucle firstPage()/nextPage() de la animación ya limpia cada página. La plantilla de ESP-IDF la mantiene activada de forma predeterminada.

Paso 5: Exportar fuentes e imágenes ​

Fuentes integradas ​

Lopaka conoce la lista de fuentes integradas de U8g2 y adapta el código generado a la fuente seleccionada. Cuando una fuente viene integrada en U8g2, Lopaka usa directamente su símbolo de la biblioteca y no genera ni ofrece para descargar un encabezado de fuente aparte. Por ejemplo:

cpp
u8g2.setFont(u8g2_font_6x10_tr);

Si una fuente no está en la lista de integradas, Lopaka la trata como fuente personalizada, genera un único include para su encabezado y muestra ese encabezado en Ajustes de código → Fuentes para que lo descargues.

Los tamaños de las fuentes integradas son fijos; elige otra fuente para agrandar o achicar el texto. Usa la lista oficial de fuentes de U8g2 para revisar qué caracteres incluye cada una.

Fuentes personalizadas ​

Los proyectos U8g2 aceptan fuentes BDF y pueden importar TTF, OTF o WOFF con el asistente de fuentes de tamaño fijo de Lopaka. En Ajustes de código → Fuentes:

  1. Descarga todos los archivos .h personalizados de la lista.
  2. Coloca los encabezados junto a tu sketch o al código fuente generado.
  3. Mantén activada Incluir fuentes para que se conserven las líneas #include "Font_Name.h" generadas.

Incluir solo los glifos usados crea un encabezado más pequeño con los caracteres que usan en ese momento las capas de texto con esa fuente. Si el valor de un texto es una variable en tiempo de ejecución, Lopaka exporta la fuente personalizada completa, porque no puede prever qué caracteres se usarán.

Imágenes y animaciones ​

Las imágenes estáticas se convierten en datos XBM de un bit y pueden declararse directamente en el código copiado. Con Declarar como PROGMEM activada, Lopaka usa U8X8_PROGMEM y drawXBMP(), de acuerdo con las indicaciones de U8g2 sobre mapas de bits en PROGMEM.

Ajustes de código → Imágenes muestra cada imagen como image_<Name>_bits.h, con exactamente los bytes XBM que recibe la llamada de dibujo. Activa Incluir archivos de imagen para generar #include "image_<Name>_bits.h" en lugar del arreglo y dejar los píxeles en el encabezado descargado.

Las animaciones también son monocromáticas. Descarga todos los archivos .h de la lista Animaciones, colócalos junto al sketch y conserva el include y el código auxiliar generados. La función auxiliar de Arduino elige los fotogramas con millis(). Sigues siendo responsable de llamar a la función auxiliar de actualización y de volver a dibujar la pantalla completa con el bucle de búfer correcto.

Advertencia

La salida de animación puede incluir código inicial de setup() y loop(). Incorpora a tu sketch sus includes, la actualización de fotogramas y las funciones auxiliares de dibujo, y luego usa el patrón de refresco con búfer completo o con búfer de página de esta guía. No dejes un segundo setup() ni un segundo loop().

Paso 6: Copiar e integrar el código ​

Crea una pantalla llamada Main, agrega una capa de texto y un marco, y haz clic en Copiar en el panel de código de Lopaka. Una función de dibujo generada típica se ve así:

cpp
void drawMain(void) {
    u8g2.setFontMode(1);
    u8g2.setBitmapMode(1);

    u8g2.setFont(u8g2_font_6x10_tr);
    u8g2.drawStr(8, 18, "Hello!");
    u8g2.drawFrame(0, 0, 128, 64);
}

Tu código usará el nombre de tu pantalla y tus propias capas, fuentes y coordenadas.

Sketch mínimo con búfer completo ​

Usa este patrón solo con un constructor _F_:

cpp
#include <Arduino.h>
#include <Wire.h>
#include <U8g2lib.h>

// Hardware-specific: replace with the constructor for your display.
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(
    U8G2_R0,
    U8X8_PIN_NONE
);

// Paste Lopaka asset declarations, custom-font includes, helpers,
// and the generated drawMain() function here.
void drawMain(void) {
    u8g2.setFontMode(1);
    u8g2.setBitmapMode(1);
    u8g2.setFont(u8g2_font_6x10_tr);
    u8g2.drawStr(8, 18, "Hello!");
    u8g2.drawFrame(0, 0, 128, 64);
}

void setup(void) {
    u8g2.begin();
}

void loop(void) {
    u8g2.clearBuffer();
    drawMain();
    u8g2.sendBuffer();
}

Alternativa con búfer de página ​

Usa este patrón de bucle de imagen con un constructor _1_ o _2_:

cpp
void loop(void) {
    u8g2.firstPage();
    do {
        drawMain();
    } while (u8g2.nextPage());
}

En modo de página, no actualices el estado de la interfaz dentro de drawMain(). U8g2 la llama más de una vez para construir un fotograma, y cada pasada debe dibujar la misma imagen. Actualiza los valores de los sensores, el estado de navegación y la selección del fotograma de animación antes de firstPage().

Paso 7: Agregar datos en tiempo de ejecución y más pantallas ​

Para que un valor sea dinámico, selecciona su propiedad en el inspector, activa su interruptor de variable y mantén activada Declarar variables. Lopaka reemplaza entonces el literal por una declaración con un nombre basado en el de la capa. Tu aplicación puede actualizar ese valor antes del siguiente redibujado.

Cada pantalla de Lopaka se exporta por separado, y su título se convierte en el nombre de la función de dibujo. Copia la función de cada pantalla en el proyecto, combina los includes y recursos compartidos para que se declaren una sola vez y luego elige qué función llamar:

cpp
enum Screen { MAIN, DETAILS };
Screen currentScreen = MAIN;

void drawCurrentScreen(void) {
    if (currentScreen == MAIN) {
        drawMain();
    } else {
        drawDetails();
    }
}

Lopaka no genera navegación entre pantallas, manejo de botones, menús, lecturas de sensores ni estado de la aplicación.

Qué hace Lopaka y qué haces tú ​

Lopaka se encarga deTú te encargas de
Distribución de píxeles y orden de las capasCableado, voltaje y asignación de pines de la pantalla
Llamadas de dibujo de U8g2 para las capas compatiblesConstructor exacto de controlador, interfaz y búfer
Referencias a fuentes integradasInstalar U8g2 y la toolchain de la placa
Conversión de fuentes personalizadas y encabezados descargablesMantener los encabezados personalizados junto al código fuente
Declaraciones de mapas de bits de un bitPresupuesto de RAM y flash, y elección del búfer
Variables opcionales y funciones auxiliares de animaciónbegin(), bucle de refresco, temporización y estado de la aplicación
Una función de dibujo con nombre por cada pantalla exportadaEntradas, navegación, sensores y cuándo volver a dibujar

Compilar, subir e iterar ​

  1. Compila antes de subir. Resuelve primero cada encabezado o símbolo que falte.
  2. Sube el sketch y compara la pantalla física con el lienzo de Lopaka.
  3. Ajusta el constructor, la rotación, el tamaño del lienzo o la posición de las capas según haga falta.
  4. Cuando cambie el diseño, reemplaza toda la sección generada en lugar de editar llamadas generadas sueltas en varios lugares.

Mantén el código de hardware y de la aplicación fuera de la sección generada, para que una nueva exportación no lo sobrescriba:

cpp
// BEGIN LOPAKA GENERATED CODE
// Replace this entire block after exporting again.
// END LOPAKA GENERATED CODE

Solución de problemas ​

La pantalla está en blanco ​

  • Primero sube un ejemplo oficial de U8g2 con el mismo constructor. Si también queda en blanco, revisa la alimentación, la tierra, el cableado, el controlador, el pin de reset y la interfaz.
  • Confirma que u8g2.begin() se ejecuta una sola vez.
  • Confirma que el dibujo ocurre entre clearBuffer() / sendBuffer() con _F_, o dentro del bucle completo firstPage() / nextPage() con _1_ y _2_.
  • Con I2C, escanea el bus y compara el resultado con la documentación del módulo. Si llamas a setI2CAddress(), U8g2 espera la dirección multiplicada por dos y la llamada debe hacerse antes de begin(); consulta la referencia oficial.

La imagen aparece desplazada, recortada, reflejada o girada ​

Comprueba que el lienzo de Lopaka coincida con el tamaño lógico de la pantalla definido por el constructor. Elige la variante exacta de controlador y pantalla: algunos módulos tienen una RAM de controlador más ancha que el panel visible. Usa de U8G2_R0 a U8G2_R3 en el constructor para rotar la pantalla y luego mantén las dimensiones de Lopaka acordes con esa orientación.

Los colores o las formas superpuestas se ven invertidos ​

La salida de U8g2 es de un bit, no en escala de grises ni RGB. Desactiva Invertido (XOR) en la capa si no querías usar XOR. No todas las primitivas de U8g2 admiten XOR, así que comprueba las elipses invertidas en el hardware.

Una fuente o un símbolo no está definido ​

  • Los nombres de las fuentes integradas deben existir en la versión de U8g2 instalada y contener los glifos que usas.
  • Para una fuente personalizada, descarga su .h, guárdalo junto al código fuente y mantén activada Incluir fuentes.
  • Si algunos caracteres salen en blanco, desactiva Incluir solo los glifos usados y vuelve a exportar la fuente personalizada, sobre todo si el texto cambia en tiempo de ejecución.

El sketch se queda sin memoria ​

Prueba un constructor con búfer de página _1_ o _2_, imágenes más pequeñas, menos fotogramas de animación o fuentes personalizadas que contengan solo los glifos necesarios. Las fuentes integradas y los recursos ocupan flash; el búfer completo de la pantalla ocupa RAM.

Las imágenes se ven toscas o invertidas ​

Las imágenes de U8g2 son de un bit, así que el tamaño, el recorte, el contraste, el umbral y el tramado que elijas importan. Vuelve a abrir el asistente de imágenes de Lopaka y revisa la vista previa al tamaño final en píxeles. Mantén Declarar como PROGMEM coherente con la declaración generada y la llamada drawXBMP().

El modo de página parpadea o muestra solo parte de la pantalla ​

Llama a la función de dibujo completa dentro del bucle de imagen do / while. No dibujes algunas capas antes de firstPage(), no cambies valores entre páginas y no llames solo a firstPage() sin nextPage().

Preguntas frecuentes ​

¿Lopaka configura mi pantalla SSD1306 o SH1106? ​

No. Lopaka genera código de dibujo. Tú eliges el constructor, el bus, los pines, la dirección, la rotación, el modo de búfer y la inicialización que correspondan.

¿Puedo usar U8x8 en su lugar? ​

No con la salida U8g2 de Lopaka. U8x8 es una API aparte, solo de caracteres, y no admite las primitivas gráficas que genera Lopaka.

¿Puede Lopaka generar código U8g2 a color? ​

No. La plataforma U8g2 de Lopaka es monocromática. Para una pantalla RGB, elige una plataforma a color como TFT_eSPI o ArduinoGFX.

¿La exportación ESP-IDF (C) es un proyecto de firmware completo? ​

No. Genera código de dibujo para la interfaz en C y los recursos. Tu proyecto ESP-IDF debe configurar la estructura de U8g2, los callbacks de GPIO y del bus, el bucle de tareas, la inicialización y la integración con la plataforma.

¿Dónde puedo aprender más? ​