Wrong sensor data using 2 multiplexers

Hi everyone,
I'm working on a project where I need to connect 20 BMP280 pressure sensors to 3 TCA9548A multiplexers to collect and analyze data. However, for now, I'm focusing on just 2 multiplexers. I'am using the redboard from Sparkfun.

The problem I'm encountering is that when I use the second multiplexer, the pressure readings from the sensors on both multiplexers are identical when using the same port.

#include <Wire.h>
#include <Adafruit_BMP280.h>

// Define the number of sensors per multiplexer
#define NUMBER_OF_SENSORS_BMP280_MUX1 1 // Number of BMP280 sensors
#define NUMBER_OF_SENSORS_BMP280_MUX2 1  // BMP280 sensors on the 2nd multiplexer

#define MUX1_ADDR 0x70  // Address of first multiplexer
#define MUX2_ADDR 0x71  // Address of second multiplexer

int counter = 0;
Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1]; // BMP280 sensors
Adafruit_BMP280 bmp281[NUMBER_OF_SENSORS_BMP280_MUX2];

// Function to control the TCA9548A multiplexer (with address)
void selectMultiplexer(uint8_t muxAddress, uint8_t bus) {
  if (bus > 7) return; // Bus must be between 0 and 7
  Wire.beginTransmission(muxAddress); // TCA9548A address
  Wire.write(1 << bus); // Select the bus
  
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);
  Wire.setClock(400000); // I2C clock speed
  Wire.begin();

  // Initialize the sensors on the 1st multiplexer (address 0x70)

  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    selectMultiplexer(MUX1_ADDR, i); // Select the bus
    if (!bmp280[i].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on port ");
      Serial.println(i);
    } else {
      Serial.print("BMP280 sensor initialized on port ");
      Serial.println(i);
    }
    //selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
  }

  // Initialize the sensors on the 2nd multiplexer (address 0x71)

  for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
    selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer
    if (!bmp281[x].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on the 2nd mux, port ");
      Serial.println(x);
    } else {
      Serial.print("BMP280 sensor initialized on the 2nd mux, port ");
      Serial.println(x);
    }
    //selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
  }
}

void loop() {
  String output = ""; // Declare the output string

  // Read BMP280 sensors on the 1st multiplexer
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    selectMultiplexer(MUX1_ADDR, i); // Select the bus

    float pressure = bmp280[i].readPressure(); // Read data from BMP280 sensor
    Serial.print("Mux1 port");
    Serial.print (i);
    Serial.print(" ");
    Serial.print(pressure);
    Serial.print(" ");
    //selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
  }

  // Read BMP280 sensors on the 2nd multiplexer
  for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
    selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer

    float pressure = bmp281[x].readPressure(); // Read data from BMP280 sensor
    Serial.print("Mux2 port ");
    Serial.print (x);
    Serial.print(" ");
    Serial.print(pressure);
    //selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
  }

  Serial.println(output); // Print the results
  delay(100);

  counter++; // Increment the counter
  if (counter >= 10) {
    while (1); // Infinite loop after 30 readings
  }
}

How is it wired? Please post schematics.

You got the right idea here. Unless you turn off MUX1 before you select a channel of MUX2, you will have 2 sensors on the bus with the same address, which either not work at all, or will give the reading from one of the 2 sensors at random.

Unfortunately, you cannot simply un-comment those lines. The selectMultiplexer() function will do nothing if the parameter is > 7. You need to amend selectMultiplexer() function also so that when it receives 0xFF it sends zero to the multiplexer which will disable all channels.

Maybe like this

// Function to control the TCA9548A multiplexer (with address)
void selectMultiplexer(uint8_t muxAddress, uint8_t bus) {
  uint8_t busMask = 0;
  if (bus < 8) busMask = 1 << bus; // Bus must be between 0 and 7, otherwise all channels will be disabled
  Wire.beginTransmission(muxAddress); // TCA9548A address
  Wire.write(busMask); // Select the bus
  
  Wire.endTransmission();
}

I don't think it's necessary. My wiring is good the problem come from my code. As PaulRB said I have 2 sensors with the same adress on the same bus.

If you were wondering I do have set the A0 of the second mux on Vcc and A1, A2 are on ground.

I changed this part on the code. And now, I receive data from the first sensor of MUX1 but receive Nan value from the second sensor of MUX2.

Ok, but I don't know what changes you made. Did you try my suggested changes?

Either way, if you want help, post the updated code. A schematic would also help us to help you.

How did You verify it?

1 Like

Hi, @khris2026

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Please not a Fritzy cut and paste picture.

Thanks Tom.. :smiley: :+1: :coffee: :australia:

1 Like

Please read this post (pinned to the top of every category on this forum):

Specifically this:
How to get the best out of this forum:

1 Like

Here is my circuit since a lot of you asked it. I'am using a Redborad instead of arduino UNO because I could not find it on fritzing. This is an axample with only 2 sensors an 2 MUX.

1 Like

I verified it using just 1 MUX. Then I added the second MUX.

Here is the updated code and you can find the schematic above.

#include <Wire.h>
#include <Adafruit_BMP280.h>

// Define the number of sensors per multiplexer
#define NUMBER_OF_SENSORS_BMP280_MUX1 1 // Number of BMP280 sensors
#define NUMBER_OF_SENSORS_BMP280_MUX2 1  // BMP280 sensors on the 2nd multiplexer

#define MUX1_ADDR 0x70  // Address of first multiplexer
#define MUX2_ADDR 0x71  // Address of second multiplexer

int counter = 0;
Adafruit_BMP280 bmp280[NUMBER_OF_SENSORS_BMP280_MUX1]; // BMP280 sensors
Adafruit_BMP280 bmp281[NUMBER_OF_SENSORS_BMP280_MUX2];

// Function to control the TCA9548A multiplexer (with address)
void selectMultiplexer(uint8_t muxAddress, uint8_t bus) {
  uint8_t busMask = 0;
  if (bus < 8) busMask = 1 << bus; // Bus must be between 0 and 7, otherwise all channels will be disabled
  Wire.beginTransmission(muxAddress); // TCA9548A address
  Wire.write(busMask); // Select the bus
  
  Wire.endTransmission();
}

void setup() {
  Serial.begin(115200);
  Wire.setClock(400000); // I2C clock speed
  Wire.begin();

  // Initialize the sensors on the 1st multiplexer (address 0x70)

  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    selectMultiplexer(MUX1_ADDR, i); // Select the bus
    if (!bmp280[i].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on port ");
      Serial.println(i);
    } else {
      Serial.print("BMP280 sensor initialized on port ");
      Serial.println(i);
    }
    selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
  }

  // Initialize the sensors on the 2nd multiplexer (address 0x71)

  for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
    selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer
    if (!bmp281[x].begin(0x76)) { // Initialize the BMP280 sensor
      Serial.print("Could not find BMP280 sensor on the 2nd mux, port ");
      Serial.println(x);
    } else {
      Serial.print("BMP280 sensor initialized on the 2nd mux, port ");
      Serial.println(x);
    }
    selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
  }
}

void loop() {
  String output = ""; // Declare the output string

  // Read BMP280 sensors on the 1st multiplexer
  for (byte i = 0; i < NUMBER_OF_SENSORS_BMP280_MUX1; i++) {
    selectMultiplexer(MUX1_ADDR, i); // Select the bus

    float pressure = bmp280[i].readPressure(); // Read data from BMP280 sensor
    Serial.print("Mux1 port");
    Serial.print (i);
    Serial.print(" ");
    Serial.print(pressure);
    Serial.print(" ");
    selectMultiplexer(MUX1_ADDR, 0xFF); // Disable the bus
  }

  // Read BMP280 sensors on the 2nd multiplexer
  for (byte x = 0; x < NUMBER_OF_SENSORS_BMP280_MUX2; x++) {
    selectMultiplexer(MUX2_ADDR, x); // Select the bus on the 2nd multiplexer

    float pressure = bmp281[x].readPressure(); // Read data from BMP280 sensor
    Serial.print("Mux2 port ");
    Serial.print (x);
    Serial.print(" ");
    Serial.print(pressure);
    selectMultiplexer(MUX2_ADDR, 0xFF); // Disable the bus
  }

  Serial.println(output); // Print the results
  delay(100);

  counter++; // Increment the counter
  if (counter >= 10) {
    while (1); // Infinite loop after 30 readings
  }
}

Then verify it for the second mux.

Ok, thanks, I can't immediately see any problems with your code or wiring.

Have you tried swapping over the sensors?

Have you tried swapping over the multiplexers?

Make only single, small, individual changes at one time and test before making other changes.

1 Like

Try commenting that out.

I might have spotted a problem with your circuit.

Looking at the internal schematic of your sensors


The pull-ups on the left side here connect to the Vcc (=Vin) pin. But your Vin pins are not connected to anything.

The sensor boards have built-in 3.3V regulator and 5V-3.3V level shifters, so it's safe to power all components with 5V from the Uno instead of 3.3V. Use the Vin pins, not the 3V3 pins when powering the sensors.

1 Like

What do you think I am trying to do ?

Thanks for helping me ! Both sensors on each MUX are working. I did the wiring again and it works now. Now I will add the third MUX and all the sensors and see if it works.

1 Like

Do you understand you only need 2 multiplexers for 20 sensors?

1 Like

Yes that's right, I can change the adress of the sensors. Thanks

1 Like