How to call multiple TCA9548A I2C MUX with different addresses

Hi,

I have 3 TCA9548A I2C Multiplexers connected to a NodeMCU (ESP8266). Also connected 6 I2C sensors with same addresses to each of the TC9548A on different channels. How do I call each of the TCA9548A I2C MUX with their address to read the sensor data continuously in a loop?
So far I can only read the sensors off one TCA9548A MUX. But unable to do so off the three MUX's.

Any help regarding this would be much appreciated.

I have attached the code for your reference.

//Libraries*******************

#include "Wire.h"
#include <Wire.h>
#include <SPI.h>
#include "SparkFun_SCD30_Arduino_Library.h" //Click here to get the library: http://librarymanager/All#SparkFun_SCD30
#include <Adafruit_BMP280.h>
#include <Adafruit_INA219.h>

//*********************************************** R1 SCD30 sensor ******************************************************

SCD30 airSensor;
//SCD30 airSensor;
//SCD30 airSensor_R3;
//SCD30 airSensor_R4;
//SCD30 airSensor_R5;
//SCD30 airSensor_R6;

//
//float co2 = 0;
//float co2hum = 0;
//float co2temp = 0;

////*********************************************** R1 BMP280 sensor ******************************************************

Adafruit_BMP280 bmp; // use I2C interface
//Adafruit_BMP280 bmp; // use I2C interface
//Adafruit_BMP280 bmp_R3; // use I2C interface
//Adafruit_BMP280 bmp_R4; // use I2C interface
//Adafruit_BMP280 bmp_R5; // use I2C interface
//Adafruit_BMP280 bmp_R6; // use I2C interface

Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();

//Adafruit_Sensor *bmp_temp = bmp_R2.getTemperatureSensor();
//Adafruit_Sensor *bmp_pressure = bmp_R2.getPressureSensor();

//Adafruit_Sensor *bmp_R1_temp = bmp_R1.getTemperatureSensor();
//Adafruit_Sensor *bmp_R1_pressure = bmp_R1.getPressureSensor();

////*********************************************** R1 INA219 sensor ******************************************************
//
Adafruit_INA219 ina219;
//Adafruit_INA219 ina219;
////Adafruit_INA219 ina219_R3;
////Adafruit_INA219 ina219_R4;
////Adafruit_INA219 ina219_R5;
////Adafruit_INA219 ina219_R6;
//
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float power_mW = 0;
float loadvoltage=0;
float array1[3];

//**************************************************************************************************

void setup(){
setupMux1();
setupMux2();
setupMux3();
}

void loop(){
loopMux1();
loopMux2();
loopMux3();
}

//**************************************** MUX 1 **********************************************

#define TCAADDR Mux1 0x70

#define TCAADDR Mux2 0x71

//#define TCAADDR 0x72

void tcaselect(uint8_t i) {
if (i > 7) return;

Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}

void setupMux1() {
Wire.beginTransmission(0x70); // join i2c bus (address optional for master)
delay(1000);
Serial.begin(115200); // start serial for output
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}

Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();

Serial.println(F("##############################"));
Serial.println(F("Starting Initialization"));
Serial.println(F("##############################"));

//*************INITIALIZING MUX 1 SENSORS *******************************

tcaselect(0);
Serial.println("Channel 0 of Mux");
Serial.println("R1 SCD30 Example");
Wire.begin();

if (airSensor.begin() == false)
{
Serial.println("R1 Air sensor not detected. Please check wiring. Freezing...");
while (1)
;
}

tcaselect(2); // channel 7 --> BMP280
Serial.println("Channel 1 of Mux");
Serial.println("R2 SCD30 Example");
Wire.begin();

if (airSensor.begin() == false)
{
Serial.println("R2 Air sensor not detected. Please check wiring. Freezing...");
while (1)
;
}
Wire.endTransmission(0x70);
}

void loopMux1() {

tcaselect(0); // channel 0 --> SCD30
if (airSensor.dataAvailable())
{
Serial.print("R1 co2(ppm):");
Serial.print(airSensor.getCO2());
// co2=airSensor.getCO2();

Serial.print(" R1 temp(C):");
Serial.print(airSensor.getTemperature(), 1);

// co2temp=airSensor.getTemperature();

Serial.print(" R1 humidity(%):");
Serial.print(airSensor.getHumidity(), 1);

// co2hum=airSensor.getHumidity();
Serial.println();
}

else
// Serial.println("R1 Waiting for new data");
// delay(500);

//***************************************************************************************************

tcaselect(2); // channel 1 --> SCD30
if (airSensor.dataAvailable())
{
Serial.print("R2 co2(ppm):");
Serial.print(airSensor.getCO2());
// co2=airSensor.getCO2();

Serial.print(" R2 temp(C):");
Serial.print(airSensor.getTemperature(), 1);

// co2temp=airSensor.getTemperature();

Serial.print(" R2 humidity(%):");
Serial.print(airSensor.getHumidity(), 1);

// co2hum=airSensor.getHumidity();
Serial.println();
}

else
// Serial.println("R2 Waiting for new data");
delay(1000);

//******************************************************************************************************************

}

//******************************************** MUX 2 *********************************

void setupMux2() {
Wire.beginTransmission(0x71); // join i2c bus (address optional for master)
delay(1000);

Serial.begin(115200); // start serial for output
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}

Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();

Serial.println(F("##############################"));
Serial.println(F("Starting Initialization"));
Serial.println(F("##############################"));

//************* *****************************************************************************************************

tcaselect(0);
////////pressure///////////////
Serial.println(F("R1 BMP280 Sensor event test"));

  if (!bmp.begin()) {
    Serial.println(F("Could not find a valid R1 BMP280 sensor, check wiring!"));
    delay(10);
  }
 

 bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  bmp_temp->printSensorDetails();

tcaselect(1); // channel 1 --> BMP280
////////pressure///////////////
Serial.println(F("R2 BMP280 Sensor event test"));

  if (!bmp.begin()) {
    Serial.println(F("Could not find a valid R2 BMP280 sensor, check wiring!"));
    delay(10);
  }
 

 bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  bmp_temp->printSensorDetails();

Wire.endTransmission(0x71);

}

void loopMux2() {

tcaselect(0); // channel 0 --> BMP
sensors_event_t temp_event, pressure_event;
bmp_temp->getEvent(&temp_event);
bmp_pressure->getEvent(&pressure_event);

Serial.println();
Serial.println();
Serial.print(F("R1 Temperature = "));
Serial.print(temp_event.temperature);
Serial.println(" *C");
//
Serial.println();
Serial.print(F("R1 Pressure = "));
Serial.print(pressure_event.pressure);
Serial.println(" hPa");
//float pressure_pascal=pressure_event.pressure/1000 - 0.90883;
Serial.println();

// array3[1] = temp_event.temperature;
// delay(1000);

tcaselect(1); // channel 1 --> BMP280
// sensors_event_t temp_event, pressure_event;
bmp_temp->getEvent(&temp_event);
bmp_pressure->getEvent(&pressure_event);

Serial.println();
Serial.println();
Serial.print(F("R2 Temperature = "));
Serial.print(temp_event.temperature);
Serial.println(" *C");
//
Serial.println();
Serial.print(F("R2 Pressure = "));
Serial.print(pressure_event.pressure);
Serial.println(" hPa");
//float pressure_pascal=pressure_event.pressure/1000 - 0.90883;
Serial.println();

// array3[1] = temp_event.temperature;
delay(1000);

}

//******************************************** MUX 3 *********************************

void setupMux3() {
Wire.beginTransmission(0x72); // join i2c bus (address optional for master)
delay(1000);

Serial.begin(115200); // start serial for output
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(300);
}

Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();

Serial.println(F("##############################"));
Serial.println(F("Starting Initialization"));
Serial.println(F("##############################"));

//************* *****************************************************************************************************

tcaselect(0);
ina219.begin();
ina219.setCalibration_16V_400mA(); // set measurement range to 16V, 400mA

tcaselect(1); // channel 1 --> BMP280
ina219.begin();
ina219.setCalibration_16V_400mA(); // set measurement range to 16V, 400mA

Wire.endTransmission(0x72);

}

void loopMux3() {

tcaselect(0); // channel 0 --> INA219
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);

Serial.println();
Serial.println();
Serial.print("R! Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("R1 Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.println("");
Serial.println();
Serial.println();
array1[0] = busvoltage;
array1[1] = shuntvoltage;
array1[2] =loadvoltage;
array1[3] = current_mA;

tcaselect(1); // channel 1 --> INA219
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);

Serial.println();
Serial.println();
Serial.print("R2 Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("R2 Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.println("");
Serial.println();
Serial.println();
array1[0] = busvoltage;
array1[1] = shuntvoltage;
array1[2] =loadvoltage;
array1[3] = current_mA;

}

On each TCA9548A there are three address pins, these should be set high or low and represent the three least significant bits of the address. This means you can set a TCA9548A to have one of eight different addresses.

I am assuming you don’t have a TCA9548A chip but a board with one of those chips on it, so changing the address will be a matter of either soldering links or cutting links on the board.

I would use much simpler code until you get this working.

Please edit your post and put your sketch between code tags. Use the </> button or put your sketch between lines with three backslash-single-quotes or in the Arduino IDE select "copy for forum".

```
Your sketch
```

It is hard for us to read your sketch if you don't do that. If you don't know how to put your sketch between code-tags, please ask.

Try this enhanced version of tcaselect():

void tcaselect(uint8_t i) {

  byte address = TCAADDR;
  static byte previousAddress = 0x99;

  while (i > 7) {
    i -= 8;
    address++;
    }

  if (address != previousAddress) {
    if (previousAddress != 0x99) {
      Wire.beginTransmission(previousAddress);
      Wire.write(0);
      Wire.endTransmission();
      }
    previousAddress = address;
    }

  Wire.beginTransmission(address);
  Wire.write(1 << i);
  Wire.endTransmission();
}

With this version, you can give channels higher than 7. It will automatically enable the relevant tca chip's channel for you. For example if you write "tcaselect(9);" it will enable channel 1 of the 2nd tca chip (the chip with address 0x71).

To make your code easier to write, you should use all 8 channels of each tca chip before using the next tca chip, so the tca chips with addresses 0x70 and 0x71 have 8 sensors and the chip with address 0x72 has only 2 sensors.

HI PaulRB,

Thank you very much for your solution. I will definitely try it out. Are there any other changes in the code I should make? Like in the Sensor initialising part or in the void loop? Apologies for my silly questions, I'm pretty new to this and this is a very big deal for me at this stage.

Also, for your suggestion to use all 8 channels for each tca, I have tried similar thing with a tca connected 3 different sensors with different i2c addresses, But I can only read out the value of one sensor. So thought of trying out similar sensors connected to one tca.

Please reply on the forum topic, not by personal message.

Yes, there are several other changes to be made. I hope my code above will help you make those other changes more easily. If this a problem for you, then make an attempt, post it, and ask for more help, explaining what problems you have encountered.

However, I will only be offering more help after you have fixed your first post, which is breaking forum rules, and if you then continue to follow the forum guide.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.