1
\$\begingroup\$

I bought a generic OLED 128x64 display on ebay and had some success in getting it running with the Adafruit SSD1306 library. I ported the initialization function to C and am driving the LCD using the SPI interface. However, when the splash screen appears, there is a horizontal offset.

OLED pinout Horizontal offset in splash screen

I think should be possible to patch this by modifying the display function. However, my question is, is there a cleaner way to do this in the configuration settings for the OLED display. The relevant initialization settings that I am using are given below:

void ssd1306_init(uint8_t vccstate) {

// Init sequence
ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
ssd1306_command(0x80);                                  // the suggested ratio 0x80

ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
ssd1306_command(SSD1306_LCDHEIGHT - 1);

ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
ssd1306_command(0x0);                                   // just changes the horizontal offset
ssd1306_command(SSD1306_SETSTARTLINE | 0x0);            // line #0
ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
if (vccstate == SSD1306_EXTERNALVCC)
{
    ssd1306_command(0x10);
}
else
{
    ssd1306_command(0x14);
}
ssd1306_command(SSD1306_MEMORYMODE);                    // 0x20
ssd1306_command(0x00);                                  // 0x0 act like ks0108
ssd1306_command(SSD1306_SEGREMAP | 0x1);
ssd1306_command(SSD1306_COMSCANDEC);

if( SSD1306_LCDWIDTH == 128 && SSD1306_LCDHEIGHT == 32) {
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command(0x02);
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
    ssd1306_command(0x8F);
}
else if (SSD1306_LCDWIDTH == 128 && SSD1306_LCDHEIGHT == 64) {
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command(0x12);
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
    if (vccstate == SSD1306_EXTERNALVCC)
    {
        ssd1306_command(0x9F);
    }
    else
    {
        ssd1306_command(0xCF);
    }
}
else if (SSD1306_LCDWIDTH == 96 && SSD1306_LCDHEIGHT == 16) {
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command(0x2);   //ada x12
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81
    if (vccstate == SSD1306_EXTERNALVCC)
    {
        ssd1306_command(0x10);
    }
    else
    {
        ssd1306_command(0xAF);
    }
}

ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
if (vccstate == SSD1306_EXTERNALVCC)
{
    ssd1306_command(0x22);
}
else
{
    ssd1306_command(0xF1);
}

ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
ssd1306_command(0x40);
ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6

ssd1306_command(SSD1306_DEACTIVATE_SCROLL);

//Debug
//ssd1306_command( 0x22 ); // Set page start and end addresses
//ssd1306_command( 0x00 ); // start at zero
//ssd1306_command (0x07) ; // end at seven.
//DEBUG


ssd1306_command(SSD1306_DISPLAYON);//--turn on oled panel

}

\$\endgroup\$
0
\$\begingroup\$

Since you write that you have ported the code to C, I assume you are no longer using the original code.

The horizontal offset cannot be configured in the initialization. Instead, it is set as the first step of each frame display.

The original code in the Arduino library is:

void Adafruit_SSD1306::display(void) {
  ssd1306_command(SSD1306_COLUMNADDR);
  ssd1306_command(0);   // Column start address (0 = reset)
  ssd1306_command(SSD1306_LCDWIDTH-1); // Column end address (127 = reset)
  ...

My guess is you have no correctly ported this code to C.

If not, try to fix the column start address line, i.e. use a different value than 0.

\$\endgroup\$
  • \$\begingroup\$ The display function is exactly the same. Thanks for the suggestion of changing the start address. I doesn't work though. \$\endgroup\$ – mr_js Nov 23 '17 at 20:49
  • 1
    \$\begingroup\$ If changing the start address does not work, then either your display is not using the SSD1306 chip or it is accidentally changed again somewhat later. Please show more code. Most likely you haven't shown the relevant code yet. \$\endgroup\$ – Codo Nov 23 '17 at 21:51
0
\$\begingroup\$

Always start with the Data sheet for the device and read https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf

See 8.3 Oscillator Circuit and Display Time Generator

The screen your showing looks to be the wrong resolution or the clock frequency has been set incorrectly. I would say it is in the initialisation that you have a problem, maybe the wrong number entered or you have failed to initialise something as simple as not initialising the divide ratio for the clock. I would recheck you code and make sure everything was initialised correctly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.