Guide for TCA9548A I2C Multiplexer: ESP32, ESP8266, Arduino

In this guide, you’ll learn how to expand the I2C bus ports (ESP32, ESP8266, Arduino) using the TCA9458A 1-to-8 I2C Multiplexer. This piece of hardware is useful if you want to control multiple I2C devices with the same I2C address. For example, multiple OLED displays, or multiple sensors like the BME280.

Guide for TCA9548A I2C Multiplexer ESP32 ESP8266 Arduino

This tutorial is compatible with ESP32, ESP8266, and Arduino boards. We’ll program the boards using Arduino IDE.

Table of Contents

In this tutorial, we’ll cover the following topics:

Introducing the TCA9548A 1-to-8 I2C Multiplexer

TCA9548A I2C Multiplexer Sensor Module

The I2C communication protocol allows you to communicate with multiple I2C devices on the same I2C bus as long as all devices have a unique I2C address. However, it will not work if you want to connect multiple I2C devices with the same address.

The TCA9548A I2C multiplexer allows you to communicate with up to 8 I2C devices with the same I2C bus. The multiplexer communicates with a microcontroller using the I2C communication protocol. Then, you can select which I2C bus on the multiplexer you want to address.

To address a specific port, you just need to send a single byte to the multiplexer with the desired output port number.

TCA9548A I2C Multiplexer How it Works

TCA9548A Multiplexer Features

Here’s a summary of its main features:

  • 1 to 8 bidireccional translating switches
  • Active-low reset input
  • Three address pins—up to 8 TCA9548A devices on the same I2C bus
  • Channel selection through an I2C bus
  • Operating power supply voltage range: 1.65V to 5.5V
  • 5V tolerant pins

For a more detailed description, consult the datasheet.

TCA9548A Multiplexer I2C Address

The TCA9548A Multiplexer communicates with a microcontroller using the I2C communication protocol. So, it needs an I2C address. The address of the multiplexer is configurable. You can select a value from 0x70 to 0x77 by adjusting the values of the A0, A1, and A2 pins, as shown in the table below.

A0A1A2I2C Address
LOWLOWLOW0x70
HIGHLOWLOW0x71
LOWHIGHLOW0x72
HIGHHIGHLOW0x73
LOWLOWHIGH0x74
HIGHLOWHIGH0x75
LOWHIGHHIGH0x76
HIGHHIGHHIGH0x77

So, you can connect up to 8 TCA9548A multiplexers to the same I2C bus, which would allow you to connect 64 devices with the same address using only one I2C bus of the microcontroller.

For example, if you connect A0, A1, and A2 to GND, it sets address 0x70 for the multiplexer.

TCA9548A Pinout

The following table describes the TCA9584A Pinout.

PinDescription
VINPowers the multiplexer
GNDConnect to GND
SDAConnect to the master microcontroller SDA pin
SCLConnect to the master microcontroller SCL pin
RSTActive low RST pin—can be used to reset the multiplexer
A0Selects multiplexer I2C address—connect to GND or VCC
A1Selects multiplexer I2C address—connect to GND or VCC
A2Selects multiplexer I2C address—connect to GND or VCC
SD0SDA for channel 0
SC0SCL for channel 0
SD1SDA for channel 1
SC1SCL for channel 1
SD2SDA for channel 2
SC2SCL for channel 2
SD3SDA for channel 3
SC3SCL for channel 3
SD4SDA for channel 4
SC4SCL for channel 4
SD5SDA for channel 5
SC5SCL for channel 5
SD6SDA for channel 6
SC6SCL for channel 6
SD7SDA for channel 7
SC7SCL for channel 7

TCA9548A I2C Multiplexer Selecting an I2C Bus

As mentioned previously, to select a specific I2C bus to read/write data, you just need to send a single byte to the multiplexer with the desired output port number (0 to 7).

To do that, you can simply use the following user-defined function:

void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address is 0x70
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
}

Then, you just need to call that function and pass as an argument the port bus number you want to control before sending the I2C commands. For example, to control the device connected to bus number 3, you would call the following line before calling other I2C commands (note that it starts at 0):

TCA9548A(2);

You’ll see how this works with practical examples in the following sections.


Control Multiple OLED Displays—TCA9548A I2C Multiplexer

In this section, we’ll show you how to control multiple OLED displays. As an example, we’ll control four OLED displays, but you can connect up to 8 displays.

Parts Required

Here’s a list of the parts required for this example:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Multiple OLED Displays with I2C Multiplexer Circuit

Connect four OLED displays as shown in the following schematic diagram. We’re using buses number 2, 3, 4 and 5. You can choose any other port number.

We’re also connecting A0, A1, and A2 to GND. This selects address 0x70 for the multiplexer.

Multiple OLED Displays TCA9548A I2C Multiplexer wiring circuit diagram

Here are the default I2C pins depending on the microcontroller you’re using:

MicrocontrollerI2C Pins
ESP32GPIO 22 (SCL), GPIO 21 (SDA)
ESP8266GPIO 5 (D1) (SCL), GPIO 4 (D2) (SDA)
Arduino UnoA5 (SCL), A4 (SDA)

Multiple OLED Displays with I2C Multiplexer Code

Controlling the displays is as easy as controlling one display. You just need to consider selecting the right I2C bus before sending the commands to write to the display.

To learn how to control an I2C display, you can read the following articles:

Installing Libraries

We’ll use the following libraries to control the OLED display. Make sure you have these libraries installed:

You can install the libraries using the Arduino Library Manager. Go to Sketch Include Library > Manage Libraries and search for the library name.

If you’re using VS Code with the PlatformIO extension, copy the following to the platformio.ini file to include the libraries.

lib_deps = adafruit/Adafruit SSD1306@^2.4.6
	adafruit/Adafruit GFX Library@^1.10.10

After installing the libraries, you can proceed.

Copy the following code to your Arduino IDE and upload it to your board. It will work straight away.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Select I2C BUS
void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
}
 
void setup() {
  Serial.begin(115200);

  // Start I2C communication with the Multiplexer
  Wire.begin();

  // Init OLED display on bus number 2
  TCA9548A(2);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Init OLED display on bus number 3
  TCA9548A(3);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Init OLED display on bus number 4
  TCA9548A(4);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Init OLED display on bus number 5
  TCA9548A(5);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display.clearDisplay();

  // Write to OLED on bus number 2
  TCA9548A(2);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("1");
  display.display(); 

  // Write to OLED on bus number 3
  TCA9548A(3);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("2");
  display.display(); 
  
  // Write to OLED on bus number 4
  TCA9548A(4);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("3");
  display.display(); 
  
  // Write to OLED on bus number 5
  TCA9548A(5);
  display.clearDisplay();
  display.setTextSize(8);
  display.setTextColor(WHITE);
  display.setCursor(45, 10);
  // Display static text
  display.println("4");
  display.display(); 
}
 
void loop() {
  
}

View raw code

How the Code Works

Continue reading to learn how the code works or skip to the Demonstration section.

First, import the required libraries to control the OLED display: Adafruit_GFX and Adafruit_SSD1306. The Wire library is needed to use the I2C communication protocol.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Define the OLED width and height.

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Create an Adafruit_SSD1306 instance to communicate with the OLED display.

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

You can use the same instance to communicate with all displays. In that case, you need to clear the display buffer (display.clearDisplay()) before writing to another OLED.

Alternatively, you can create multiple Adafruit_SSD1306 instances, one for each OLED. In that case, you don’t need to clear the buffer. We’ll show you an example with multiple instances at the end of this section.

Select the I2C Channel

The TCA9548A() function can be called to select the bus that you want to communicate with. It sends a byte to the multiplexer with the port number.

// Select I2C BUS
void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
}

You must call this function whenever you want to select the I2C port.

setup()

In the setup(), initialize a serial communication for debugging purposes.

Serial.begin(115200);

Start I2C communication on the default I2C pins with the I2C multiplexer.

Wire.begin();

Then, initialize each display. The following lines show an example for the first OLED display (it is connected to bus number 2).

//Init OLED display on bus number 2
TCA9548A(2);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
} 
// Clear the buffer
display.clearDisplay();

Initializing the other displays is similar, but you need to call the TCA9548A() function with the corresponding I2C bus number.

Then, write something to the displays. Don’t forget you need to call the TCA9548A() function every time you want to switch between OLEDs. You also need to clear the display buffer before writing anything to the OLED.

// Write to OLED on bus number 2
TCA9548A(2);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("1");
display.display(); 

In this case, we’re just printing a different number on each display. Here’s an example for OLED number 4 (it is connected to bus number 5).

// Write to OLED on bus number 5
TCA9548A(5);
display.clearDisplay();
display.setTextSize(8);
display.setTextColor(WHITE);
display.setCursor(45, 10);
// Display static text
display.println("4");
display.display();

And that’s pretty much how the code works.

The following code shows a similar example but using multiple Adafruit_SSD1306 instances. Notice that you don’t need to clear the buffer before writing to the display.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display3(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_SSD1306 display4(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Select I2C BUS
void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
}

void setup() {
  Serial.begin(115200);

  // Start I2C communication with the Multiplexer
  Wire.begin();

  // Init OLED display on bus number 2 (display 1)
  TCA9548A(2);
  if(!display1.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display1.clearDisplay();

  // Init OLED display on bus number 3
  TCA9548A(3);
  if(!display2.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display2.clearDisplay();

  // Init OLED display on bus number 4
  TCA9548A(4);
  if(!display3.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display3.clearDisplay();

  // Init OLED display on bus number 5
  TCA9548A(5);
  if(!display4.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } 
  // Clear the buffer
  display4.clearDisplay();

  // Write to OLED on bus number 2
  TCA9548A(2);
  display1.setTextSize(8);
  display1.setTextColor(WHITE);
  display1.setCursor(45, 10);
  // Display static text
  display1.println("1");
  display1.display(); 
  
  // Write to OLED on bus number 3
  TCA9548A(3);
  display2.setTextSize(8);
  display2.setTextColor(WHITE);
  display2.setCursor(45, 10);
  // Display static text
  display2.println("2");
  display2.display(); 
  
  // Write to OLED on bus number 4
  TCA9548A(4);
  display3.setTextSize(8);
  display3.setTextColor(WHITE);
  display3.setCursor(45, 10);
  // Display static text
  display3.println("3");
  display3.display(); 
  
  // Write to OLED on bus number 5
  TCA9548A(5);
  display4.setTextSize(8);
  display4.setTextColor(WHITE);
  display4.setCursor(45, 10);
  // Display static text
  display4.println("4");
  display4.display();
}
 
void loop() {
  
}

View raw code

Demonstration

Upload the code to your board. Here’s what you should get.

OLED SSD1306 Demonstration TCA9548A I2C Multiplexer Sensor Module

As you can see, it is pretty easy to control multiple OLED displays showing different graphics using an I2C multiplexer.


Read Multiple BME280 Sensors —TCA9548A I2C Multiplexer

In this section, you’ll learn how to read data from multiple BME280 sensors using the TCA9548A I2C multiplexer. We’ll read data from four sensors, but you can hook up to 8 sensors.

BME280 Demonstration TCA9548A I2C Multiplexer Sensor Module

Parts Required

Here’s a list of the parts required for this example:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Multiple BME280 Sensors with I2C Multiplexer Circuit

Connect four BME280 sensors as shown in the following schematic diagram. We’re using buses number 2, 3, 4 and 5. You can choose any other port numbers.

We’re also connecting A0, A1, and A2 to GND. This selects address 0x70 for the multiplexer.

Multiple BME280 Sensors with TCA9548A I2C Multiplexer wiring circuit diagram

Here are the default I2C pins depending on the microcontroller you’re using:

MicrocontrollerI2C Pins
ESP32GPIO 22 (SCL), GPIO 21 (SDA)
ESP8266GPIO 5 (D1) (SCL), GPIO 4 (D2) (SDA)
Arduino UnoA5 (SCL), A4 (SDA)

Multiple BME280 Sensors with I2C Multiplexer Code

Similar to the OLED display, reading data from multiple sensors is as easy as controlling one single sensor. You just need to take into account selecting the right I2C bus before communicating with the sensor.

To learn how to read data from a BME280 sensor:

Installing Libraries

We’ll use the following libraries to read from the BME280 sensor. Make sure you have these libraries installed:

You can install the libraries using the Arduino Library Manager. Go to Sketch Include Library > Manage Libraries and search for the library name.

If you’re using VS Code with the PlatformIO extension, copy the following to the platformio.ini file to include the libraries.

lib_deps = adafruit/Adafruit Unified Sensor @ ^1.1.4
            adafruit/Adafruit BME280 Library @ ^2.1.2  

After installing the libraries, you can proceed.

Copy the following code to your Arduino IDE and upload it to your board. It will work straight away.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/tca9548a-i2c-multiplexer-esp32-esp8266-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1022)

Adafruit_BME280 bme1; // I2C
Adafruit_BME280 bme2; // I2C
Adafruit_BME280 bme3; // I2C
Adafruit_BME280 bme4; // I2C

// Select I2C BUS
void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
}

void printValues(Adafruit_BME280 bme, int bus) {
  TCA9548A (bus);
  Serial.print("Sensor number on bus");
  Serial.println(bus);
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  
  Serial.print("Pressure = ");
  Serial.print(bme.readPressure() / 100.0F);
  Serial.println(" hPa");

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");

  Serial.println();
}

void setup() {
  Serial.begin(115200);
  
  // Start I2C communication with the Multiplexer
  Wire.begin();

  // Init sensor on bus number 2
  TCA9548A(2);
  if (!bme1.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor on bus 2, check wiring!");
    while (1);
  }
  Serial.println();
  
  // Init sensor on bus number 3
  TCA9548A(3);
  if (!bme2.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor on bus 2, check wiring!");
    while (1);
  }
  Serial.println();
  
  // Init sensor on bus number 4
  TCA9548A(4);
  if (!bme3.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor on bus 2, check wiring!");
    while (1);
  }
  Serial.println();
  
  // Init sensor on bus number 5
  TCA9548A(5);
  if (!bme4.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor on bus 2, check wiring!");
    while (1);
  }
  Serial.println();
}

void loop() { 
  //Print values for sensor 1
  printValues(bme1, 2);
  printValues(bme2, 3);
  printValues(bme3, 4);
  printValues(bme4, 5);
  delay(5000);
}

View raw code

How the Code Works

Continue reading to learn how the code works or skip to the Demonstration section.

First, import the required libraries to control the BME280 display: Adafruit_BME280 and Adafruit_Sensor. The Wire library is needed to use the I2C communication protocol.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Then, you need to create several instances of Adafruit_BME280, one for each sensor: bme1, bme2, bme3, and bme4.

Adafruit_BME280 bme1; // I2C
Adafruit_BME280 bme2; // I2C
Adafruit_BME280 bme3; // I2C
Adafruit_BME280 bme4; // I2C

Select the I2C Channel

The TCA9548A() function can be called to select the bus that you want to communicate with. It sends a byte to the multiplexer with the port number.

// Select I2C BUS
void TCA9548A(uint8_t bus){
  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
}

You must call this function whenever you want to select the I2C port.

printValues() function

Then, we create a function printValues() that allows us to print in the Serial Monitor the values for each sensor. This function allows us to pass the Adafruit_BME280 instance and its bus.

Inside the function, we select the I2C bus we want to talk to by calling the TCA9548A() function and passing the bus as an argument.

TCA9548A (bus);

Then, we use the usual functions to get readings from the sensor.

Serial.print("Sensor number on bus");
Serial.println(bus);
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
  
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");

Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");

Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");

setup()

In the setup(), initialize a serial communication for debugging purposes.

Serial.begin(115200);

Start I2C communication on the default I2C pins with the I2C multiplexer.

Wire.begin();

Then, initialize each sensor. The following lines show an example for the first BME280 sensor (it is connected to bus number 2, and it refers to the bme1 instance).

//Init sensor on bus number 2
TCA9548A(2);
if (!bme1.begin(0x76)) {
  Serial.println("Could not find a valid BME280 sensor on bus 2, check wiring!");
  while (1);
}
Serial.println();

Initializing the other sensors is similar, but you need to call the TCA9548A() function with the corresponding I2C bus number. Also, don’t forget that each sensor has its own instance.

loop()

In the loop(), we call the printValues() function for each sensor.

printValues(bme1, 2);
printValues(bme2, 3);
printValues(bme3, 4);
printValues(bme4, 5);

And that’s pretty much how the code works.

Demonstration

Upload the code to your board. Open the Serial Monitor at a baud rate of 115200. The readings for each sensor will be displayed on the Serial Monitor.

Multiple BME280 Sensors I2C Multiplexer Demonstration

Wrapping Up

This tutorial taught you how to add more I2C ports to your microcontroller with the TCA9548A I2C multiplexer. This is especially useful if you want to connect multiple devices with the same I2C address. Furthermore, the I2C address of the multiplexer itself can be changed from 0x70 to 0x77. This allows us to connect up to 8 multiplexers simultaneously, which allows you to control 64 devices.

The examples shown throughout this tutorial are compatible with the ESP32, ESP8266, and Arduino boards.

We have an extensive tutorial about I2C functions with the ESP32:

Learn more about ESP32, ESP8266, and Arduino with our resources:

Free ProjectsCourse/eBook
ESP32ESP32 TutorialsLearn ESP32 with Arduino IDE
ESP8266ESP8266 TutorialsHome Automation using ESP8266
ArduinoArduino TutorialsArduino Step-by-step Projects

We hope you find this tutorial useful.

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

30 thoughts on “Guide for TCA9548A I2C Multiplexer: ESP32, ESP8266, Arduino”

  1. I’m following this tutorial and I cannot get it to work. When I run an i2c scan I get no devices found. This is when scanning the traditional way as well as using a nested for loop to scan all addresses on the multiplexor.

    In my online research people have recommended using pull up resistors. But I don’t see any mention of that in this tutorial. When I connect the OLED directly to my esp32 the i2c scan sees it. Is the lack of pull up resistors the reason my setup doesn’t work or do I just have a non-functional multiplexor?

    Reply
    • Hi.
      These modules don’t need resistors because they are already built-in into the module.
      If you were using the bare chip, you would need to use the resistors.

      The multiplexer will have a different address depending on the values of A0, A1, and A2.
      Make sure you’re connecting the multiplexer to the right I2C pins of your microcontroller.

      Regards,
      Sara

      Reply
  2. Good afternoon
    Excellent contribution, which has helped me to practice with the multiplexer and at the same time change OLED with the SH1106 driver, with excellent results.
    Thanks

    Reply
  3. Thank you for your excellent tutorials.
    I succeeded with BME280 and SSD1306 using the same I2C. Next step….
    I made a mix of the two parts of this tutorial using TCA9548A, two BME280 and two SSD1306.
    I defined bme1 and bme2 as sensors and display1 and display2 for screens 1 and 2
    Once I got the “fusion” of the codes I compiled it and it was ok.
    No problem connecting the devices according to your diagrams.
    I tried the code displaying: display1(“1”); and display2(“2”) it was ok. That means the circuit and the code for printing at least was correct.
    The problem comes when displaying the variables:
    display1.print(bme1,readTemperature());
    ……..
    display2.print(bme2,readTemperature());
    it shwos:
    Screen1 181,18 Screen2 180,25
    This values don’t change even heating the sensors with my fingers
    I changed the positions of BME1 and BME2 , …..the same result.
    Changing position of SSD1 and SSD2 …. Screen2 180.25 and Screen 1 181,18

    I included in the same code a part that prints the BME values on the monitor and they are correct.
    I tried to define a STRING ON EACH VARIABLE BUT ALWAYS THE SAME……..
    PLEASE, CAN YOU HELP ME? THANK YOU

    Reply
    • Hi.
      You’re probably not updating your OLED displays properly.
      Make sure you call: display.clearDisplay() before writing something to the display.
      AND, don’t forget to call display.display() after any display.print(…).
      I hope this helps.
      Regards,
      Sara

      Reply
      • Thank you Sara for your answer.
        In my code after “writing” I call to “display.display()” but before writing I did not call to
        “display.clearDisplay()” once corrected it, when compiling, at code point:
        — display2.display(bme1.readTemperature());
        I get error:
        ” no matching function for call to ‘Adafruit_SSD1306::display(float)'”
        It seems a problem of writing a float variable. This is why I tried to define a Srting without any result.
        The same order
        — display.display(bme.readTemperature());
        works well when BME280 and SSD1306 work on the same I2C without TCA9548A
        I’m thinking the possibility of a bad pin welding in TCA9548A. I’ll try with a new one.
        I’m very confused.

        Reply
        • Solved my problem. In case anybody interested i explain how I solved it.
          The problem :
          point of code:
          — display2.print(bme1.readTemperature());
          when compiling I got:
          ” no matching function for call to ‘Adafruit_SSD1306::display(float)’”

          Then I defined:
          float temp,….,…;
          …………..
          temp = bme.readTemperature();
          ……………..
          display.print(temp);

          it works wery well.
          Thank you for yout attention.

          Reply
          • Bona tarda Jordi, series tan amable de compartir el teu codi. Et deixo el meu email [email protected] Gràcies. Salutacions

            Good afternoon Jordi, I would appreciate it if you could share your code. I leave you my email [email protected] Thank you, a cordial greeting.

  4. thanks, excelet tutorial,
    i need conect a nodemcu v3 to multiplex, i like use i2c keypad, i2c ole and i2c lcd

    i not understand, how to connect pin A0,A1,A2, ti pin Nodemcu, the tutorial work only display ole,

    not work example
    TCA9548A(0); TCA9548A(1); and use others port never
    work not problem
    TCA9548A(2);

    i change multiplex for other, never working, please help me ..

    sc0/sd0 = keypad_i2c
    sc1/sd1= Lcd 16×2 use i2c
    sc2/sd2 = display ole
    SC3/sD3= MFR522 I2C.

    the utils i2scanner, found only display ole
    the components direct to nodemcu worwing, ok.

    Reply
  5. Hello,

    Thank you for the informative tutorial, Can you please tell me the software with which you showed us the wiring? I tried circuit but it does not have the multiplexer in it. ‘

    Thank you in advance

    Reply
  6. Hello,
    and thanks for another great tutorial 🙂

    I just want to mention that the program won´t show anything if you don´t connect all I2C devices.

    This is due to the “while (1)” constrain during initialization.

    So if you only have two sensors at hand comment the other initializing parts out.

    Maybe “while” should not be used?

    Greetings Dom

    Reply
  7. Hi again,

    one question though:

    If you combine both projects (OLED and BME) you can display a sensor reading on the OLED.

    BUT I was able to do so only if I hoocked up one OLED to the TCA9548A() as another device.

    When I tried to put it parallel to the TCA9548A() it messed up!?

    So is it working this way at all? Or does all I2C devices run trough the TCA9548A()?

    Thanks Dom

    Reply
  8. Hola, buenas tardes Sara Santos. Agradecerte por compartir la información.
    Ayuda por favor, ¿Cómo implementaría el código en caso de usar 3 sensores MPU6050?

    Reply
  9. hi there, i am trying to connect 5 MPU6050 sensors using ESP32 and MULTIPLEXER. can you help with the coding in arduino ide. if possible can we connect to discuss. thanks.

    Reply
  10. Great tutorial 🙂 Quick question, could you add an example on how to connect 2 multiplexers at the same time? Thanks.

    Reply
  11. Hi there Sara,

    Thanks for this tutorial. I have been able to hook up 16 OLED screens at once for my Jingle cart machine, using 2 multiplexers and a Arduino Mega!

    Reply
  12. Hello Sara,

    I used the exact same code as you posted, with 4 bme280 and a PCA9546, which should work the same (isnt it ?).
    It works for the first loop, but give nonsense and reboots at the second.
    I posted a question on the forum.

    below is the main loop

    Thanks for any help

    Jacques

    void loop() {
    //Print values for sensors
    printValues(bme0, 0);
    printValues(bme1, 1);
    printValues(bme2, 2);
    printValues(bme3, 3);
    delay(5000);
    Serial.println(” end of loop”);
    }

    Here is the output :

    Sensor number on bus0
    Temperature = 22.21 *C
    Pressure = 1022.59 hPa
    Humidity = 52.52 %

    Sensor number on bus1
    Temperature = 21.92 *C
    Pressure = 1021.75 hPa
    Humidity = 50.33 %

    Sensor number on bus2
    Temperature = 21.68 *C
    Pressure = 1020.94 hPa
    Humidity = 53.21 %

    Sensor number on bus3
    Temperature = 22.04 *C
    Pressure = 1021.31 hPa
    Humidity = 51.59 %

    end of loop
    Sensor number on bus0
    Temperature = 183.15 *C
    Pressure = -133.56 hPa
    Humidity = 100.00 %

    ————— CUT HERE FOR EXCEPTION DECODER —————

    Exception (3):
    epc1=0x4010084d epc2=0x00000000 epc3=0x00000000 excvaddr=0x4003bff9 depc=0x00000000

    stack>>>

    ctx: cont
    sp: 3ffffdb0 end: 3fffffd0 offset: 0150
    3fffff00: 00000568 000000ad 3ffe85e4 40100906
    3fffff10: 40202cd4 3ffe889b 3ffee860 3ffee8e0
    3fffff20: 3fffdad0 00000020 3ffef7c4 40100c54
    3fffff30: 40202cd4 00000000 3fffff50 402015c2
    3fffff40: 3fffdad0 00000000 00000054 402012a4
    3fffff50: 3ffef7c4 00000000 00000000 00000000
    3fffff60: 00000000 00000000 00000060 000e4ef1
    3fffff70: 00000000 67546ce2 92440032 0bd0d678
    3fffff80: ffdb1ad6 300cfff9 1388d120 0149004b
    3fffff90: 01970000 001e0032 00000000 000000ed
    3fffffa0: 000000a0 00000000 3ffee8b4 3ffee8e0
    3fffffb0: 00000000 00000000 3ffee8b4 40203670
    3fffffc0: feefeffe feefeffe 3fffdab0 40101001
    <<<stack<<<

    ————— CUT HERE FOR EXCEPTION DECODER —————

    Reply
  13. Hello, excellent tutorial, rich material of information!

    I would like to know if I can read the data from 3 ADXL345 accelerometer sensors with the TCA9548A on the ESP32, and what would it look like?

    Grateful!

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.