What You See
You wired up a small OLED display (usually 0.96" or 1.3", either 128x64 or 128x32 pixels) and uploaded code that should show text or graphics. The display is completely dark. Not even a flicker.
Or the display was working in a previous project and now it will not turn on with your new code.
OLED displays are more complicated to set up than LEDs or buttons because they use a communication protocol (usually I2C) and require a library with specific configuration. There are several places where things can go wrong.
Most Likely Causes
1. Wrong I2C Address
I2C devices have an address, a number that identifies them on the bus. Most small OLED displays use address 0x3C, but some use 0x3D. If your code is set to one address but the display uses the other, the display will never receive the data.
Fix: Run an I2C scanner sketch (provided below) to find out what address your display is actually using. Then update your code to match.
If you are using the U8g2 library, the address is usually set in the constructor or by using the right constructor variant. If you are using Adafruit SSD1306, the address is passed to display.begin():
// Adafruit SSD1306
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Try 0x3D if 0x3C does not work
For U8g2, some constructors let you specify the address. Others auto-detect it. Check the U8g2 documentation for your specific constructor.
2. SDA and SCL Wires Swapped
I2C uses two wires: SDA (data) and SCL (clock). On the Arduino Uno, SDA is pin A4 and SCL is pin A5. If you swap these two, communication fails completely and the display stays dark.
Fix: Check your wiring:
- SDA goes to A4 (on Uno)
- SCL goes to A5 (on Uno)
Some boards have dedicated SDA/SCL pins near the USB port, labeled on the board. Those are the same as A4/A5 on the Uno.
3. Missing Wire.h or Wrong Library
If you are using I2C but forgot to include the Wire library, the I2C hardware is never initialized.
Fix: Make sure your sketch includes:
#include <Wire.h>
Most OLED libraries include Wire.h internally, but it is good practice to include it explicitly.
Also check that you have the correct display library installed:
- U8g2: Install "U8g2" from the Library Manager. This is the most versatile library.
- Adafruit SSD1306: Install both "Adafruit SSD1306" and "Adafruit GFX Library."
4. Wrong Constructor (U8g2)
U8g2 has dozens of constructors for different display types, resolutions, and communication methods. Using the wrong one means the library sends commands the display does not understand.
Common constructors for 128x64 SSD1306 I2C OLEDs:
// Full buffer mode (uses more RAM but faster)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Page buffer mode (uses less RAM)
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
For 128x32 displays:
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
Fix: Make sure your constructor matches your display's resolution (128x64 vs 128x32) and chip (SSD1306 vs SH1106). If you are not sure, try SSD1306 first since it is the most common.
5. Forgot to Call begin() or sendBuffer()
With U8g2, you must call u8g2.begin() in setup(). If you skip this, nothing works.
With U8g2 in full-buffer mode, you also need to call u8g2.sendBuffer() after drawing. Without it, your drawing commands fill a buffer in memory but never actually send the data to the display.
Fix:
void setup() {
u8g2.begin(); // REQUIRED
}
void loop() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 20, "Hello World");
u8g2.sendBuffer(); // REQUIRED in full-buffer mode
}
6. Power Issue
OLED displays typically run on 3.3V or 5V (check your module). Most breakout boards have a voltage regulator and work fine on 5V from the Arduino. But if you are powering multiple components, you might not have enough current.
Fix: Make sure VCC on the display goes to the Arduino's 5V or 3.3V pin (check your module), and GND goes to GND. Try disconnecting other components temporarily to see if the display works on its own.
7. Bad Solder Joints on the Display Module
Many OLED modules come with unsoldered header pins. If you soldered the pins yourself and one joint is cold (looks dull and blobby instead of shiny and cone-shaped), that connection might be intermittent or completely open.
Fix: Inspect the solder joints under good light. Reheat any joints that look dull, blobby, or have visible gaps. Apply a tiny bit more solder if needed.
8. Display Has SH1106 Chip Instead of SSD1306
Some 1.3" OLED displays use the SH1106 driver chip instead of SSD1306, even though they look identical. Code written for SSD1306 will not work on SH1106.
Symptom: The display stays black, or you see a garbled/shifted image.
Fix: In U8g2, change your constructor to the SH1106 variant:
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
Test Code: I2C Address Scanner
Upload this first. It scans every possible I2C address and tells you what devices it finds.
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
delay(200);
Serial.println("I2C Scanner - looking for devices...");
}
void loop() {
int deviceCount = 0;
for (byte address = 1; address < 127; address++) {
Wire.beginTransmission(address);
byte error = Wire.endTransmission();
if (error == 0) {
Serial.print("Device found at address 0x");
if (address < 16) Serial.print("0");
Serial.println(address, HEX);
deviceCount++;
}
}
if (deviceCount == 0) {
Serial.println("No I2C devices found! Check SDA/SCL wiring.");
} else {
Serial.print("Found ");
Serial.print(deviceCount);
Serial.println(" device(s).");
}
Serial.println("---");
delay(3000);
}
Open the Serial Monitor at 9600 baud. You should see something like:
Device found at address 0x3C
Found 1 device(s).
If it says "No I2C devices found," your wiring is wrong (SDA/SCL swapped, loose connection, or no power to the display).
Test Code: OLED Hello World (U8g2)
Once the I2C scanner finds your display, use this to confirm the display works:
#include <U8g2lib.h>
#include <Wire.h>
// Change this constructor if your display is different
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
void setup() {
u8g2.begin();
Serial.begin(9600);
Serial.println("OLED test starting...");
}
void loop() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 15, "Hello World!");
u8g2.drawStr(0, 35, "OLED is working.");
u8g2.drawStr(0, 55, "You got this.");
u8g2.sendBuffer();
delay(1000);
}