The 1.3″ SH1106 OLED is the bigger, easier-to-read sibling of the 0.96″ SSD1306, at almost the same price. On the ESP32-C3 SuperMini the only trap is the pins: the core’s default I2C pins are the strapping pins.
The OLED goes on GPIO5 (SDA) and GPIO6 (SCK/SCL) at 3V3, and the sketch starts Wire on those pins before U8g2 takes over. It finds the display at 0x3C or 0x3D and shows the board name, the chip temperature and an uptime clock in large digits.
Wiring
| ESP32-C3 SuperMini | SH1106 OLED 1.3″ (128×64, I2C) | Wire | Notes |
|---|---|---|---|
| 3V3 | VDD | red | Check the silk-screen: many 1.3″ boards put VDD first and GND second. |
| GND | GND | black | |
| 6 | SCK | yellow | I2C clock — printed SCK or SCL depending on the seller. |
| 5 | SDA | blue |
3.3–5 V (on-board regulator) part, 3.3 V board. Most modules have a regulator and pull-ups to VDD. On ESP32 and Pico power the OLED from 3.3 V so SDA/SCK stay at 3.3 V; on Uno 5 V is fine.
Board quirks
- The C3 core’s default I2C pins are GPIO8 and GPIO9 — both strapping pins, with the LED on 8 and the BOOT button on 9. An OLED’s pull-ups there can stop the board booting. Call
Wire.begin(5, 6)beforeoled.begin(), as the sketch does. - SH1106, not SSD1306. 1.3″ modules almost always carry an SH1106; SSD1306 code shows a strip of noise down one side because the SH1106 has 132 columns. U8g2’s
SH1106_128X64_NONAMEhandles the offset. - Power from 3V3: the module’s pull-ups go to its VDD, so the bus stays at the C3’s 3.3 V level. The SuperMini’s small regulator handles the OLED’s ~20 mA easily.
- The
_F_(full buffer) mode needs 1 KB of RAM — nothing on a C3. On an Uno you would pick the page mode (_1_/_2_) to save memory. - The sketch shows
temperatureRead(), the C3’s internal chip sensor. It reads the die, which runs well above room temperature.
Code
// 1.3" SH1106 128x64 I2C OLED on an ESP32-C3 SuperMini with U8g2.
// VDD → 3V3, GND → GND, SCK → 6 (I2C SCL), SDA → 5. Not on GPIO8/9: those are strapping pins
// (the LED sits on 8, the BOOT button on 9) even though the core uses them as default I2C.
#include <Wire.h>
#include <U8g2lib.h>
constexpr uint8_t SDA_PIN = 5, SCL_PIN = 6;
// "NONAME" covers the common 1.3" modules; the full-buffer (_F_) mode uses 1 KB of the C3's 400 KB RAM.
U8G2_SH1106_128X64_NONAME_F_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN); // before oled.begin(), so U8g2 uses these pins
Wire.beginTransmission(0x3C);
bool at3C = Wire.endTransmission() == 0;
if (!at3C) oled.setI2CAddress(0x3D * 2); // U8g2 takes the 8-bit address
oled.setBusClock(400000);
oled.begin();
Serial.printf("SH1106 at 0x%02X on SDA 5 / SCL 6\n", at3C ? 0x3C : 0x3D);
}
void loop() {
uint32_t s = millis() / 1000;
float chipC = temperatureRead(); // the C3's internal sensor: chip temperature, not room temperature
char line[24];
oled.clearBuffer();
oled.setFont(u8g2_font_6x12_tr);
oled.drawStr(0, 12, "ESP32-C3 SuperMini");
snprintf(line, sizeof line, "Chip %.1f C", chipC);
oled.drawStr(0, 26, line);
oled.setFont(u8g2_font_logisoso22_tn);
snprintf(line, sizeof line, "%02lu:%02lu:%02lu", s / 3600, (s / 60) % 60, s % 60);
oled.drawStr(0, 60, line);
oled.sendBuffer();
Serial.printf("Uptime %s chip %.1f C\n", line, chipC);
delay(1000);
}// 1.3" SH1106 128x64 I2C OLED on an ESP32-C3 SuperMini with U8g2.
// VDD → 3V3, GND → GND, SCK → 6 (I2C SCL), SDA → 5. Not on GPIO8/9: those are strapping pins
// (the LED sits on 8, the BOOT button on 9) even though the core uses them as default I2C.
#include <Wire.h>
#include <U8g2lib.h>
constexpr uint8_t SDA_PIN = 5, SCL_PIN = 6;
// "NONAME" covers the common 1.3" modules; the full-buffer (_F_) mode uses 1 KB of the C3's 400 KB RAM.
U8G2_SH1106_128X64_NONAME_F_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN); // before oled.begin(), so U8g2 uses these pins
Wire.beginTransmission(0x3C);
bool at3C = Wire.endTransmission() == 0;
if (!at3C) oled.setI2CAddress(0x3D * 2); // U8g2 takes the 8-bit address
oled.setBusClock(400000);
oled.begin();
Serial.printf("SH1106 at 0x%02X on SDA 5 / SCL 6\n", at3C ? 0x3C : 0x3D);
}
void loop() {
uint32_t s = millis() / 1000;
float chipC = temperatureRead(); // the C3's internal sensor: chip temperature, not room temperature
char line[24];
oled.clearBuffer();
oled.setFont(u8g2_font_6x12_tr);
oled.drawStr(0, 12, "ESP32-C3 SuperMini");
snprintf(line, sizeof line, "Chip %.1f C", chipC);
oled.drawStr(0, 26, line);
oled.setFont(u8g2_font_logisoso22_tn);
snprintf(line, sizeof line, "%02lu:%02lu:%02lu", s / 3600, (s / 60) % 60, s % 60);
oled.drawStr(0, 60, line);
oled.sendBuffer();
Serial.printf("Uptime %s chip %.1f C\n", line, chipC);
delay(1000);
}Library: U8g2 (oliver) — compiled with U8g2 2.36.19.
Expected serial output
SH1106 at 0x3C on SDA 5 / SCL 6
Uptime 00:00:01 chip 41.2 C
Uptime 00:00:02 chip 41.4 CSH1106 at 0x3C on SDA 5 / SCL 6 Uptime 00:00:01 chip 41.2 C Uptime 00:00:02 chip 41.4 C
Common errors
Board doesn’t boot with the OLED connected
It is wired to GPIO8/9. Move SDA/SCL to GPIO5/6.
Noise stripe down one edge
You are using SSD1306 code. Use the U8g2 SH1106 constructor as in the sketch.
Nothing on screen, sketch prints 0x3D
Nothing answered at 0x3C, so it tried 0x3D. Check VDD/GND order on your board, then run the I2C scanner.