Part

OLED display, 128x64

The small OLED over I2C at 0x3C. Two wires plus power.

or see every part
  • 4 pins
  • 1 property
Drawn live by the editor's own code, at the size you see it.
Reference

Every one of its 4 pins

Pin
What it does
GND
Ground.
VCC
Supply.
SCL
Open-drain clock.
SDA
Open-drain data.
This part

What it does

The 0.96 inch SSD1306 OLED is a 128 by 64 pixel monochrome display on two I2C wires. Unlike a character LCD it has no font of its own: the board draws every pixel into a 1 KB copy of the screen in its own memory and sends the parts that changed, which on an Uno is half of all the RAM there is. Mokxi’s part is an I2C device decoded from the pin edges, with the command set the common libraries actually send, its own display memory, and the internal charge pump that has to be started before the glass lights, which is one of the two commonest reasons a real one stays black. The address is 0x3C by default and 0x3D as a property. Hardware scrolling is accepted and ignored, and contrast comes through in sixteen steps rather than 256. The Adafruit SSD1306 and GFX calls compile on every board except the ATtiny85.

How to use it

How to use an SSD1306 OLED with an Arduino

Four wires: SDA to A4, SCL to A5, VCC to 5 V and GND to GND. Most modules answer at 0x3C. Draw with the Adafruit SSD1306 and GFX calls, which compile here as they stand, and remember that nothing reaches the glass until display() sends the frame.

The frame is a 1 KB copy of the screen in the board’s own memory, half of an Uno’s RAM, so a big sketch with an OLED is the first one to run out.

Part pin
Board pin
SDA
A4
SCL
A5
VCC
5 V
GND
GND

The same calls work on every board here except the ATtiny85, and there is a built-in ESP32 version of this demo.

Arduino Uno: SSD1306 OLEDlive0.000 s 0.00x
Click to open it in the editor
This is the simulator itself, running here. Click anything to open it in the editor.
Text on the OLED with the Adafruit calls
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(128, 64, &Wire, -1);

void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) for (;;);
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Hello");
  display.display();
}

void loop() {}
Reference

The one property you can set

Property
Default
What it means
address
60
the I2C address, 0x3C by default (the alternate 0x3D also works).
How it is modeled

What is true about the OLED display, 128x64, here

What is modeled

The part models the command set the common libraries actually send (display on and off, addressing mode, column and page windows, inverse, entire-display-on, contrast, segment remap and COM scan direction) in all three addressing modes, so a driver written against a real panel works here unchanged. A 128x64 monochrome frame is 1024 bytes; on an Uno, sending all of it over the bit-banged bus takes a third of a second, which is why the firmware library sends only the 8-column blocks of each page that actually changed.

Not modeled

It never stretches the clock. A real SSD1306 can hold SCL low to make the master wait; this one acknowledges every byte immediately and always. A driver that relies on clock stretching works here and might not on the bench, and, the other way around, a master that ignores stretching passes here and would corrupt a real panel.

The bus has no errors in it. The slave acknowledges its own address and every byte sent to it, and answers nothing else at all: there is no read transfer, no NACK, no arbitration, no bus timeout and no way to make it fail. Nothing checks the clock rate either, so a bit-banged bus at any speed works.

The charge pump is modeled. A module has one supply pin and the 7.5 V the panel needs comes from a pump inside the chip, which powers up off. 0x8D 0x14 starts it and 0x8D 0x10 stops it, and the glass is lit only when the display is on and the pump is running, so a driver that sends 0xAF and forgets 0x8D gets the same dark panel here that it gets on the bench, which is one of the two commonest reasons a real SSD1306 stays black.

Several other commands are taken and thrown away. The multiplex ratio, the display offset, the display clock divide, pre-charge, COM pin configuration, VCOMH deselect and the start line are all accepted and stored and change nothing on the glass. Hardware scrolling (0x26–0x2F) is accepted and ignored, so a scrolling banner stands still.

Contrast (0x81) reaches the canvas as one of sixteen brightness steps rather than as the real panel's 256, and there is no refresh rate, no pixel persistence and no burn-in. Reads from the panel are not modeled at all.

From SSD1306 OLED display, in full.

Projects

See the OLED display, 128x64 in a project

Shown here on: ESP32-C3-DevKitM-1, Arduino Uno R3

Learn

Where it turns up in a lesson

In a learn article

Wire up the OLED display, 128x64

Open the editor and push it into the breadboard. It is free, and it runs on your own machine.