Arduino Nano 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 Nano 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 Nano 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 Nano
Every connection in the circuit above, with the board’s own pin names.
| SSD1306 OLED pin | Arduino Nano 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 Nano’s I2C data line, where Wire.begin() puts it. |
| SCL | pin A5 | Arduino Nano’s I2C clock line. |
The Nano has the Uno’s chip, so I2C is A4 (SDA) and A5 (SCL), on the analog side of the board next to A6 and A7. The display answers at address 0x3C, the address almost every 0.96 inch module ships with.
Pins to leave alone on the Arduino Nano
A6 and A7 are analog only: pinMode(A6, OUTPUT) does nothing and digitalRead(A7) is not there to call. D0 and D1 are the USB serial port.
On a real bench
The Nano plugs into the breadboard itself, straddling the center channel, so the SSD1306 OLED goes in a few columns along and every connection is a short jumper. The silkscreen labels its pins D2 to D13 and A0 to A7; in code D2 is simply 2. A Nano clone with a CH340 USB chip needs that driver on a real computer.
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 Nano 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 Nano
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 Nano without the hardware?
Yes. The circuit at the top of this page is an Arduino Nano 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 Nano?
The Nano has the Uno’s chip, so I2C is A4 (SDA) and A5 (SCL), on the analog side of the board next to A6 and A7.
Does the display work at 3.3 V?
Yes, the common modules run from 3.3 to 5 V. On an Arduino Nano 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.