OLED 128 x 32 SSD1306 display problem (picture inside)

I bought one of these cheap 0.91" OLED displays and hooked it up according to a datasheet that was sent to me by the seller. I tried several drivers for it after I thought there are compatibility problems, but all of them give the same problem. Only the top of the display shows any characters, the rest seems like random pixels and it flickers while lines are running up and down on it. VBAT + VDD are connected to ~3.3V.

Perhaps someone can spot the issue just by looking at the display picture?

Here is the initiation sequence:

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
}


And what the LCD shows after I sent some characters to it.

• Looks like some kind of RAM buffer overflow in your code. – jippie Apr 25 '14 at 5:34
• What is the host platform? – Zuofu Apr 25 '14 at 5:54
• @Zuofu - ATmega128A – user34920 Apr 25 '14 at 6:00
• Hmm, the ATmega128A only has 4KBytes of memory, exactly the size you need for a frame buffer assuming monochrome 8 bpp (128 * 32). However, that is assuming there is absolutely no overhead - which is never true if you are using a compiler (stack space, etc..) How are you drawing the characters? – Zuofu Apr 25 '14 at 7:02
• Please also describe what you thought you were writing to the screen (some message, or ???), and also show a much better resolution picture (of just the display) for comparison. – gwideman Apr 25 '14 at 10:59

Taking a guess in lieu of more information (see my comments above). It does look suspiciously like what is drawn is 1/8th of the screen. The controller says that it operates at 8 bits per pixel (256 monochrome levels). Are you drawing into the screen as if it was a 1 bit per pixel screen instead of 8? As I noted in the comment above, you will not be able to hold a frame buffer at 8 bpp and still have any RAM left to do anything else.

• It seems that the driver for the display defined a frame buffer which is just as big as the RAM I have on the device... I'm moving to an ATmega328. Thanks! – user34920 Apr 25 '14 at 19:27
• Cool, but the ATmega328 has even less SRAM (2KB). The issue is not flash memory (or program memory) it is SRAM. There are some MegaAVR controllers which have 8KB, which should be enough for this application: atmel.com/Images/8491E_MegaAVR_E_US_110112_LoRes.pdf – Zuofu Apr 25 '14 at 21:20

Responding in case anyone actually needs the issue solved,

If you aren't familiar with the SSD1306, it would be a good idea to read the documentation.

Each byte is vertical, with the LSB at the top and the MSB at the bottom. The screen is separated into several pages, each of which stores 1 byte by N columns. For a 128 by 32 pixel screen, that's 4 pages tall (8*4=32) and 128 columns wide. This can all be remapped, but if you follow the guides from the manufacturer, the default setup is the way I am describing.

When you write a data byte, by any method, it will increment the column pointer by one. So, if you set the column and page to zero, you are at the top left of the screen. If you write 10 bytes all 0xff, you would have a 10x8 pixel square at the top left of the screen. If you keep going, and write 128, the entire top page would be filled.

However, if you set the address mode incorrectly, it will not auto-increment the page. So, you might have a full buffer (which is only 512 bytes), but you are only writing the first 128 of those bytes, after which i don't know what will happen. It looks like it goes off the page, rather than re-writing over it.

So, tl;dr, change the address mode to horizontal so that it auto-increments the page. Alternatively, write 128 bytes at a time, then increment the page after each chunk.

For reference, the SSD1306 specs.