Scan the I2C bus first. If the OLED shows up at 0x3C or 0x3D, use that address, and call display() after drawing.
What the message means
The display needs the right address and the right size in the library. Drawing commands only go to a memory buffer until you send it to the screen.
Fix it in this order
- Run an I2C scanner sketch and note the address that appears.
- Use that address in begin(), usually 0x3C and sometimes 0x3D.
- Set the width and height in the library to 128×64 or 128×32 to match your screen.
- Call display.display() after you draw, and clearDisplay() before a new frame.
- Check SDA and SCL pins, and that the board is powered.
- Check the free memory, since the buffer takes about a kilobyte.
Why it happens
The library draws into a buffer in the microcontroller’s memory. Nothing appears on the screen until you send that buffer to the display, which is what display() does, so a sketch that draws but never calls it shows a blank screen.
The display also has to be reached on the right I2C address, and the library has to be told the right size. A scanner sketch shows which address replies, so you use the one you have, not the one in an example.
If you see this, do this
| You see | Do this |
|---|---|
| Scanner finds nothing | Wiring, power or pull-ups. |
| Found, screen blank | Address, size or missing display() call. |
Related
address conflict, I2C pull-ups, low memory.
Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.
Why this happens
The SSD1306 controller has no text mode. Your sketch draws shapes and characters into a buffer in the microcontroller’s RAM, and display() sends the whole buffer to the screen over I2C. A 128 by 64 pixel display with one bit per pixel needs 128 x 64 / 8 = 1024 bytes, and a 128 by 32 one needs 512. If the library cannot allocate that much memory, begin() returns false and nothing will ever show.
I2C addresses are the second source of trouble. The usual 7-bit address is 0x3C, sometimes 0x3D, set by a resistor on the module. Some libraries ask for the 8-bit form of the same address, which is 0x78. The scanner’s answer and the library’s expectation have to agree. Also, modules sold as 1.3 inch often use an SH1106 controller instead, which looks similar but needs a different library and shows shifted or garbled output with the SSD1306 one.
How to confirm the cause
- Run an I2C scanner and write down the address it reports. No address means a wiring, power or pull-up problem, not a code problem.
- Print the result of display.begin(). If it returns false, either the address is wrong or the library could not allocate its buffer.
- Measure VCC on the module. 3.3 V or 5 V depending on the module, but not 0 V.
- Check which pins your board uses for SDA and SCL. On an Uno they are A4 and A5, and on many ESP32 boards 21 and 22.
- Compare the picture on the screen with what you drew. A half-height or shifted image points at the wrong screen size or the wrong controller.
Worked example
A minimal sketch that reports failure instead of silently showing nothing:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 not found or no memory"); for (;;) {}
}
display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0); display.println("Hello"); display.display();
}
void loop() {}Common mistakes
- Copying the address from an example without scanning.
- Choosing a 128 by 32 size for a 128 by 64 module, or the reverse.
- Drawing but never calling display().
- Swapping SDA and SCL.
- Putting two devices on the same address on the same bus.
If this did not fix it
- A different controller on the module, such as SH1106, needs another library.
- Missing or weak pull-up resistors on long wires; shorten the cable first.
- A sketch that runs out of RAM leaves too little for the display buffer; check the memory report at compile time.