Problem with SH1106 OLED on ESP32 Lollin32 Lite (U8G2 library)

I have a problem with a 1.3" SH1106 I2C OLED connected to a “Lolin32 Lite V1.0 with ESP32 Rev1” board, using U8G2 library:

When I upload the sketch to the board, everything works as expected, i.e. the display shows the counter and the LED is blinking.
But when I unplug and replug USB, the display looks scrumbled, sometimes, the LED even doesn’t blink.

Same occurs when I connect the LOLIN just to a USB power supply, without any USB communication.

No other device is connected to I2C.
No difference whether I use “Full Buffer” or “Page Buffer”.
Before U8G2, I tried the Adafruit_SH1106 library with the same result.

The same sketch on the “ESP32 Dev Kit C” has no problems.
Also, I can use a 0.9" SSD1306 OLED on both boards without problems.

What do I miss?
Do I need any additional setting for the Lolin32 Lite?

boards:
“AZDelivery LOLIN32 Lite Board V1.0 mit ESP-32 Rev1”
“AZDelivery ESP32 NodeMCU Module WLAN WiFi Dev Kit C Development Board mit CP2102”

display:
“1,3” OLED I2C 128 x 64"

Good display after upload:

Bad display after reconnect:

platform.io-ini:

[env:lolin32_lite]
board = lolin32_lite
platform = espressif32
framework = arduino
monitor_speed = 115200
build_flags = -DCORE_DEBUG_LEVEL=5
lib_deps = 
	adafruit/Adafruit GFX Library@^1.12.0
	olikraus/U8g2@^2.36.5

sketch:

#include <Arduino.h>
#include <common.h>

#define ESP32_LOLIN

//#define DISPLAY_SH1106
//#define TEST_I2C
#define TEST_U8G2
#define U8G2_FULL
//#define U8G2_PAGE

#ifdef TEST_I2C
#include <Wire.h>
#endif

#ifdef TEST_U8G2
#include <Wire.h>
#include <U8g2lib.h>
#endif

#ifdef DISPLAY_SSD1306
#endif

#ifdef ESP32_LOLIN
  // Lolin32 Lite
  #define PIN_SDA (0)
  #define PIN_SCL (4)
  #define OUT_LED (25)
#else
  // ESP32
  #define PIN_SDA (21)
  #define PIN_SCL (22)
  #define OUT_LED (12)
#endif

// SH1106 Display -----------------------------------------------
#ifdef DISPLAY_SH1106
  #include "main_display.h"
#endif

#ifdef TEST_U8G2
  // SSD1306
  // U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

  // SH1106
  #ifdef U8G2_FULL
    U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
  #endif

  #ifdef U8G2_PAGE
    U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
  #endif
#endif


// Main ---------------------------------------------------------

#ifdef TEST_U8G2
  void setup_u8g2() {
    Wire.begin(PIN_SDA, PIN_SCL);
    detect_i2c();
    u8g2.begin();
  }
#endif

void setup() {
  Serial.begin(115200);
	while (!Serial)
	{
		; // wait for serial port to connect. Needed for native USB
	}

	Serial.println(F(""));
	Serial.println(F("-----------------------"));
	Serial.println(F("------ ESP32 Test -----"));
	Serial.println(F("-----------------------"));
	Serial.println(S("Build Date: ") + __DATE__);
	Serial.println(S("Build Time: ") + __TIME__);
	Serial.println(F("-----------------------"));
	Serial.println(F(""));
  pinMode(OUT_LED, OUTPUT);

#ifdef TEST_I2C
  Wire.begin(PIN_SDA, PIN_SCL);
  detect_i2c();
#endif

#ifdef DISPLAY_SH1106
  setup_sh1106();
#endif

#ifdef TEST_U8G2
  setup_u8g2();
#endif
}

#ifdef TEST_U8G2
  void loop_u8g2_full(int value) {
    static char outText[20] = {0};
    u8g2.clearBuffer();					// clear the internal memory
    u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
    u8g2.drawStr(0,10,"Full Buffer");	// write something to the internal memory
    snprintf(outText, sizeof(outText), "count %d", value);
    u8g2.drawStr(0,30, outText);
    u8g2.sendBuffer();					// transfer internal memory to the display
  }

  void loop_u8g2_page(int value) {
    static char outText[20] = {0};
    u8g2.firstPage();
    do {
      u8g2.setFont(u8g2_font_ncenB10_tr);
      u8g2.drawStr(0,20,"Page Buffer");
      snprintf(outText, sizeof(outText), "count %d", value);
      u8g2.drawStr(0,40, outText);
    } while ( u8g2.nextPage() );
  }
#endif

void loop() {
  static unsigned long timestamp = 0;
  static bool state = 0;
  static int count = 0;

  if ((millis() - timestamp) > 1000)
  {
    count++;
    Serial.println(count);
    digitalWrite(OUT_LED, state);
    state = 1 - state;
    timestamp = millis();
    
    #ifdef TEST_U8G2
      #ifdef U8G2_FULL
      loop_u8g2_full(count);
      #endif

      #ifdef U8G2_PAGE
      loop_u8g2_page(count);
      #endif

    #endif

    #ifdef DISPLAY_SH1106
    loop_1106();
    #endif

  }
}


No resistor on the LED?

Anyway, this might be some sort of power stabilization problem. Does the same happen when you

  1. Unplug the USB cable
  2. Hold down the RST button on the Lolin board
  3. Plug the USB cable in
  4. Release the RST button?

Thanks for your reply.

No worries, the LED has a built-in resistor

Yes

Same with delay(3000); as the first line in setup()?

Still the same problem

Is anyone successfully using a “Lolin32 Lite” together with an OLED SH1106 I2C ?

I found a solution:

With the HW constructors of SH1106, I get the described problem. With the SW constructors, the problem does not occur.

Does not work:

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

Works:

U8G2_SH1106_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, PIN_SCL, PIN_SDA, /* reset=*/ U8X8_PIN_NONE);

With the SW constructors, the display is significantly slower, so I don’t know whether I finally want to use that, but for now, I can go ahead.

Axel