TCA9548A I2C Multiplexer with Omron pressure sensors

Hey guys,

I am trying to measure the pressure in a wind tunnel using a multiplexer TCA9548A I2C Multiplexer and multiple pressure sensors D6F-PH5050AD3 & D6F-PH0025AD1. For the beginning I want to measure with 2 sensors (1 of each type). As soon as I get reasonable results, I want to extend this to multiple sensors. I soldered the pins to the multiplexer and ran a scanner sketch which finds the two sensors. So the connection should work. There is no real reason, why I used Port 2 and 3 for this example.

grafik

Now I have the problem that I am a beginner and do not get along with the programming. I use the code below for the measurement with the individual sensors. I have found examples of the code with multiplexer and other sensors, but can not transfer them to my case. Can someone help me? I am using an Arduino ATMEGA btw. But I could also switch to an Uno if that does make a difference.

#include "Wire.h"
#define addrs 0x6C // I2C bus address
int P;
int I;
float T;

int initialize(int i2c_addr)
{
  //INITIALIZATION AFTER POWER UP
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x0B);  
  Wire.write(0x00); 
  int x = Wire.endTransmission(); 
  return x;
}

int pressure(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte 
//  Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission(); 

  delay(33);

  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x51);
  Wire.write(0x2C);
  x = Wire.endTransmission(); 
  
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission(); 

  Wire.requestFrom(i2c_addr, 2);
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte);  
  //Serial.print("raw pressure:\t ");
  //Serial.println(raw); 
  
  // D6F-PH5050AD3 ==> rangeMode=500 ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0505AD3 ==> rangeMode=50  ==> int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode
  // D6F-PH0025AD1 ==> rangeMode=250 ==> int rd_pressure=(raw - 1024) * rangeMode / 60000L
  int rangeMode = 50;
  int rd_pressure =  ((raw - 1024) * rangeMode * 2 / 60000L) - rangeMode;
  return rd_pressure;
}

float temperature(int i2c_addr)
{
  //MCU MODE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);  // reg 0 - address register high byte 
  // Wire.write(0x51);  // reg 1 - address register low byte
  Wire.write(0x40);  // reg 1 - address register low byte  
  Wire.write(0x18);  // reg 2  - serial control register - indicate # bytes among others (page 7 bottom)
  Wire.write(0x06);  // reg 3 - value to be written to SENS control register
  int x = Wire.endTransmission(); 

  delay(33);
  
  //WRITE
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x00);   
  Wire.write(0xD0);
  Wire.write(0x61);
  Wire.write(0x2C);
  x = Wire.endTransmission(); 
  
  //READ
  Wire.beginTransmission(i2c_addr);
  Wire.write(0x07);
  x = Wire.endTransmission(); 

  Wire.requestFrom(i2c_addr, 2);  
  byte hibyte = Wire.read();
  byte lobyte = Wire.read();
  long raw = word( hibyte, lobyte);  
  //Serial.print("raw temperature:\t ");
  //Serial.println(raw); 
  int temp = round((float)(raw - 10214) / 3.739);  // this is the temperature multiplied by 10...
  return (temp/10.0);                      // ...and the function returs the float temperature with 0.1°C resolution
}

void setup()
{  // Open serial communications 
 Wire.begin();
  Serial.begin(9600);
 I=initialize (addrs); // start wire connection

}

void loop()
{
    P=pressure(addrs);
    Serial.print("pressure:\t ");
    Serial.println(P);
    T=temperature(addrs);
    Serial.print("temperature:\t ");
    Serial.println(T);
    delay(30000); //delay for 30 seconds

}

The example you posted seems to not use a multiplexer. Can you post your attempt to use the multiplexer code? It's more relevant to your need.

The scanning sketch you ran to produce the debug listing above must interface the multiplexer, are there no example sketches with that software to actually access devices via the multiplexer?

Basically, I am wondering whether you have fully explored the resources that you have already downloaded...

Manufacturer's page with all the documents: http://components.omron.eu/Product-details/D6F-PH
The I2C register description is in the "Technical Information Datasheet".

The Arduino Mega 2560 is a 5V Arduino board with a 5V I2C bus.
The pressure sensor is a 3.3V sensor with a 3.3V I2C bus.
The TCA9548A can translate those levels when powered with 3.3V. Do you have that ?
Do you use the TCA9548A chip, or a module ?

What kind of wires or cable do you use for the I2C bus ? How long are they ?

Do you have pullup resistors on the (sub) I2C bus that is connected to the sensor ? What value ?

In the datasheet is a repeated start when reading data. Your sketch does not have that.

Here are two pictures of my setup. First the setup for measuring with 1 sensor (which gave me reasonable results)

And then my setup for measuring with 2 sensors.

I'm using 20cm jumper cables and 2kOhm resistors. I can adjust this setup when I do the measurements and I can compare the results.

But to perform measurements at all I need the right programming. And I read everything I have as data, but since I'm a beginner and I really dont know how to start programming this, I need your help.
I tried around with other sketches I found online, but I can't transfer them to my sensors. So it is unnecessary to post my attempts here, as they are probably pretty garbage.

The resistors are too low in value. I prefer 10k (or perhaps 4k7) and none on the Arduino Mega side (it has already 10k onboard pullup resistors).
I'm not 100% sure how the TCA9548A behaves when it opens a I2C channel. If you can not find 10k resistors, then you can measure the maximum sink current of the I2C bus.

In your first setup, the onboard 10k pullup resistors leak current from the 5V into the sensor. That means that your sensor is no longer reliable and can be damaged. Do you know which one you used for that test ?

My suggestion: Start with one sensor, but keep the TCA9548A as level translator. Open the first I2C channel, and make a sketch or find a library for your sensors.

Did you read the Adafruit tutorial: https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout.
Use the code from that, to select the first channel.

Open the Library Manager in the Arduino IDE, search for: omron
Install the library. This is the library: https://github.com/bitixel/Omron_D6FPH
Use the example.

The first part of your sketch could look like this:

// Library: https://github.com/bitixel/Omron_D6FPH

#include <Wire.h>
#include <Omron_D6FPH.h>

Omron_D6FPH mySensor;

#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( 115200);      // or 9600, set the Serial Monitor to the same value.
  Serial.println( "The sketch has started");
  Wire.begin();         // Start the I2C bus
  tcaselect( 0);         // select the first I2C bus

  // From now on, the first sensor is connected to the I2C bus.

  mySensor.begin(MODEL_5050AD3);
}

Show your sketch and tell what it does.
Please also tell what you did about those 2k2 pullup resistors.