Problema de pantalla OLED 128 x 32 SSD1306 (imagen interior)

Compré una de estas pantallas OLED baratas de 0,91" y la conecté de acuerdo con una hoja de datos que me envió el vendedor. Probé varios controladores después de pensar que había problemas de compatibilidad, pero todos daban el mismo problema. Solo la parte superior de la pantalla muestra caracteres, el resto parece píxeles aleatorios y parpadea mientras las líneas suben y bajan. VBAT + VDD están conectados a ~ 3.3V.

¿Quizás alguien pueda detectar el problema simplemente mirando la imagen de la pantalla?

Cableado, las tapas de 1uF son de cerámica, las de 4.7uF electroAquí está la secuencia de iniciación:

void oled_init() {
    L(PORTE, SS1306_OLED_RST);
    _delay_ms(10);
    H(PORTE, SS1306_OLED_RST);
    _delay_ms(10);

    oled_write(0, 0xAE); // display off
    oled_write(0, 0xD5); // clock
    oled_write(0, 0x81); // upper nibble is rate, lower nibble is divisor
    oled_write(0, 0xA8); // mux ratio
    oled_write(0, 0x3F); // rtfm
    oled_write(0, 0xD3); // display offset
    oled_write(0, 0x00); // rtfm
    oled_write(0, 0x00);
    oled_write(0, 0x8D); // charge pump
    oled_write(0, 0x14); // enable
    oled_write(0, 0x20); // memory addr mode
    oled_write(0, 0x00); // horizontal
    oled_write(0, 0xA1); // segment remap
    oled_write(0, 0xA5); // display on
    oled_write(0, 0xC8); // com scan direction
    oled_write(0, 0xDA); // com hardware cfg
    oled_write(0, 0x12); // alt com cfg
    oled_write(0, 0x81); // contrast aka current
    oled_write(0, 0x7F); // 128 is midpoint
    oled_write(0, 0xD9); // precharge
    oled_write(0, 0x11); // rtfm
    oled_write(0, 0xDB); // vcomh deselect level
    oled_write(0, 0x20); // rtfm
    oled_write(0, 0xA6); // non-inverted
    oled_write(0, 0xA4); // display scan on
    oled_write(0, 0xAF); // drivers on
}

Y lo que muestra la pantalla LCD después de que le envié algunos caracteres.ingrese la descripción de la imagen aquí

Parece una especie de desbordamiento de búfer de RAM en su código.
¿Cuál es la plataforma de acogida?
@Zuofu - ATmega128A
Hmm, el ATmega128A solo tiene 4 KBytes de memoria, exactamente el tamaño que necesita para un búfer de cuadros, suponiendo 8 bpp monocromáticos (128 * 32). Sin embargo, eso suponiendo que no haya absolutamente ningún gasto general, lo que nunca es cierto si está utilizando un compilador (espacio de pila, etc.) ¿Cómo está dibujando los caracteres?
Describa también lo que pensó que estaba escribiendo en la pantalla (algún mensaje, o ???), y también muestre una imagen de resolución mucho mejor (solo de la pantalla) para comparar.
Yo tuve el mismo problema. Puede que no sea un OLED con el controlador SSD1306 sino un SH1106 parecido. Podría ayudar si usas la biblioteca U8g de Google. ¡Funcionó para mí! Buena suerte

Respuestas (3)

Adivinando en lugar de más información (ver mis comentarios arriba). Parece sospechosamente que lo que se dibuja es 1/8 de la pantalla. El controlador dice que opera a 8 bits por píxel (256 niveles monocromáticos). ¿Está dibujando en la pantalla como si fuera una pantalla de 1 bit por píxel en lugar de 8? Como señalé en el comentario anterior, no podrá mantener un búfer de cuadros a 8 bpp y aún le quedará RAM para hacer cualquier otra cosa.

Parece que el controlador de la pantalla definió un búfer de cuadros que es tan grande como la RAM que tengo en el dispositivo... Me estoy mudando a un ATmega328. ¡Gracias!
Genial, pero el ATmega328 tiene incluso menos SRAM (2KB). El problema no es la memoria flash (o la memoria del programa), es SRAM. Hay algunos controladores MegaAVR que tienen 8 KB, que deberían ser suficientes para esta aplicación: atmel.com/Images/8491E_MegaAVR_E_US_110112_LoRes.pdf

Respondiendo en caso de que alguien realmente necesite resolver el problema,

Si no está familiarizado con el SSD1306, sería una buena idea leer la documentación.

Cada byte es vertical, con el LSB en la parte superior y el MSB en la parte inferior. La pantalla está separada en varias páginas, cada una de las cuales almacena 1 byte por N columnas. Para una pantalla de 128 por 32 píxeles, son 4 páginas de alto (8*4=32) y 128 columnas de ancho. Todo esto se puede reasignar, pero si sigue las guías del fabricante, la configuración predeterminada es la que describo.

Cuando escribe un byte de datos, por cualquier método, incrementará el puntero de la columna en uno. Entonces, si establece la columna y la página en cero, se encuentra en la parte superior izquierda de la pantalla. Si escribe 10 bytes todos 0xff, tendría un cuadrado de 10x8 píxeles en la parte superior izquierda de la pantalla. Si continúa y escribe 128, se llenará toda la página superior.

Sin embargo, si configura el modo de dirección incorrectamente, no se incrementará automáticamente la página. Entonces, es posible que tenga un búfer lleno (que tiene solo 512 bytes), pero solo está escribiendo los primeros 128 de esos bytes, después de lo cual no sé qué sucederá. Parece que se sale de la página, en lugar de volver a escribir sobre ella.

Entonces, tl; dr, cambie el modo de dirección a horizontal para que aumente automáticamente la página. Alternativamente, escriba 128 bytes a la vez, luego incremente la página después de cada fragmento.

Como referencia, las especificaciones SSD1306.

http://www.buydisplay.com/download/ic/SSD1306.pdf

En particular, busque la documentación bajo el comando "Establecer modo de direccionamiento", tiene muchas imágenes para aclarar qué está sucediendo exactamente.

Bueno, tuve el mismo problema y encontré una respuesta. Todo lo que tienes que cambiar es

esta línea: oled_write(0, 0x3F); a esto: oled_write(0, 0x1F);

y esta línea: oled_write(0, 0x12); a esta línea: oled_write(0, 0x02);

Su código anterior funciona para las pantallas OLED de 128x64. Los cambios en el código hacen que funcione para pantallas OLED de 128x32.