TCA9548A i2c scanner not detecting i2c slave (allsensor DLHR)

After few tries, I am still struggling to detect the i2c All sensor DLHR I have (0x29) using various i2c scanners.

My i2c devices works well using a simple i2c scanner
tca9548a detected as 0x70
MPU6050 as 0x68
DLHR as 0x29.

I have then hooked up the i2c devices on the different tca9548a ports:
using the TCAA4598 i2c multiplex scanner, I can detect the MPU6050 but not the DLHR pressure sensor.

note the MPU6050 is used just there to check if the i2c addresses are detected.

I am using the Allsensors_DLHR library from GitHub - jeremycole/AllSensors_DLHR: Arduino library for the AllSensors DLHR Series Low Voltage Digital Pressure Sensors.

Does anyone would be able to help me with this ?

What if you hook them to the same port?

The idea is to multiplex the DLHR which have a fixed i2c address, so I am not intending to have more than 1 device attached to the same port.

however, when both hooked on the same i2c bus, both i2c address are detected :astonished: I am confused .

So here is a piece of code.

#include <Arduino.h>
#include <Wire.h>
#include <AllSensors_DLHR.h>

#define TCAADDR 0x70

AllSensors_DLHR_F05D_8 gagePressure(&Wire);

void tcaselect(uint8_t i);

void setup() {
    Wire.begin();
    Serial.begin(115200);
    gagePressure.setPressureUnit(AllSensors_DLHR::PressureUnit::PASCAL);
}

void loop() {
     for (uint8_t t=0; t<8; t++){
      tcaselect(t); 
      Serial.print("TCA Port #"); Serial.print(t);
      for (uint8_t addr = 0; addr<=127; addr++) {
        if (addr == TCAADDR) continue;
        Wire.beginTransmission(addr);
        if (!Wire.endTransmission()) {
          Serial.print("Found I2C 0x");  Serial.println(addr,HEX); Serial.print("\t");
        }
      }
      Serial.println("");
    }

  delay(1000);


  Serial.println("\n\nTrying Measurement\n\n");


  tcaselect(1);
    gagePressure.startMeasurement();
    gagePressure.readData(true);

  Serial.print("Pressure: ");
  Serial.print(gagePressure.pressure);
  Serial.print(" Temperature: ");
  Serial.println(gagePressure.temperature);
  Serial.print("\n\n");
  delay(100);
}

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

When the MPU6050 is plugged on the same port, I am able to communicate and retriev temperature and pressure, when I disconnect the MPU6050, the DLHR is no more detected.

Maybe the MPU-6050 is actually a module with the sensor and pullup resistors. Maybe the DLHR sensor does not have pullup resistors.

Which Arduino board do you use ? The DLHR sensor is a 3.3V sensor, and it is better to not apply SDA and SCL from a 5V Arduino board to it.

Can you give links to all the I2C modules or show of photo with them ?

Did you know that your MPU-6050 could be fake ?

I think that you should use the tcaselect() also in setup(). The sensor functions in setup() might already communicate with the sensor (maybe not for this sensor, but for most others sensors they do).

I am using a Uno and I am powering everything to 3.3V.
I had a try with 10kOhm resistors and did not work.
the DLHR sensor datasheet is here: http://www.allsensors.com/datasheets/DS-0350_Rev_C.pdf
the chips I have are DLHR-F50D-E1BD-I-NAV8 (so package and pinout is given p15). I dont see if they have pull up resistors.

It will be easier to us when you show what you really have, photos, schematics, links to modules and so on. You are looking at something, and we have to guess what you have.

Do you have the SS pin of the DLHR sensor set high ? So it does not accidentally go into SPI mode.

The I2C multiplexer needs pullup resistors between the Arduino and the I2C multiplexer and also on every (sub) I2C bus.
The Arduino Uno has very weak internal pullup resistors, that might not be enough. The I2C multiplexer module has probably 10k pullup resistors on the Arduino side, but they can sometimes be enabled or disabled and they connect to 3.3V. I suggest to disable those and add 10k external pullup to 5V for the Arduino side.
The MPU-6050 module probably has pullup resistors.
If you tried with 10k pullup, then it should work. You need those anyway, so please keep them to pullup the (sub) I2C bus.

Looks like something is wrong with your hardware, most probably missing pullup resistors. Each (used) port of the multiplexer must have pullup resistors on SCL and SDA. The pullups must connect to the supply voltage used by the I2C modules of that port.

I'd try at most 3k3 so that at least 1mA current flows in the active state.

Thank you, the 3.3kOhm resistor allows the detection!

I've tried a 1.1k, 3.9k, and 10k pulldown but I still can't get access to the device on the SD0/SC0. I'm using a MPU6050 and was expecting to see 0x70 (of the multiplexer) and 0x68 (of the MPU6050). When I run the scan sketch I can see the 0x70 but nothing else.

After watching about 10 tutorial and reading 2 dozen posting on how to hook this up, there is nothing wrong with my circuit. Is it possible the sketch or compiler is missing a library preventing it from communicating properly?

#include <Wire.h>
#include <i2cdetect.h>

#define AD0 4   // GPIO4
#define AD1 2   // GPIO2
#define AD2 15  // GPIO15

int multiplexer[8][3] = { {LOW,LOW,LOW},      //0x70
                          {HIGH,LOW,LOW},     //0x71   
                          {LOW,HIGH,LOW},     //0x72
                          {HIGH,HIGH,LOW},    //0x73
                          {LOW,LOW,HIGH},     //0x74
                          {HIGH,LOW,HIGH},    //0x75
                          {LOW,HIGH,HIGH},    //0x76
                          {HIGH,HIGH,HIGH}    //0x77
                          };
uint8_t address[8] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77 };

uint8_t bus;

int channel = 0;

void setup() {
  
pinMode(AD0, OUTPUT);
pinMode(AD1, OUTPUT);
pinMode(AD2, OUTPUT);



Serial.begin(115200);
  
  Wire.begin();
  
  Serial.println("i2cdetect example\n");
  Serial.print("Scanning address range 0x03-0x77\n\n");
}

void loop() {

  Serial.println(channel);
  
  digitalWrite(AD0, multiplexer[channel][0]);
  digitalWrite(AD1, multiplexer[channel][1]);
  digitalWrite(AD2, multiplexer[channel][2]);
  
  i2cdetect();  // default range from 0x03 to 0x77
/*
  Wire.beginTransmission(address[channel]);  // TCA9548A address
  Wire.write(1 << bus);          // send byte to select bus
  Wire.endTransmission();
  Serial.print(bus);
  */
  delay(2000);
  
  
  channel += 1 ; // increment the channel
  if (channel > 7) channel = 0; // reset the counter when at the end of the row
}

I2C requires pullup resutors on both sides of the multiplexer.

Thanks...yes...pull-up. It wasn't the problem.
I'm running it now without a pull(up/down) on either side and its working.
The problem was software.

I'm not a programmer by profession so I have no way to explain why this solution works.
This code snippet placed below Wire.setClock(clk); the devices become available on the bus.

  Wire.beginTransmission(0x70);  // TCA9548A address
  Wire.write(1 << 0);          // send byte to select bus
  Wire.endTransmission();

Obviously, its sending a byte to the device, but why it wakes up the device or initiates communication is a mystery. I'll be improving the code so that the address can be switched out for all channels as it loops. More on this later. I may edit my previous posts so that its more concise and useful to readers.

update

This would be a loopable portion of the code to work with the scanner.

  Wire.beginTransmission(address[channel]);  // TCA9548A address
  Wire.write(1 << channel);          // send byte to select bus
  Wire.endTransmission();

It's a misunderstanding. Channel 0 is enabled, nothing is sent to any channel. You have to enable the selected channel(s) before device scanning or data transmission.

So by enabled you mean:

  Wire.beginTransmission(address[channel]);  // TCA9548A address
  Wire.write(1 << channel);          // send byte to select bus
  Wire.endTransmission();

because without this bit of code...it doesn't work. There is no other code that I see which "enables" the device(s).

Here's the updated sketch:

#include <Wire.h>
#include <i2cdetect.h>

#define AD0 4   // GPIO4
#define AD1 2   // GPIO2
#define AD2 15  // GPIO15

int multiplexer[8][3] = { {LOW,LOW,LOW},      //0x70
                          {HIGH,LOW,LOW},     //0x71   
                          {LOW,HIGH,LOW},     //0x72
                          {HIGH,HIGH,LOW},    //0x73
                          {LOW,LOW,HIGH},     //0x74
                          {HIGH,LOW,HIGH},    //0x75
                          {LOW,HIGH,HIGH},    //0x76
                          {HIGH,HIGH,HIGH}    //0x77
                          };
uint8_t address[8] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77 };

uint8_t bus;

int channel = 0;

void setup() {
  
pinMode(AD0, OUTPUT);
pinMode(AD1, OUTPUT);
pinMode(AD2, OUTPUT);



Serial.begin(115200);
  
  Wire.begin();
  
  Serial.println("i2cdetect example\n");
  Serial.print("Scanning address range 0x03-0x77\n\n");
}

void loop() {

  Serial.println(channel);
  
  digitalWrite(AD0, multiplexer[channel][0]);
  digitalWrite(AD1, multiplexer[channel][1]);
  digitalWrite(AD2, multiplexer[channel][2]);

  Wire.beginTransmission(address[channel]);  // TCA9548A address
  Wire.write(1 << channel);          // send byte to select bus
  Wire.endTransmission();
  
   i2cdetect();  // default range from 0x03 to 0x77
 
  delay(2000);
  
  
  channel += 1 ; // increment the channel
  if (channel > 7) channel = 0; // reset the counter when at the end of the row
}

That's crap, the multiplexer address pins have to be fixed with ever chip so that it gets a unique I2C address.

You still don't understand how such a multiplexer works :frowning:

Oh...you're one of those smart fellers. Apparently, I DO! Because it works like a charm. Maybe you should TRY IT YOURSELF before pontificating what you don't know or can prove.

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