U8g2 drawXBMP: corrige los problemas de bitmap en SSD1306

Un bitmap convertido puede compilar sin errores y aun así aparecer mal en un SSD1306: en blanco, espejado dentro de cada grupo de ocho píxeles, desplazado un poco más en cada fila o repetido por la pantalla. La reacción habitual es pasar la imagen por el convertidor otra vez con ajustes distintos. Eso rara vez ayuda, porque los bytes pocas veces son el único problema.
Un array de bytes por sí solo no dice qué ancho tiene la imagen, qué bit es el píxel más a la izquierda, cómo se rellena cada fila ni cómo espera tu constructor de pantalla que se dibuje la imagen. Si te equivocas en una de esas cosas, los mismos datos que parecen correctos se convierten en una imagen inclinada o desordenada. Las comprobaciones siguientes separan esas causas en orden: primero demuestra la ruta de dibujo del firmware con un bitmap cuya salida correcta conoces de memoria y después compara tu propia imagen con él.
Para un bitmap XBM en memoria de programa, usa u8g2.drawXBMP(x, y, width, height, bits). El ancho y el alto son dimensiones en píxeles. Si una imagen SSD1306 convertida aparece en blanco, espejada o desplazada, comprueba su formato y su bucle de dibujo antes de convertirla otra vez.
Un bitmap aceptado por U8g2 no es necesariamente la disposición nativa del búfer del controlador SSD1306. Copiar bytes entre esas representaciones sin conversión puede producir un patrón que parece casi correcto.
Prueba con un bitmap asimétrico pequeño
Este ejemplo de 8 × 8 es deliberadamente desigual. Ayuda a distinguir una imagen orientada correctamente de una espejada:
static const unsigned char corner_bits[] U8X8_PROGMEM = {
0x01, 0x03, 0x07, 0x0F,
0x01, 0x01, 0x01, 0x00
};
void drawBitmapTest() {
u8g2.setDrawColor(1);
u8g2.drawXBMP(0, 0, 8, 8, corner_bits);
}Añádelo a un sketch con un objeto de pantalla u8g2 que funcione. En los datos de fila XBM, el bit bajo representa el píxel más a la izquierda de cada byte. La primera fila de arriba enciende su píxel más a la izquierda; la cuarta enciende cuatro píxeles desde la izquierda. La implementación de bitmaps de U8g2 muestra cómo se leen esos bits.

Patrón de prueba, 8 × 8: una escalera que crece desde la esquina superior izquierda y después una sola columna. Si la tuya crece desde la derecha, el orden de bits no coincide. Descarga el archivo XBM correspondiente.
Si esta prueba funciona pero tu logotipo no, mantén la configuración de pantalla e inspecciona los datos del logotipo.
Usa el bucle de dibujo que coincida con tu constructor
Un constructor de búfer completo contiene _F_. Dibuja en ese búfer y después envíalo:
u8g2.clearBuffer();
drawBitmapTest();
u8g2.sendBuffer();Para un constructor de búfer por páginas, como uno que contenga _1_, repite la función de dibujo dentro del bucle de imagen:
u8g2.firstPage();
do {
drawBitmapTest();
} while (u8g2.nextPage());Usa el modo elegido por tu constructor existente. La referencia de configuración de U8g2 explica la nomenclatura y las opciones de búfer. Si estás configurando la pantalla por primera vez, sigue la guía de integración de U8g2 de Lopaka y mantén el constructor específico del controlador del ejemplo que funciona.
Haz coincidir ancho, alto y relleno de filas
Una fila XBM ocupa un número entero de bytes. Para un ancho de 13 píxeles, cada fila usa dos bytes, con tres bits sin usar al final. Una imagen de ocho filas necesita por tanto 16 bytes.
bytes per row = (width + 7) / 8, using integer division
total bytes = bytes per row * heightSi pasas 16 como ancho porque la fila tiene dos bytes, la API dibujará 16 píxeles. Pasa en su lugar el ancho original en píxeles. Si cambias el ancho sin recompactar los datos, las filas pueden empezar en sitios equivocados.
La interfaz antigua drawBitmap() usa un conteo de bytes para el tamaño horizontal, mientras que drawXBM() y drawXBMP() usan píxeles. La referencia de dibujo de U8g2 documenta la distinción y recomienda las funciones XBM.
Lee el síntoma antes de cambiar ajustes
| Symptom | Check |
|---|---|
| Text and the test image are both blank | Constructor, initialization, wiring, and display address |
| Test image works; custom image is blank | Array contents, dimensions, draw color, and coordinates |
| Pixels reverse inside each group of eight | Source bit order versus XBM bit order |
| Rows shift or repeat | Row padding and the width supplied to the function |
| Correct image, wrong foreground/background behavior | Bitmap mode, draw color, and how the background is cleared |
Al mover un ícono, redibuja también el fondo afectado. De lo contrario, los píxeles encendidos de la posición anterior pueden permanecer. Decide si la aplicación limpia el búfer completo o repinta solo la región que cambió.
Exporta el bitmap con su llamada de dibujo
Para un logotipo nuevo, el tutorial del convertidor de imágenes U8g2 cubre la preparación en Lopaka. Mantén juntos el ancho, el alto, el array y la llamada de dibujo generados al mover el resultado al firmware.
El diseño de la pantalla sigue dejando el constructor de pantalla y la configuración del bus a tu proyecto. Los módulos SSD1306 y SH1106 pueden compartir una resolución y aun así necesitar una configuración de controlador distinta. Una vista previa visual no puede validar el cableado ni una dirección I2C.
Preguntas comunes
¿Dibuja drawXBMP toda la pantalla automáticamente?
Dibuja las dimensiones que se le pasan en las coordenadas elegidas. Un logotipo pequeño sigue siendo un logotipo pequeño; posiciónalo explícitamente o prepara un bitmap a pantalla completa.
¿Puedo pegar los bytes de un archivo PNG en el array?
No. La función espera píxeles monocromo compactados, no un archivo PNG comprimido. Convierte primero la imagen.
¿Cómo compruebo el diseño antes de flashear otra vez?
Usa el bitmap asimétrico pequeño para verificar la ruta de firmware y después inspecciona el recurso real en Lopaka. Eso te da una referencia que sabes que funciona mientras ajustas el logotipo.