A small OLED makes a XIAO project self-contained: show a sensor value, an IP address or battery state without a laptop.
On the XIAO ESP32C3 the default I2C pins are D4 (SDA) and D5 (SCL), both free of boot duties, so the wiring is four wires and Wire.begin() with no arguments.
Wiring
| XIAO ESP32C3 | SSD1306 OLED 0.96″ (128×64, I2C) | Wire | Notes |
|---|---|---|---|
| GND | GND | black | |
| 3V3 | VCC | red | |
| D5 | SCL | yellow | |
| D4 | SDA | blue |
3.3–5 V (on-board regulator) part, 3.3 V board. Most modules have a regulator and run from 3.3 V or 5 V. Their I2C pull-ups go to VCC, so on ESP32 and Pico power the OLED from 3.3 V to keep SDA/SCL at a safe level.
Board quirks
- Unlike a generic C3 board (default I2C on the strapping pins GPIO8/9), the XIAO variant puts I2C on D4/D5 = GPIO6/7, so plain
Wire.begin()is safe here. - Check the pin order printed on your OLED: some start with VCC, some with GND. Swapping them can kill the display.
- Seeed’s XIAO expansion board has the same 0.96″ OLED wired to D4/D5 — this sketch runs on it unchanged.
Code
// SSD1306 128x64 I2C OLED on a Seeed XIAO ESP32C3.
// GND → GND, VCC → 3V3, SDA → D4 (GPIO6), SCL → D5 (GPIO7) — the XIAO's default I2C pins.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
Serial.begin(115200);
delay(1500);
Wire.begin(); // SDA = D4, SCL = D5 on the XIAO variant
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 not found at 0x3C - try 0x3D, and check the GND/VCC order on your module");
while (true) delay(1000);
}
display.setTextColor(SSD1306_WHITE);
Serial.println("OLED ready");
}
void loop() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print("XIAO C3");
display.setTextSize(1);
display.setCursor(0, 28);
display.printf("Uptime: %lu s", millis() / 1000);
display.setCursor(0, 44);
display.printf("Free heap: %u KB", ESP.getFreeHeap() / 1024);
display.display();
delay(1000);
}// SSD1306 128x64 I2C OLED on a Seeed XIAO ESP32C3.
// GND → GND, VCC → 3V3, SDA → D4 (GPIO6), SCL → D5 (GPIO7) — the XIAO's default I2C pins.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
Serial.begin(115200);
delay(1500);
Wire.begin(); // SDA = D4, SCL = D5 on the XIAO variant
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 not found at 0x3C - try 0x3D, and check the GND/VCC order on your module");
while (true) delay(1000);
}
display.setTextColor(SSD1306_WHITE);
Serial.println("OLED ready");
}
void loop() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print("XIAO C3");
display.setTextSize(1);
display.setCursor(0, 28);
display.printf("Uptime: %lu s", millis() / 1000);
display.setCursor(0, 44);
display.printf("Free heap: %u KB", ESP.getFreeHeap() / 1024);
display.display();
delay(1000);
}Library: Adafruit SSD1306 (Adafruit (also install Adafruit GFX Library)) — compiled with Adafruit SSD1306 2.5.17.
Expected serial output
OLED readyOLED ready
Common errors
“SSD1306 not found at 0x3C”
Try 0x3D, then check SDA/SCL. Full fix.
Garbage on the right edge
It is a 1.3″ SH1106 display, not an SSD1306. Use the SH1106 library.