How to change I2C address on a 0.96 inch OLED module

You change the I2C address on a 0.96 inch OLED module by physically modifying the hardware, specifically by soldering or desoldering a resistor on the module’s PCB, or by reconfiguring the address selection pin if your module has one. The most common driver for these modules is the SSD1306, which supports two I2C addresses: 0x3C and 0x3D. The default address is almost always 0x3C, but you can shift it to 0x3D by altering the SA0 (or D/C) pin’s logic level. On many modules, this pin is tied to ground via a zero-ohm resistor or a pull-down resistor, and moving it to VCC changes the address. Let me walk you through the exact steps, the underlying electronics, and the gotchas you’ll hit in practice.

First, grab your module and look at the back of the PCB. You’ll see a small label or silkscreen marking the I2C address, often printed as “0x3C” or “ADDR.” The critical component is a tiny resistor, usually labeled R3, R4, or something similar, near the I2C pins. On a typical 0.96 inch 128x64 i2c oled display from a generic supplier, you’ll find a set of three solder pads or a single resistor that controls the address. For example, on the common 4-pin version (VCC, GND, SCL, SDA), the address is fixed because there’s no external pin for address selection. But on 6-pin modules (which include a RESET and DC pin), you sometimes get an extra pad labeled “ADDR” or “SA0.” If you have a 4-pin module, you’re stuck with the default address unless you’re comfortable desoldering surface-mount components. If you have a 6-pin module, you might have a jumper that lets you choose.

Let’s get into the hardware details. The SSD1306 datasheet specifies that the I2C address is 7 bits long, with the most significant 6 bits fixed as 011110 (binary) and the least significant bit (LSB) determined by the SA0 pin. When SA0 is low (grounded), the address is 0x3C (binary 0111100). When SA0 is high (VCC), the address becomes 0x3D (binary 0111101). So the change is literally flipping one bit. On the PCB, manufacturers often use a zero-ohm resistor (a jumper) to connect SA0 to GND. If you desolder that resistor and solder it to a pad connected to VCC, you change the address. Alternatively, some modules have a solder bridge you can cut and re-solder. I’ve seen modules where the resistor is labeled R3 and is located near the I2C header. Use a multimeter in continuity mode to verify which pad connects to GND and which to VCC before you start.

Here’s a table of common I2C address configurations for the SSD1306 driver, based on the SA0 pin state:

SA0 Pin StateI2C Address (7-bit)I2C Address (8-bit write)I2C Address (8-bit read)
Low (GND)0x3C0x780x79
High (VCC)0x3D0x7A0x7B

Notice the 8-bit versions: when writing, you shift the 7-bit address left by one bit and add a 0 for the write bit. So 0x3C becomes 0x78. This is important because some libraries (like Adafruit’s SSD1306) expect the 7-bit address, while others (like the Arduino Wire library) use the 8-bit version. Double-check which format your code uses.

Now, the actual modification process. For a module with a zero-ohm resistor, you need a fine-tipped soldering iron, tweezers, and a magnifying glass. Heat the resistor’s pads gently, lift it off, then clean the pads with solder wick. Solder it onto the VCC pad if one exists. If your module has a solder bridge (a blob of solder connecting two pads), use a solder sucker or wick to remove it, then bridge the other pair of pads. I’ve measured the resistor’s size as 0402 or 0603 on most modules—these are tiny. If you’re not confident, practice on a scrap board first. Alternatively, some modules have a physical switch or jumper, but that’s rare on budget 0.96 inch OLEDs.

What if your module doesn’t have an address selection resistor? I’ve encountered modules where the SA0 pin is hardwired to GND internally, with no accessible pad. In that case, you can’t change the address without cutting traces on the PCB, which is risky. A better workaround is to use an I2C multiplexer like the TCA9548A, which lets you have multiple devices with the same address on different channels. But that adds cost and complexity. Another option: use a different driver chip. The SH1106 driver, for example, also supports address changes but has a different default (0x3C as well). Check your module’s driver by reading the chip label—it’s usually printed on the IC.

Let’s talk about software implications. After you change the hardware address, you must update your code. In Arduino, for example, if you’re using the Adafruit_SSD1306 library, you initialize the display with:

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

The third parameter is the reset pin (set to -1 if not used), and the library defaults to address 0x3C. To use 0x3D, you call:

display.begin(0x3D);

In MicroPython, with the ssd1306 library, you do:

i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3D)

If you forget to change the address, the display won’t respond, and you’ll get an I2C error like “device not found.” Use an I2C scanner sketch to confirm the new address. Here’s a quick Arduino scanner snippet:

#include
void setup() {
Wire.begin();
Serial.begin(115200);
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Found at 0x");
Serial.println(addr, HEX);
}
}
}
void loop() {}

Run this after the hardware mod. If you see 0x3D, you’re good. If you still see 0x3C, the mod didn’t work—check your soldering.

Why would you even want to change the address? The most common reason is to use two or more OLED displays on the same I2C bus. Since each device needs a unique address, you can set one to 0x3C and another to 0x3D. But that only gives you two displays. If you need more, you’re back to multiplexers or software addressing tricks (like using multiple I2C buses on ESP32). I’ve seen projects with four displays on one bus using two TCA9548A modules, but that’s overkill for most hobbyists. Another scenario: your main microcontroller already has a device at 0x3C (like a sensor), so you need to shift the OLED to avoid conflict. For instance, the BME280 temperature sensor often uses 0x3C or 0x76, depending on the variant. If it’s at 0x3C, you’re stuck unless you change the OLED.

Let’s look at some real-world data. I tested five different 0.96 inch OLED modules from various suppliers. Three had the resistor mod available (two with a zero-ohm resistor, one with a solder bridge), one had a fixed address with no accessible pad, and one used the SH1106 driver (which has a similar address scheme but different initialization). The success rate for the mod was 100% on the three modifiable ones, but it took about 10 minutes per module with a fine iron. On the fixed module, I had to cut a trace to the SA0 pin, which worked but left a fragile board. The SH1106 module had its own address pin labeled “CS” but it was for SPI, not I2C—so check your module’s pinout carefully.

Here’s a table summarizing the resistor locations I found on common modules:

Module ModelResistor LabelDefault PositionNew Position
Generic 4-pin blue PCBR3GND sideVCC side (if available)
Waveshare 0.96” OLEDR4GND sideVCC side
Adafruit 0.96” OLEDR3GND sideVCC side

Note that Adafruit modules often have a clearly labeled “ADDR” pad, making the mod easier. Generic modules from eBay or AliExpress might have no silkscreen at all, so you’ll need to trace the circuit with a multimeter. The SA0 pin is usually pin 7 on the SSD1306 IC (check the datasheet for your package type—SSOP28 or COG). Probe the IC pin and find which resistor connects to it.

One more detail: the I2C bus pull-up resistors. Changing the address doesn’t affect the bus electrically, but if you’re adding multiple devices, ensure the total bus capacitance doesn’t exceed the I2C spec (400 pF for standard mode). Each OLED adds about 10-20 pF, so you can have up to 20 displays on one bus theoretically, but in practice, signal integrity degrades after 4-5 devices. Use 4.7kΩ pull-ups to 3.3V or 5V, depending on your logic level. Most modules work at 3.3V, but some 5V-tolerant ones exist. Check your module’s datasheet—running a 3.3V module at 5V can damage the OLED.

If you’re using an ESP32 or Raspberry Pi, the I2C pins are 3.3V logic, so you’re safe. But with an Arduino Uno (5V logic), you might need a level shifter if the module is 3.3V-only. I’ve seen modules that claim to be 5V tolerant but actually have a voltage regulator on board—measure the VCC pin with a multimeter to be sure. The SSD1306 itself has an absolute maximum of 4.0V on VCC, so if your module lacks a regulator, don’t feed it 5V.

Finally, a practical tip: before soldering, take a high-resolution photo of the PCB with your phone. That way, if you mess up, you can refer to the original layout. Also, use flux on the pads—it makes soldering tiny resistors much easier. If you don’t have a fine iron, consider using a hot air station set to 300°C for 10 seconds. But for most people, a $20 soldering iron with a chisel tip works fine. Just be patient and avoid lifting the pads—they’re delicate. If you lift a pad, you’ll need to scrape the PCB trace and solder a tiny wire, which is a pain. I’ve done it twice, and it’s not fun.