Dual OLED Arduino — Two SSD1306 Displays on One I2C Bus
Students ask for this constantly: “Can I run two OLEDs from one Arduino?” Yes — if the
modules can use different I2C addresses. Most cheap 0.96" boards ship as
0x3C. For two screens on the same SDA/SCL wires, one of them must become 0x3D.
If both stay on 0x3C, the bus fights itself. You will see flicker, wrong content, or only one
panel responding. That is not a library bug — it is an address collision.
What you need
- Arduino Uno / Nano (or ESP32 — same idea, different SDA/SCL pins)
- Two I2C SSD1306 modules (4-pin: VCC GND SDA SCL)
- At least one module with an address select pad / resistor / jumper for
0x3D - Adafruit GFX + Adafruit SSD1306 libraries
Hardware: change one display to 0x3D
Look on the back of the PCB. Many boards have a tiny solder jumper labeled ADDR, 0x3C / 0x3D, or a resistor footprint next to the controller. Closing the jumper (or moving the 0Ω resistor) switches the address.
Not every AliExpress module has this. If both boards are hard-wired to 0x3C with no pad, you
cannot put them on the same I2C bus without a multiplexer (TCA9548A). Buy modules that document dual-address
support, or use SPI OLEDs with separate CS pins instead.
Wiring (shared bus)
| Both OLEDs | Arduino Uno / Nano |
|---|---|
| VCC | 5V (check 3.3V-only modules) |
| GND | GND |
| SDA | A4 (shared) |
| SCL | A5 (shared) |
Same four nets for both panels. Power both from the board if current is modest; for long cables use a solid GND and consider a 0.1 µF cap near each module if you see sparkles.
Verify with the I2C scanner
Before writing dual-screen code, upload a scanner. You want two lines:
I2C device found at 0x3C
I2C device found at 0x3D
Only one address? The second module did not switch, or a wire is loose. Fix hardware first.
Working sketch: two Adafruit_SSD1306 objects
Important: each display object has its own 1 KB buffer on Uno. Two 128×64 buffers ≈ 2 KB — that is basically all of Uno SRAM. Keep other globals tiny, or use 128×32 panels / ESP32.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define W 128
#define H 64
Adafruit_SSD1306 displayA(W, H, &Wire, -1); // 0x3C
Adafruit_SSD1306 displayB(W, H, &Wire, -1); // 0x3D
void setup() {
Serial.begin(9600);
if (!displayA.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("Display A (0x3C) failed"));
for (;;);
}
if (!displayB.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
Serial.println(F("Display B (0x3D) failed"));
for (;;);
}
displayA.clearDisplay();
displayA.setTextSize(2);
displayA.setTextColor(SSD1306_WHITE);
displayA.setCursor(0, 20);
displayA.println(F("Screen A"));
displayA.display();
displayB.clearDisplay();
displayB.setTextSize(2);
displayB.setTextColor(SSD1306_WHITE);
displayB.setCursor(0, 20);
displayB.println(F("Screen B"));
displayB.display();
}
void loop() {
// Example: bounce a marker on A, counter on B
static int x = 0;
static int dir = 1;
displayA.clearDisplay();
displayA.fillCircle(x, 32, 6, SSD1306_WHITE);
displayA.display();
displayB.clearDisplay();
displayB.setTextSize(2);
displayB.setCursor(0, 24);
displayB.print(F("x="));
displayB.print(x);
displayB.display();
x += dir;
if (x < 6 || x > 121) dir = -dir;
delay(30);
}
Mistakes I see every time
- Calling begin() twice with 0x3C. Second display must be
0x3D. - Updating only one object.
displayA.display()does not refresh B. - SRAM exhaustion on Uno. Two full buffers + big bitmaps = random crashes. Drop resolution or move to ESP32.
- Mixing SH1106 and SSD1306 without the right drivers — one panel will look shifted.
When you need more than two
Three+ devices on the same address space need a TCA9548A I2C multiplexer, or SPI displays with separate chip-select lines. For classroom demos, two I2C panels at 0x3C/0x3D is the sweet spot.
Using Dual Screen mode in the tool
In OLED Animation Maker, choose Dual Screen (2 OLEDs) if you want different animations on A and B. The exporter targets the same 0x3C / 0x3D pattern as this sketch.
FAQ
Can both displays show the same animation?
Yes — draw into both buffers the same way, or draw once and copy commands. Usually people want different content though.
Do I need pull-up resistors?
Most modules already have I2C pull-ups. Two modules = two sets of pull-ups, which is usually still OK. If the bus is flaky with long wires, check voltage levels with a meter.
Uno vs ESP32 for dual OLED?
ESP32 has far more RAM. Dual 128×64 is uncomfortable on Uno; fine on ESP32.
Related
Design Screen A and Screen B separately
Dual Screen mode → export code for both addresses.
Open the tool →