Getting wrong values when reading data from sensors with i2C TCA9548A i2C multiplexer getting bad values from BMP180 sensors multuplexer TCA9548A

Hello,

I am using a TCA9548A i2c multiplexer to read data from 4 BMP180 sensors.
Everything seems to be connected properly, as I am getting data, but the data are not correct (except for one sensor).

I have check the sensors one by one, there are working correctly.

I have tried to add "delay" in my code, but it doesn't change anything.

Does anyone know how to solve this issue?

Thank you


#include <Wire.h>
#include <SFE_BMP180.h>

  SFE_BMP180 pressure_0;
  SFE_BMP180 pressure_1;
  SFE_BMP180 pressure_2;
  SFE_BMP180 pressure_3;


#define TCAADDR 0x70
  void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

void setup() {
  Serial.begin(9600);
  Wire.begin();
          
  Serial.println("Starting Initialization");     
 
pressure_0.begin();
   delay(100);
pressure_1.begin();
   delay(100);
pressure_2.begin();
   delay(100);
pressure_3.begin();

Serial.println("Initialization Finished");


}

void loop() 
{ 
    delay(1000);
   tcaselect(0);
  char status;
  double T0,P0;

  status = pressure_0.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    status = pressure_0.getTemperature(T0);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("T0: ");
      Serial.print(T0,2);
    Serial.print(" °C, ");

      status = pressure_0.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        status = pressure_0.getPressure(P0,T0);
        if (status != 0)
        {
          Serial.print("P0: ");
          Serial.print(P0,2);
          Serial.println(" mb ");
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");   
   delay(1000);   

   tcaselect(1);
  
  double T1,P1;

  status = pressure_1.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    status = pressure_1.getTemperature(T1);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("T1: ");
      Serial.print(T1,2);
    Serial.print(" °C, ");

      status = pressure_1.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        status = pressure_1.getPressure(P1,T1);
        if (status != 0)
        {
          Serial.print("P1: ");
          Serial.print(P1,2);
          Serial.println(" mb, ");

        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");

   delay(1000);   
   
    tcaselect(2);
;
  double T2,P2;

  status = pressure_2.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    status = pressure_2.getTemperature(T2);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("T2: ");
      Serial.print(T2,2);
    Serial.print(" °C, ");

      status = pressure_2.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        status = pressure_2.getPressure(P2,T2);
        if (status != 0)
        {
          Serial.print("P2: ");
          Serial.print(P2,2);
          Serial.println(" mb, ");

        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");
delay(1000); 
       
  tcaselect(3);

  double T3,P3;

  status = pressure_3.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    status = pressure_3.getTemperature(T3);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("T3: ");
      Serial.print(T3,2);
    Serial.print(" °C, ");

      status = pressure_3.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        status = pressure_3.getPressure(P3,T3);
        if (status != 0)
        {
          Serial.print("P3: ");
          Serial.print(P3,2);
          Serial.println(" mb, ");

        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");
  
  Serial.println();

   delay(1000);   
 
}

In french:
Bonjour,
j'utilise un i2c multiplexer pour lire les donner de 4 capteurs BMP180. Tout semble correctement branché. J'obtiens de données mais sont erronées.

(voir image) Seul un des capteurs semble donner des valeurs plausibles. J'ai testé les capteurs un par un. Ils donnent des résultats corrects.

J'ai essayé d'ajouter des "delay" dans mon code, me disant que la ligne SDA est peut-être "embouteillée. ça ne change rien.

Est-ce que quelqu'un a une idée?

Merci

Olivier

Rewrite your code to use the same procedure for each sensor.
for (byte tca = 0; tca < maxtca; tca++) { tcaselect(tca); ... }

Thank your answer,

I have the feeling it will help but I am sorry, I don't understand your advice.
Can you please precise?

thank you very much

Which of the sensors is working?

Follow the DRY principle: Don't Repeat Yourself.

Write code once for one sensor, then instead of copy&paste that code for every further sensor of the same type make your code work with any number of sensors. In a for loop the index variable indicates the currently active sensor number. What else must be known to distinguish multiple sensors?

DRY ^^
I think I get it you something like that?


#include <Wire.h>
#include <SFE_BMP180.h>

  SFE_BMP180 pressure;
//  SFE_BMP180 pressure_1;
//  SFE_BMP180 pressure_2;
//  SFE_BMP180 pressure_3;



#define TCAADDR 0x70
  void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

int maxtca=4; // nombre de voies utilisées

void setup() {
  Serial.begin(9600);
  Wire.begin();
          
  Serial.println("Starting Initialization");     
 
pressure.begin();
//   delay(100);
//pressure_1.begin();
//   delay(100);
//pressure_2.begin();
//   delay(100);
//pressure_3.begin();

Serial.println("Initialization Finished");


}

void loop() 
{ 
  char status;
for (byte tca = 0; tca < maxtca; tca++) { tcaselect(tca); 
  double T,P;

  status = pressure.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    status = pressure.getTemperature(T);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("BMP: ");
      Serial.print(tca,1);
      Serial.print(" _ T: ");
      Serial.print(T,2);
    Serial.print(" °C, ");

      status = pressure.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          Serial.print("P: ");
          Serial.print(P,2);
          Serial.println(" mb ");
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");   
 };  
    

   delay(1000);   
 
}

This "works" but it doesn't change the results

TCA9548A and BMP1802

It seems that the last sensor is giving a good result

Thankyou for using code tags.

Please perform Tools-->Auto Format in the IDE each time before you post code.

Please do not post images of the serial monitor. Copy the text from serial monitor and paste it into your post, inside code tags.

I think maybe you need one object per sensor, maybe you cannot share the same object for 4 sensors.

Make an array of SFE_BMP180 objects like this:

const int maxtca=4; // nombre de voies utilisées

SFE_BMP180 pressure[maxtca];

and initialise them in setup:

for (byte tca = 0; tca < maxtca; tca++) {
  tcaselect(tca); 
  pressure[tca].begin();
}

And read them like this

status = pressure[tca].startTemperature();
...
status = pressure[tca].getTemperature(T);

And from looking at you code it is reasonable to see why only one sensor, #3, is giving the correct values. Follow the advice given in Post#2, #5, and #9 to fix your issue.

Look at your own code and see why "3" "3" "3" seems to work but not "0" or "1" or "2" there is only "3" "3" "3".

Thank you very much guys! PaulRB articularly!
It works :wink:

final code:


#include <Wire.h>
#include <SFE_BMP180.h>
 
#define TCAADDR 0x70
  void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

 const int maxtca=4; // nombre de voies utilisées


//SFE_BMP180 pressure[tca];
//SFE_BMP180 pressure[0];
//SFE_BMP180 pressure[1];
//SFE_BMP180 pressure[2];
//SFE_BMP180 pressure[3];

SFE_BMP180 pressure[maxtca];

void setup() {
  Serial.begin(9600);
  Wire.begin();
          
  Serial.println("Starting Initialization");     


for (byte tca = 0; tca < maxtca; tca++) {
  
  tcaselect(tca); 
  //Serial.println(tca);  
  pressure[tca].begin();
}
 
//pressure.begin();
//   delay(100);
//pressure_1.begin();
//   delay(100);
//pressure_2.begin();
//   delay(100);
//pressure_3.begin();

Serial.println("Initialization Finished");


}

void loop() 
{ 
  char status;
for (byte tca = 0; tca < maxtca; tca++) { tcaselect(tca); 
  double T,P;

  status = pressure[tca].startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    status = pressure[tca].getTemperature(T);
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("BMP: ");
      Serial.print(tca);
      Serial.print(" _ T: ");
      Serial.print(T,2);
    Serial.print(" °C, ");

      status = pressure[tca].startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        status = pressure[tca].getPressure(P,T);
        if (status != 0)
        {
          Serial.print("P: ");
          Serial.print(P,2);
          Serial.println(" mb ");
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");   
 };  
    
Serial.println("  ");
   delay(1000);   
 
}



and serial monitor:

09:33:56.430 -> Starting Initialization
09:33:56.465 -> Initialization Finished
09:33:56.465 -> BMP: 0 _ T: 21.15 °C, P: 1018.10 mb 
09:33:56.535 -> BMP: 1 _ T: 22.74 °C, P: 1021.37 mb 
09:33:56.570 -> BMP: 2 _ T: 22.46 °C, P: 1016.75 mb 
09:33:56.605 -> BMP: 3 _ T: 24.05 °C, P: 1016.50 mb 
09:33:56.640 ->   
09:33:57.585 -> BMP: 0 _ T: 21.15 °C, P: 1018.06 mb 
09:33:57.655 -> BMP: 1 _ T: 22.74 °C, P: 1021.38 mb 
09:33:57.690 -> BMP: 2 _ T: 22.44 °C, P: 1016.66 mb 
09:33:57.725 -> BMP: 3 _ T: 24.05 °C, P: 1016.51 mb 
09:33:57.760 ->   
09:33:58.740 -> BMP: 0 _ T: 21.15 °C, P: 1018.06 mb 
09:33:58.775 -> BMP: 1 _ T: 22.74 °C, P: 1021.41 mb 
09:33:58.810 -> BMP: 2 _ T: 22.46 °C, P: 1016.75 mb 
09:33:58.845 -> BMP: 3 _ T: 24.02 °C, P: 1016.42 mb 

Well done!

+1 for posting serial monitor output inside code tags.

-1 for not auto formatting your code.

ahah sorry,
I will try to think about it next time!