SSD1306 OLED from Adafruit - what is the I2C secret?
Erlend
Posts: 612
The nice little 128x64 monochrome oled display is a hard nut to crack. I have trawled github, obex, and internet in general, and finally I got it, or so I thought. It doesn't behave the <register> <data> way I am used to with I2C, but instead wants <cmd|data flag><command or data>[<more data>]. So, the first byte decides how the next one(s) are treated. I put together some code which sent all the initialisation commands to the display, and hey - it lit up showing random bits all over.
Next step should be easy: send a bunch of bytes into the graphical RAM area. Not so.
When the first I2C byte is $80 (or$00) the next byte is handled as a command by the SSD. When the first byte is $40, the next bytes should be handled as data going into the SSD graphical RAM, with auto-increment of address after each byte. Bit6 in this first byte determines this. Then there is the bit7 of this byte, which is a 'continuation' flag, but the description in the datasheet leaves it's function a mystery.
I have tried all variants of bit settings, but the SSD refuses to transfer data to RAM; the display stubbernly continue to show just random bits.
The first part of this code works fine - it sends a command to invert the display. The nest part of the code should result in the first line of the display showing a bar, but nothing happens.
The data sheet http://sabernetics.com/wp-content/uploads/2012/03/SSD1306-V1.2.pdf is written in english, yes, but in a very 'opaque' style, making it difficult to understand the functionallity.
I am hoping for the Forum, but otherwise I will give up, rewire for SPI, and just use ready-made code from Obex. Giving up is not fun.
Erlend
Next step should be easy: send a bunch of bytes into the graphical RAM area. Not so.
When the first I2C byte is $80 (or$00) the next byte is handled as a command by the SSD. When the first byte is $40, the next bytes should be handled as data going into the SSD graphical RAM, with auto-increment of address after each byte. Bit6 in this first byte determines this. Then there is the bit7 of this byte, which is a 'continuation' flag, but the description in the datasheet leaves it's function a mystery.
I have tried all variants of bit settings, but the SSD refuses to transfer data to RAM; the display stubbernly continue to show just random bits.
'(prior to this a bunch of initialization code is sent, see bottom page code) bus.CallChip(ChipAddr << 1) bus.WriteBus($00) 'also works with $80 bus.WriteBus(SSD1306_INVERTDISPLAY) bus.Stop bus.CallChip(ChipAddr << 1) bus.WriteBus($40) 'have tried with $C0 too repeat 127 bus.WriteBus($FF) bus.Stop
The first part of this code works fine - it sends a command to invert the display. The nest part of the code should result in the first line of the display showing a bar, but nothing happens.
The data sheet http://sabernetics.com/wp-content/uploads/2012/03/SSD1306-V1.2.pdf is written in english, yes, but in a very 'opaque' style, making it difficult to understand the functionallity.
I am hoping for the Forum, but otherwise I will give up, rewire for SPI, and just use ready-made code from Obex. Giving up is not fun.
Erlend
bus.WriteByteDirect(ChipAddr, $00, SSD1306_DISPLAYOFF) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETLOWCOLUMN) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETHIGHCOLUMN) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETSTARTLINE) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETCONTRAST) bus.WriteByteDirect(ChipAddr, $00, $CF) bus.WriteByteDirect(ChipAddr, $00, $A1) bus.WriteByteDirect(ChipAddr, $00, SSD1306_NORMALDISPLAY) bus.WriteByteDirect(ChipAddr, $00, SSD1306_DISPLAYALLON_RESUME) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETMULTIPLEX) bus.WriteByteDirect(ChipAddr, $00, $3F) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETDISPLAYOFFSET) bus.WriteByteDirect(ChipAddr, $00, $0) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETDISPLAYCLOCKDIV) bus.WriteByteDirect(ChipAddr, $00, $80) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETPRECHARGE) bus.WriteByteDirect(ChipAddr, $00, $F1) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETVCOMDETECT) bus.WriteByteDirect(ChipAddr, $00, $40) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SETCOMPINS) bus.WriteByteDirect(ChipAddr, $00, $12) bus.WriteByteDirect(ChipAddr, $00, SSD1306_MEMORYMODE) bus.WriteByteDirect(ChipAddr, $00, $00) bus.WriteByteDirect(ChipAddr, $00, SSD1306_SEGREMAP | $1) bus.WriteByteDirect(ChipAddr, $00, SSD1306_COMSCANDEC) bus.WriteByteDirect(ChipAddr, $00, SSD1306_CHARGEPUMP) bus.WriteByteDirect(ChipAddr, $00, $14)
Comments
http://obex.parallax.com/object/725
Have you found out what the Co - continuation bit actually is for? The explanation in the datasheet is hard to dechiffer.
Erlend
Is the reset sequence critical?
Maybe this particular display is finicky on timing, maybe something else. I only have one.
Erlend