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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\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.