Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

SSD1306 OLED with Arduino Uno — I2C wiring and the 2 KB RAM catch

Wire a 0.96" SSD1306 I2C OLED to an Arduino Uno R3 (SDA/SCL, 5 V), auto-detect 0x3C/0x3D and draw text without running out of RAM.

Arduino C++Verified — core avr 1.8.8, Adafruit SSD1306 2.5.17, 3 Nov 2026Compile-only

Community draft — report a mistake

The 0.96-inch SSD1306 OLED is the most popular small display for Arduino projects: 128×64 pixels, readable indoors and out, and only four wires over I2C.

On the Uno the wiring is simple — the module runs from 5 V and its I2C lines go to SDA/SCL (the same signals as A4/A5). The real limit is memory. Adafruit’s driver keeps a full copy of the screen in RAM, and that is 1 KB of the Uno’s 2 KB. The sketch below fits easily, but every library and string you add eats into what is left.

The sketch checks whether the module answers at 0x3C or 0x3D, shows uptime in large text and a live analog reading from A0, and redraws once a second.

Wiring

Arduino Uno R3Only the pins used are shown · 5 V logicSSD1306 OLED 0.96″ (128×64, I2C)5VGNDSDA · 18SCL · 19GNDVCCSCLSDA
Every connection
Arduino Uno R3SSD1306 OLED 0.96″ (128×64, I2C)WireNotes
GNDGNDblackCheck the silkscreen — some clones put VCC first. Reversing them kills the module.
5VVCCredThe module’s regulator accepts 5 V, and its pull-ups then sit at 5 V — right for the Uno.
SCLSCLyellowSame signal as A5
SDASDAblueSame signal as A4

3.3–5 V (on-board regulator) part, 5 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

  • The Adafruit library allocates a 1024-byte frame buffer with malloc() when begin() runs. The compiler’s RAM figure doesn’t include it, so a sketch that “uses 60 % of dynamic memory” can still fail with “allocation failed”.
  • Keep every fixed string in flash with F("…"). On the Uno, plain strings are copied into RAM at start-up.
  • The SDA/SCL pins next to AREF are the same signals as A4/A5. Once the OLED is on, A4 and A5 can’t be used as analog inputs.
  • GFX text and the driver take a big share of the Uno’s 32 KB flash. If you add a sensor library and run short, see sketch too big or use the page-buffered U8g2 driver.

Code

ssd1306-uno.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// 0.96" SSD1306 I2C OLED (128x64) on an Arduino Uno R3.
// GND → GND, VCC → 5V, SCL → SCL (A5), SDA → SDA (A4).
// The display buffer needs 1 KB of the Uno's 2 KB RAM, allocated at run time,
// so keep every fixed string in flash with F().
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(128, 64, &Wire, -1);  // -1: no reset pin on 4-pin modules

void setup() {
  Serial.begin(9600);
  uint8_t addr = 0x3C;
  Wire.begin();
  Wire.beginTransmission(0x3C);
  if (Wire.endTransmission() != 0) addr = 0x3D;  // some modules answer at 0x3D
  if (!display.begin(SSD1306_SWITCHCAPVCC, addr)) {
    Serial.println(F("SSD1306 allocation failed - not enough free RAM"));
    for (;;) {}
  }
  Serial.print(F("OLED ready at 0x"));
  Serial.println(addr, HEX);
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  unsigned long s = millis() / 1000;
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println(F("Arduino Uno + OLED"));
  display.drawLine(0, 10, 127, 10, SSD1306_WHITE);
  display.setTextSize(2);
  display.setCursor(0, 20);
  display.print(F("Up "));
  display.print(s);
  display.println(F("s"));
  display.setTextSize(1);
  display.setCursor(0, 48);
  display.print(F("A0 = "));
  display.print(analogRead(A0));
  display.display();
  Serial.print(F("Uptime "));
  Serial.println(s);
  delay(1000);
}

Library: Adafruit SSD1306 (Adafruit (also install Adafruit GFX Library)) — compiled with Adafruit SSD1306 2.5.17.

Expected serial output

Serial Monitor · 9600Output
OLED ready at 0x3C
Uptime 0
Uptime 1
Uptime 2

Common errors

“SSD1306 allocation failed”

Less than about 1.1 KB of RAM is free when begin() runs. Move strings into F(), shrink arrays, or use a 128×32 display (512-byte buffer). Details in SSD1306 allocation failed.

Serial says ready but the screen is black or shows a shifted, noisy image

Wrong controller: most 1.3" modules are SH1106, not SSD1306. Use the SH1106 guide instead.

Nothing at either address

SDA and SCL swapped, or VCC/GND reversed. Run the I2C scanner.

↑↓ to move · Enter to open