U8g2 drawXBMP: corrija problemas de bitmap no SSD1306

Um bitmap convertido pode compilar sem erros e ainda aparecer errado em um SSD1306: em branco, espelhado dentro de cada grupo de oito pixels, deslocado um pouco mais a cada linha ou repetido pela tela. A reação comum é passar a imagem pelo conversor de novo com outras configurações. Isso raramente ajuda, porque os bytes raramente são o único problema.
Um array de bytes sozinho não diz qual é a largura da imagem, qual bit é o pixel mais à esquerda, como cada linha é preenchida nem como o construtor do seu display espera que a imagem seja desenhada. Acerte um deles errado e os mesmos dados com aparência correta viram uma imagem inclinada ou embaralhada. As verificações abaixo separam essas causas em ordem: primeiro prove o caminho de desenho do firmware com um bitmap cuja saída correta você sabe de cor, depois compare a sua própria imagem com ele.
Para um bitmap XBM na memória de programa, use u8g2.drawXBMP(x, y, width, height, bits). Largura e altura são dimensões em pixels. Se uma imagem SSD1306 convertida está em branco, espelhada ou deslocada, confira o formato e o loop de desenho dela antes de converter de novo.
Um bitmap aceito pelo U8g2 não é necessariamente o layout nativo do buffer do controlador SSD1306. Copiar bytes entre essas representações sem conversão pode produzir um padrão que parece quase certo.
Teste com um bitmap assimétrico pequeno
Este exemplo de 8 × 8 é deliberadamente desigual. Ele ajuda a distinguir uma imagem orientada corretamente de uma espelhada:
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);
}Adicione ele a um sketch com um objeto de display u8g2 funcionando. Nos dados de linha XBM, o bit baixo representa o pixel mais à esquerda em cada byte. A primeira linha acima acende o pixel mais à esquerda; a quarta acende quatro pixels a partir da esquerda. A implementação de bitmap do U8g2 mostra como esses bits são lidos.

Padrão de teste, 8 × 8: uma escada que cresce a partir do canto superior esquerdo e depois uma única coluna. Se a sua cresce a partir da direita, a ordem dos bits não corresponde. Baixe o arquivo XBM correspondente.
Se este teste funciona, mas o seu logotipo não, mantenha a configuração do display e inspecione os dados do logotipo.
Use o loop de desenho que corresponde ao seu construtor
Um construtor de buffer completo contém _F_. Desenhe nesse buffer e depois envie ele:
u8g2.clearBuffer();
drawBitmapTest();
u8g2.sendBuffer();Para um construtor de buffer por páginas, como um que contém _1_, repita a função de desenho dentro do loop de imagem:
u8g2.firstPage();
do {
drawBitmapTest();
} while (u8g2.nextPage());Use o modo selecionado pelo seu construtor atual. A referência de configuração do U8g2 explica os nomes e as escolhas de buffer. Se você está configurando o display pela primeira vez, siga o guia de integração do U8g2 do Lopaka e mantenha o construtor específico do controlador do exemplo que funciona.
Combine largura, altura e preenchimento das linhas
Uma linha XBM ocupa um número inteiro de bytes. Para uma largura de 13 pixels, cada linha usa dois bytes, com três bits não usados no fim dela. Uma imagem de oito linhas, portanto, precisa de 16 bytes.
bytes per row = (width + 7) / 8, using integer division
total bytes = bytes per row * heightSe você passar 16 como largura porque a linha tem dois bytes, a API vai desenhar 16 pixels. Passe a largura original em pixels. Se você mudar a largura sem reempacotar os dados, as linhas podem começar nos lugares errados.
A interface mais antiga drawBitmap() usa uma contagem de bytes para o tamanho horizontal, enquanto drawXBM() e drawXBMP() usam pixels. A referência de desenho do U8g2 documenta a distinção e recomenda as funções XBM.
Leia o sintoma antes de mudar as configurações
| Sintoma | Confira |
|---|---|
| Texto e imagem de teste ambos em branco | Construtor, inicialização, fiação e endereço do display |
| Imagem de teste funciona; imagem personalizada em branco | Conteúdo do array, dimensões, cor de desenho e coordenadas |
| Pixels se invertem dentro de cada grupo de oito | Ordem de bits da origem versus ordem de bits XBM |
| Linhas deslocam ou se repetem | Preenchimento das linhas e largura passada para a função |
| Imagem correta, comportamento de primeiro plano/fundo errado | Modo do bitmap, cor de desenho e como o fundo é limpo |
Quando você move um ícone, redesenhe também o fundo afetado. Caso contrário, pixels acesos da posição anterior podem continuar. Decida se a aplicação limpa o buffer inteiro ou repinta só a região que mudou.
Exporte o bitmap com a chamada de desenho dele
Para um logotipo novo, o passo a passo do conversor de imagens U8g2 cobre a preparação no Lopaka. Mantenha a largura, a altura, o array e a chamada de desenho gerados juntos quando você mover o resultado para o firmware.
O design da tela ainda deixa o construtor do display e a configuração do barramento para o seu projeto. Módulos SSD1306 e SH1106 podem compartilhar uma resolução e precisar de configurações de controlador diferentes. Uma pré-visualização visual não consegue validar a fiação nem um endereço I2C.
Perguntas frequentes
O drawXBMP desenha a tela inteira automaticamente?
Ele desenha as dimensões passadas para ele nas coordenadas escolhidas. Um logotipo pequeno continua um logotipo pequeno; posicione ele explicitamente ou prepare um bitmap em tela cheia.
Posso colar os bytes de um arquivo PNG no array?
Não. A função espera pixels monocromáticos empacotados, e não um arquivo PNG comprimido. Converta a imagem primeiro.
Como confiro o layout antes de gravar de novo?
Use o bitmap assimétrico pequeno para verificar o caminho do firmware e depois inspecione o recurso real no Lopaka. Isso dá para você uma referência que você sabe que funciona enquanto ajusta o logotipo.