Shop OBEX P1 Docs P2 Docs Learn Events
SSD1306 OLED from Adafruit - what is the I2C secret? — Parallax Forums

SSD1306 OLED from Adafruit - what is the I2C secret?

ErlendErlend Posts: 612
edited 2015-09-19 07:23 in Accessories
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.
'(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

  • MacTuxLin wrote: »
    Yes, I did. It did flash the display (i.e. responded to commands) but it only displays random dots (i.e. did not take in data). So, I rewired for SPI, loaded the demo from Obex, and the display behaves nicely. Beats me.
    Have you found out what the Co - continuation bit actually is for? The explanation in the datasheet is hard to dechiffer.

    Erlend

  • I'm sure you did but just checking, were there pull-ups on your I2C?
  • Sure. 4k7. The chip responds fine to address calls, and execute commands as well. Just not data.
    Is the reset sequence critical?
  • Not sure if your problem was like mine. The reset is important
    PRI OLED_Reset
      OUTA[RST]~~
      Pause(1)
      OUTA[RST]~
      Pause(150)
      OUTA[RST]~~
      Pause(1)
    
  • Thanks for the support. I re-soldered the pads, connected I2C, included the exact RST code, ran again, but still it only takes commands, not data. I give up. I will go forward using the SPI set up, I have plenty of P-pins.
    Maybe this particular display is finicky on timing, maybe something else. I only have one.

    Erlend
Sign In or Register to comment.