Arduino Uno SSD1306 OLED Simulator: Wiring, Code and a Live Circuit
This is a 0.96 inch SSD1306 OLED, 128 by 64 pixels, wired to an Arduino Uno over I2C and running live: the board writes two lines of text, draws a box and counts the seconds in it. It uses the Adafruit SSD1306 and GFX libraries, exactly as a tutorial would.
Four wires: power, ground, SDA to pin A4 and SCL to pin A5. The Arduino Uno is a 5 V board and the module takes 5 V directly.
- 5 V logic
- Library: Adafruit_SSD1306.h
- I2C address 0x3C
- SDA A4, SCL A5
Wiring the SSD1306 OLED to the Arduino Uno
Every connection in the circuit above, with the board’s own pin names.
| SSD1306 OLED pin | Arduino Uno pin | Why |
|---|---|---|
| VCC | 5V | The module has its own regulator and runs from 3.3 or 5 V. |
| GND | GND | Common ground. |
| SDA | pin A4 | Arduino Uno’s I2C data line, where Wire.begin() puts it. |
| SCL | pin A5 | Arduino Uno’s I2C clock line. |
On an Uno the I2C bus is A4 (SDA) and A5 (SCL). The SDA and SCL pins beside AREF are the same two wires, so either pair works. The display answers at address 0x3C, the address almost every 0.96 inch module ships with.
Pins to leave alone on the Arduino Uno
Pins 0 and 1 are the USB serial port on a real Uno, so anything wired there fights the upload and the serial monitor. Pin 13 carries the onboard LED.
On a real bench
On a real bench the Uno stands beside the breadboard: the SSD1306 OLED goes into the breadboard and male-to-male jumpers run from the Uno’s female headers to its rows. Power the Uno from USB while you build, and unplug it before you move a wire.
The code
The sketch the circuit above runs. Open it in the editor, change a line and press Run: it compiles in your browser.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// 128 x 64 pixels, on the I2C bus: SDA pin A4, SCL pin A5
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("No SSD1306 at 0x3C");
for (;;) {}
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println("HELLO");
display.setTextSize(1);
display.println("SSD1306 OLED");
display.drawRect(0, 40, 128, 24, SSD1306_WHITE);
display.display();
Serial.println("OLED ready");
}
void loop() {
// A counter in the box, redrawn twice a second.
display.fillRect(2, 42, 124, 20, SSD1306_BLACK);
display.setCursor(8, 48);
display.print("Up for ");
display.print(millis() / 1000);
display.print(" s");
display.display();
delay(500);
}
Adafruit_SSD1306 display(128, 64, &Wire, -1) describes a 128 by 64 panel on the Wire bus with no reset pin. display.begin(SSD1306_SWITCHCAPVCC, 0x3C) starts the controller at its address and returns false if nothing answers there, which the sketch reports on the serial monitor rather than drawing into thin air.
Every drawing call (println, drawRect, fillRect) changes a copy of the screen in the board’s RAM. Nothing reaches the glass until display() sends the whole frame, 1024 bytes, over I2C. That is why the loop clears its box, draws the new number and calls display() once.
The frame buffer is 1 KB, half of the ATmega328P’s 2 KB of RAM, so on the Arduino Uno a big sketch with an OLED is the first to run out of memory. The font in the simulator is a 5 by 7 one with capitals, digits and punctuation, so lower case prints as capitals here.
Common mistakes with the SSD1306 OLED on the Arduino Uno
Forgetting display()
Every call before display() only changes the copy in RAM. A sketch that draws and never calls display() leaves the screen black, and that is the most common "my OLED does not work" there is.
Trying address 0x3D first
Adafruit’s own example uses 0x3D, the address of their 128 by 64 board with the jumper changed. The cheap blue and yellow modules answer at 0x3C. If begin() fails, the address is the first thing to check.
Running out of RAM
The display’s buffer takes 1 KB of the ATmega328P’s 2 KB. Add a few long strings and begin() fails because malloc() could not find room. Wrap fixed text in F("...") to keep it in flash.
Questions and answers
Can I test an SSD1306 OLED with an Arduino Uno without the hardware?
Yes. The circuit at the top of this page is an Arduino Uno with a SSD1306 OLED, running in your browser on a simulated ATmega328P. Every pixel the sketch sends is drawn on the simulated panel, so you can lay out a screen before the module arrives. Press Run it in the editor to change the wiring or the code; it is free and needs no account.
Which pins are SDA and SCL on the Arduino Uno?
On an Uno the I2C bus is A4 (SDA) and A5 (SCL). The SDA and SCL pins beside AREF are the same two wires, so either pair works.
Does the display work at 3.3 V?
Yes, the common modules run from 3.3 to 5 V. On an Arduino Uno 5 V is simpler, because the module’s pull-ups then pull to the same voltage the board uses.
Can I use U8g2 instead of the Adafruit library?
U8g2lib.h compiles here too. The page uses Adafruit_SSD1306 because it is what most tutorials start from, and its calls (setCursor, print, display) carry over to the other Adafruit displays.
Build your own SSD1306 OLED project
Open this circuit in the editor, change the wiring or the code, and keep your version in a free account.