Adafruit_SH110x icon indicating copy to clipboard operation
Adafruit_SH110x copied to clipboard

96x96 SH1107 display not centred

Open joveaaron opened this issue 1 year ago • 4 comments

  • Arduino board: ESP32 (not relevant I think)

  • Arduino IDE version (found in Arduino -> About Arduino menu): 2.3.2 (still don't think it's relevant)

  • List the steps to reproduce the problem below (if possible attach a sketch or copy the sketch code in too): DEFAULT SH1107 EXAMPLE WITH WIDTH AND HEIGHT CHANGED TO 96x96 and any other code you try to use.

Hey there, I bought a sh1107 display from aliexpress and it this library didn't work correctly for me at first. I opened "Adafruit_SH1107.cpp" and modified the code in the begin function to pass over these commands to the display:

if (WIDTH == 96 && HEIGHT == 96) {
    static const uint8_t init_96x96[] = {
        SH110X_SETDISPLAYOFFSET, 0x6F, SH110X_SETMULTIPLEX, 0x5F
    };
    if (!oled_commandList(init_96x96, sizeof(init_96x96))) {
      return false;
    }
  }

because the screen was offset and it cut off and I got it to align on the X axis by modifying the SETDISPLAYOFFSET AND SETMULTIPLEX but the Y axis is still unaligned. I have experimented with the commands on the datasheet to see what would happen but I couldn't get it to align on the Y axis. Pictures: Before aligning (unmodified library and 96x96 sketch) WhatsApp Image 2024-06-10 at 19 05 09_fed13a7e After aligning (modified library and 96x96 sketch, garbled data below is whatever was stored in RAM after powerup, seems to be 16 pixels tall) WhatsApp Image 2024-06-10 at 19 05 26_c74b6b7e The display's backside (address is 0x3C not 0x78 lol): WhatsApp Image 2024-06-10 at 19 08 28_3724246b WhatsApp Image 2024-06-10 at 19 08 49_e9b02eab

joveaaron avatar Jun 10 '24 17:06 joveaaron

Is there any way to centre the Y axis? I couldn't find a way by myself

joveaaron avatar Jun 10 '24 17:06 joveaaron

For the moment I can only think of increasing the Y size and implementing a virtual offset but I wish this gets fixed :)

joveaaron avatar Jun 10 '24 17:06 joveaaron

Did you manage to find a fix? my x-coordinate 0 is in the wrong place, about 34 pixels to the left

nplata24s avatar May 28 '25 16:05 nplata24s

@nplata24s I kinda fixed it, but you have to modify the Adafruit_SH1107.cpp file in your local library (mine is in Documents\Arduino\libraries\Adafruit_SH110X), specifically the bool Adafruit_SH1107::begin(uint8_t addr, bool reset) function at line 135. In comments I have marked the code I've written, so you can see what you have to alter. On the if statement if (WIDTH == 96 && HEIGHT == 96 + 16), the "+ 16" is the virtual offset for my display. That is how many pixels to the right have to be added to y = 0 to make it actually display. Other than that it's just fiddling around with the SH110X_SETDISPLAYOFFSET, 0x6F and SH110X_SETMULTIPLEX, 0x5F values until you get something that fills up the entire screen correctly. Then DON'T FORGET to set your resolution to, in my case 96, 96 + YOFFSET (which is 16 in my case), or in the X axis, like you're having trouble with. It's just fiddling around with the values. I don't know if the fact that my SETDISPLAYOFFSET and SETMULTIPLEX end in F mean yours has to end in F too, but you should definitely try inbetween values.

Here is my edited function:

bool Adafruit_SH1107::begin(uint8_t addr, bool reset) {

  Adafruit_GrayOLED::_init(addr, reset);

  setContrast(0x2F);

#ifndef SH110X_NO_SPLASH
  // the featherwing with 128x64 oled is 'rotated' so to make the splash right,
  // rotate!
  if (WIDTH == 64 && HEIGHT == 128) {
    setRotation(1);
    drawBitmap((HEIGHT - splash2_width) / 2, (WIDTH - splash2_height) / 2,
               splash2_data, splash2_width, splash2_height, 1);
    setRotation(0);
  }
  if (WIDTH == 128 && HEIGHT == 128) {
    drawBitmap((HEIGHT - splash2_width) / 2, (WIDTH - splash2_height) / 2,
               splash2_data, splash2_width, splash2_height, 1);
  }
#endif

  // Init sequence, make sure its under 32 bytes, or split into multiples!
  // clang-format off
  static const uint8_t init[] = {
      SH110X_DISPLAYOFF,               // 0xAE
      SH110X_SETDISPLAYCLOCKDIV, 0x51, // 0xd5, 0x51,
      SH110X_MEMORYMODE,               // 0x20
      SH110X_SETCONTRAST, 0x4F,        // 0x81, 0x4F
      SH110X_DCDC, 0x8A,               // 0xAD, 0x8A
      SH110X_SEGREMAP,                 // 0xA0
      SH110X_COMSCANINC,               // 0xC0
      SH110X_SETDISPSTARTLINE, 0x0,    // 0xDC 0x00
      SH110X_SETDISPLAYOFFSET, 0x60,   // 0xd3, 0x60,
      SH110X_SETPRECHARGE, 0x22,       // 0xd9, 0x22,
      SH110X_SETVCOMDETECT, 0x35,      // 0xdb, 0x35,
      SH110X_SETMULTIPLEX, 0x3F,       // 0xa8, 0x3f,
      // SH110X_SETPAGEADDR,                  // 0xb0
      // SH110X_SETCOMPINS, 0x12,             // 0xda, 0x12,
      SH110X_DISPLAYALLON_RESUME, // 0xa4
      SH110X_NORMALDISPLAY,       // 0xa6
  };
  // clang-format on

  if (!oled_commandList(init, sizeof(init))) {
    return false;
  }

  if (WIDTH == 128 && HEIGHT == 128) {
    static const uint8_t init_128x128[] = {
        SH110X_SETDISPLAYOFFSET, 0x00, SH110X_SETMULTIPLEX, 0x7F, // 0xa8, 0x3f,
    };
    if (!oled_commandList(init_128x128, sizeof(init_128x128))) {
      return false;
    }
  }

  //MY CODE STARTS HERE
  if (WIDTH == 96 && HEIGHT == 96 + 16) {
      static const uint8_t init_96x96[] = {
          SH110X_SETDISPLAYOFFSET, 0x6F, SH110X_SETMULTIPLEX, 0x5F
      };
      if (!oled_commandList(init_96x96, sizeof(init_96x96))) {
          return false;
      }
  }
  //MY CODE ENDS HERE

  delay(100);                     // 100ms delay recommended
  oled_command(SH110X_DISPLAYON); // 0xaf

  return true; // Success
}

joveaaron avatar May 29 '25 21:05 joveaaron