You have three BME280 environmental sensors on your workbench, but they all default to the same I2C address (0x76 or 0x77). You cannot change the hardware address on two of them, and software tricks will not save you. I2C multiplexing solves this by inserting a silicon traffic switch between your microcontroller and the sensors, routing the master's SDA/SCL lines to one of several isolated downstream channels on demand.
Instead of fighting address collisions or attempting fragile bit-banging, a multiplexer IC like the Texas Instruments TCA9548A allows you to connect up to eight identical devices to a single I2C bus. Below is the physical, electrical, and code-level blueprint for implementing I2C multiplexing reliably.
I2C Bus Mechanics and Multiplexer Silicon
Before wiring a multiplexer, you must understand the physical limits of the I2C protocol. I2C is a multi-master, multi-slave, packet-switched, single-ended, serial computer bus. It relies on open-drain lines pulled high by resistors. When you introduce a multiplexer, you are essentially adding analog switches in series with these lines, which adds capacitance and resistance.
Protocol Fit: Distance, Speed, and Device Count
Which protocol fits your project? Use this decision matrix before committing to I2C multiplexing:
- I2C (with Mux): Best for high device count (up to 100+ via muxing) at short distances (<1 meter) and low-to-medium speeds (100kHz - 1MHz). Requires only 2 shared wires.
- SPI: Best for high speed (10MHz+) and medium device count. Requires 3 shared wires + 1 dedicated Chip Select wire per device. Wiring complexity scales poorly past 5 devices.
- UART/RS-485: Best for long distances (up to 1200m for RS-485) and low device count without complex addressing protocols.
Bus Mechanics and IC Specifications
The following tables define the baseline I2C protocol limits and the specific silicon options available for multiplexing in 2026.
| Parameter | Standard I2C Spec | Multiplexed Reality (TCA9548A) |
|---|---|---|
| Wires Required | 2 (SDA, SCL) + GND | 2 Main + (2 × Channels) + GND |
| Max Speed | 3.4 MHz (High-Speed Mode) | 400 kHz (Fast Mode) reliably |
| Addressing | 7-bit or 10-bit | Mux uses 7-bit (0x70-0x77) |
| Max Bus Capacitance | 400 pF | 400 pF per active channel |
| Max Distance | ~1 meter (at 100kHz) | ~1 meter main + ~0.5m branches |
| Part Number | Manufacturer | Channels | VCC Range | Typical Price (Breakout) |
|---|---|---|---|---|
| TCA9548A | Texas Instruments | 8 | 1.65V - 5.5V | $6.00 - $9.50 |
| PCA9548A | NXP Semiconductors | 8 | 2.3V - 5.5V | $7.50 - $11.00 |
| TCA9546A | Texas Instruments | 4 | 1.65V - 5.5V | $4.50 - $6.00 |
| PCA9544A | NXP Semiconductors | 4 | 2.3V - 5.5V | $5.00 - $7.00 |
Physical Wiring and Pull-Up Resistor Physics
The most common reason I2C multiplexer projects fail on the bench is a misunderstanding of pull-up resistors. I2C lines (SDA and SCL) are open-drain. The microcontroller and sensors can only pull the line LOW; they rely on pull-up resistors to bring the line HIGH.
The Multiplexer Advantage: When you wire sensors directly to an I2C bus, their pull-up resistors add in parallel, lowering the total resistance and potentially exceeding the 3mA sink current limit of the microcontroller GPIO. A TCA9548A isolates the downstream channels. The pull-ups on Channel 0 do not electrically parallel with the pull-ups on Channel 1. You can safely use 4.7kΩ pull-ups on every single channel without overloading the ESP32.
Wiring the TCA9548A to an ESP32
Follow this exact physical pinout. Do not leave the RESET pin floating.
| TCA9548A Pin | ESP32 DevKit Pin | Notes |
|---|---|---|
| VIN / VCC | 3V3 | Match the logic level of your sensors. |
| GND | GND | Common ground is mandatory. |
| SCL | GPIO 22 | Standard ESP32 I2C SCL. |
| SDA | GPIO 21 | Standard ESP32 I2C SDA. |
| RST | 3V3 (or float if pulled high on breakout) | Active LOW. Tie to VCC to prevent brownout resets. |
For the downstream sensors (e.g., BME280), wire their VCC, GND, SCL, and SDA to the corresponding Channel 0, Channel 1, etc., headers on the multiplexer. If your breakout board lacks downstream pull-ups, add 4.7kΩ resistors from SDA to VCC and SCL to VCC on each channel you use.
Minimal Working Exchange: ESP32 to TCA9548A
The TCA9548A has its own I2C address, typically 0x70. To route the master bus to a specific channel, you write a single byte to the mux where the bits represent the channels (e.g., 0x01 for Channel 0, 0x02 for Channel 1, 0x04 for Channel 2). You can also enable multiple channels simultaneously by ORing the bits, though this defeats the purpose of avoiding address clashes.
Below is a complete, compilable Arduino/ESP32 sketch using the native Wire library. It initializes the mux, switches to Channel 0, and scans for the BME280 sensor (address 0x76).
#include <Wire.h>
#define MUX_ADDRESS 0x70
#define SENSOR_ADDRESS 0x76
// Function to switch the TCA9548A multiplexer channel
void selectMuxChannel(uint8_t channel) {
if (channel > 7) return; // Guard against invalid channels
Wire.beginTransmission(MUX_ADDRESS);
// Write a byte with the nth bit set to 1
Wire.write(1 << channel);
uint8_t error = Wire.endTransmission();
if (error != 0) {
Serial.printf("[ERROR] Mux I2C error: %d\n", error);
}
}
void setup() {
Serial.begin(115200);
delay(500);
Serial.println("I2C Multiplexing Boot Sequence...");
// Initialize main I2C bus (ESP32 defaults: SDA=21, SCL=22)
Wire.begin();
Wire.setClock(400000); // Set to 400kHz Fast Mode
// Test Channel 0
selectMuxChannel(0);
delay(10); // Allow analog switches to settle
Wire.beginTransmission(SENSOR_ADDRESS);
uint8_t sensorError = Wire.endTransmission();
if (sensorError == 0) {
Serial.println("[SUCCESS] BME280 found on Channel 0!");
} else {
Serial.printf("[FAIL] No sensor on Channel 0. Error code: %d\n", sensorError);
}
}
void loop() {
// In a real project, you would cycle through channels 0-7 here,
// reading data from identical sensors on each branch.
delay(1000);
}
Debugging the Bus: Sniffing and Classic Failures
When an I2C multiplexer setup fails, it rarely fails silently. The bus will lock up, the microcontroller will hang, or the sensor will return garbage data. Here is how to diagnose the three classic I2C failures, plus the tools to sniff the physical layer.
The Classic Failures and Fixes
- Address Clash (Downstream): Symptom: The scanner finds the sensor, but data reads are corrupted or missing. Cause: You wired two sensors with the same address to the same multiplexer channel. Fix: Move one sensor to a different channel. The mux only isolates channels from each other, not devices on the same channel.
- Missing Pull-Up Resistors: Symptom:
Wire.endTransmission()returns error code 2 or 4. Oscilloscope shows SDA/SCL lingering at 0.5V instead of snapping to 3.3V. Cause: Open-drain lines floating. Fix: Verify 4.7kΩ pull-ups on the main bus AND the downstream channels. (Note: Adafruit breakouts have main bus pull-ups, but often omit downstream ones). - Baud Mismatch and Clock Stretching: Symptom: ESP32 crashes or watchdog resets during sensor read. Cause: A slow downstream sensor holds SCL LOW (clock stretching) to buy time. The TCA9548A passes this stretch through to the master. If the master (ESP32) has a strict I2C timeout, it aborts and locks the bus. Fix: Lower the bus speed to 100kHz (
Wire.setClock(100000)) or increase the I2C timeout in your microcontroller's HAL configuration.
How to Sniff and Debug the Physical Layer
Do not guess what is happening on the wire; look at it. For under $150, a basic logic analyzer (like a Saleae Logic clone or a Digilent Analog Discovery) running PulseView/Sigrok will decode I2C packets natively.
- Check the Mux Address: Probe the main SDA line. You should see the master send
0xE0(0x70 shifted left for write) followed by the channel select byte. - Check the Downstream Edge: Probe Channel 1 SDA. You should see the exact same sensor traffic, delayed by roughly 100 nanoseconds (the propagation delay of the TCA9548A internal MOSFETs).
- The "SDA Stuck Low" Recovery: If a sensor resets mid-byte, it may hold SDA low, locking the entire bus. Because the mux isolates the channels, a lockup on Channel 2 won't freeze Channel 0. To clear a locked downstream device without power-cycling, toggle the SCL line manually via GPIO bit-banging 9 times. The sensor will interpret the 9th clock pulse as a NACK and release the SDA line.
For deeper electrical specifications regarding bus capacitance and timing diagrams, always refer to the TI TCA9548A Datasheet and the foundational NXP I2C-bus specification and user manual. If you are using off-the-shelf maker hardware, the Adafruit TCA9548A wiring guide provides excellent visual references for breadboard layouts.






