I2C Multiplexer with MS5803_05 Pressure Sensors - Memory Issue?

Hi,

I'm fairly novice with programming and I am hoping that someone can help me with a challenge that I'm facing with my project. (I also hope that I've posted this in the correct group)

I am trying to connect three pressure sensors to an I2C Multiplexer using a Seeeduino.
I have been able to successfully read data individually with another setup that includes the sensors, but I cannot seem to get the same results using this multiplexer.

I have adapted some code from the TCA9548A documentation as well as code for the pressure sensors.
My first guess is that I have a memory issue, because all of the values that I receive are the same. What is also curious is that when I unplug the power cable, the values continue to roll through the serial monitor as if the pressure sensors are not even connected. The first section of code shows that the sensors are in-fact connected, but the values that I am printing must not be from the sensors...

I do not really understand what is happening with the memory here... can anyone help?

Here is my code:

#include <Wire.h>

extern "C" 
{
  #include "utility/twi.h"
}

#define TCAADDR 0x70

unsigned long Coff[6], Ti = 0, offi = 0, sensi = 0;
unsigned int data[3]; 


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

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

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  
  //pinMode(0, OUTPUT);
  
  Serial.println("\nTCAScanner ready!");
  
  for(uint8_t t=1; t<=3; t++)
  {
    tcaselect(t);
    Serial.print("TCA Port #");
    Serial.println(t);

    for(uint8_t addr = 0; addr <= 127; addr++)
    {
      if(addr == TCAADDR) continue;

      uint8_t data;
      if(! twi_writeTo(addr, &data, 0, 1, 1))
      {
        Serial.print("Found I2C 0x");
        Serial.println(addr, HEX);
      }
    }
    
    for(int i = 0; i < 6; i++)
    {
      Wire.beginTransmission(TCAADDR);
      Wire.write(0xA2 + (2*i));
      Wire.endTransmission();

      Wire.requestFrom(TCAADDR, 2);
      
      if(Wire.available() == 2)
      {
        data[0] = Wire.read();
        data[1] = Wire.read();
      }
      Coff[i] = ((data[0]*256) + data[1]);
    }
    delay(10);
  }
  Serial.println("\nDone!");
}

void loop() 
{
  for(uint8_t i = 1; i <= 3; i++)
  {
    
    //tcaselect(i);
    Wire.beginTransmission(TCAADDR);
    Wire.write(0x1E);
    Wire.endTransmission();
    delay(10);
  
    //tcaselect(i);
    Wire.beginTransmission(TCAADDR);
    Wire.write(0x40);
    Wire.endTransmission();
    delay(10);

    //tcaselect(i);
    Wire.beginTransmission(TCAADDR);
    Wire.write(0x00);
    Wire.endTransmission();
    delay(10);

    Wire.requestFrom(TCAADDR, 3);

    if(Wire.available() == 3)
    {
      data[0] = Wire.read();
      data[1] = Wire.read();
      data[2] = Wire.read();
    }

    unsigned long ptemp = ((data[0]*65536.0) + (data[1]*256.0) + data[2]);

    //tcaselect(i);
    Wire.beginTransmission(TCAADDR);
    Wire.write(0x50);
    Wire.endTransmission();
    delay(10);

    //tcaselect(i);
    Wire.beginTransmission(TCAADDR);
    Wire.write(0x00);
    Wire.endTransmission();
    
    Wire.requestFrom(TCAADDR, 3);

    if(Wire.available() == 3)
    {
      data[0] = Wire.read();
      data[1] = Wire.read();
      data[2] = Wire.read();
    }

    unsigned long temp = ((data[0] * 65536.0) + (data[1] * 256.0) + data[2]);
    unsigned long dT = temp - ((Coff[4] * 256));
    temp = 2000 + (dT * (Coff[5] / pow(2, 23)));

    unsigned long long off = Coff[1] * 262144 + (Coff[3] * dT) / 32;
    unsigned long long sens = Coff[0] * 131072 + (Coff[2] * dT) / 128;

    if(temp < 2000)
    {
      Ti = 3 * (dT * dT) / (pow(2,33));
      offi = 3 * ((pow((temp - 2000), 2))) / 8;
      sensi = 7 * (pow((temp - 2000), 2)) / 8; 
      if(temp < - 1500)
      {
        sensi = sensi + 3 * ((pow((temp + 1500), 2)));
      }
    }
    else if(temp >= 2000)
    {
      Ti = 0;
      offi = 0;
      sensi = 0;
    }

    temp -= Ti;
    off -= offi;
    sens -= sensi;
    
    ptemp = (((ptemp * sens) / 2097152) - off);
    ptemp /= 32768.0;
    float pressure = ptemp / 100.0;
    float ctemp = temp / 100.0;
    float fTemp = ctemp * 1.8 + 32.0;

    if(i == 1)
    {
      Serial.print("P");
      Serial.print(i);
      Serial.print(" = ");
      Serial.print(pressure);
      Serial.print("\t");
    }

    else if(i == 2)
    {
      Serial.print("P");
      Serial.print(i);
      Serial.print(" = ");
      Serial.print(pressure);
      Serial.print("\t");
    }

    else
    {
      Serial.print("P");
      Serial.print(i);
      Serial.print(" = ");
      Serial.print(pressure);
      Serial.print("\n");
    }

    delay(10);
  }

  //digitalWrite(0, LOW);
  
}

Website for the I2C Multiplexer - Arduino Wiring & Test | Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout | Adafruit Learning System

Website to the Pressure Sensor - http://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Data+SheetMS5803-05BAB3pdfEnglishENG_DS_MS5803-05BA_B3.pdfCAT-BLPS0011

I am using an I2C multiplexer since the addresses of all of the pressure sensors are the same.

Any insights would be greatly appreciated! :slight_smile:

ryguy95:
Hi,

I'm fairly novice with programming and I am hoping that someone can help me with a challenge that I'm facing with my project. (I also hope that I've posted this in the correct group)

I am trying to connect three pressure sensors to an I2C Multiplexer using a Seeeduino.
I have been able to successfully read data individually with another setup that includes the sensors, but I cannot seem to get the same results using this multiplexer.

Using that multiplexor you need to have pullup resistors on each branch, I would recommend 50k

When you disable a branch, it disconnects that branch, so, if your pullups are at the CPU, the branch sees both SDA and SCL fall which can cause the devices to lockup.

Just use the default Wire() functions:

#include <Wire.h>

#define MULTIADDR 0x70


struct SENSOR{
  uint8_t limb;
  uint8_t addr;
  };

#define MAXSENSORS 100

SENSOR sensors[MAXSENSORS];
uint8_t sensorCount=0;


void branch( uint8_t limb){
// limb is valid from 0..8, 0 means all off
Wire.beginTransmission(MULTIADDR);
if(limb>0){
  Wire.write( 1<<(limb&7));
  }
else {
  Wire.write(0);
  }
Wire.endTransmission();
}

void setup(){
Wire.begin();
Serial.begin(115200);


// scan for I2c Devices

uint8_t limb=0;
while(limb<9){
  branch(limb);
  Serial.print("\n Scanning Branch = ");
  Serial.println(limb,DEC);
  char buf[10];
  for(uint8_t ic=0;ic<128;ic++){
    Wire.beginTransmission(ic);
    uint8_t err=Wire.endTransmission();
    if((ic%16)==0){
      sprintf(buf,"\n%02X:",ic);
      Serial.print(buf);
      } 
    if (err==0){ // found device
      sprintf(buf," %02x",ic);
      if(sensorCount<MAXSENSORS){
        sensors[sensorCount].limb=limb;
        sensors[sensorCount].addr=ic;
        sensorCount++;
        }
      }
    else sprintf(buf," ..");
    Serial.print(buf);
    }
  limb++;
  }
Serial.println();
limb=0;
char buff[100];
while(limb<sensorCount){
  sprintf(buff,"Sensor[%d:%02x]\n",sensors[limb].limb,sensors[limb].addr);
  Serial.print(buff);
  limb++;
  }
}

void resetSensors(){
uint8_t i = 0;
char buff[50];
while(i<sensorCount){
  branch(sensors[i].limb);
  Wire.beginTransmission(sensors[i].addr);
  Wire.write(0x1E); // reset command
  uint8_t err=Wire.endTransmission();
  if(err!=0){
    sprintf(buff,"sensor[%d:%02x] reset Failed=%d\n",sensors[i].limb,sensors[i].addr,err);
    Serial.print(buff);
    }
  i++;
  }
}

void startConversion(){
uint8_t i=0;
char buff[100];
while(i<sensorCount){
  branch(sensors[i].limb);
  Wire.beginTransmission(sensors[i].addr);
  Wire.write(0x48); // start coversion D1 4096
  uint8_t err=Wire.endTransmission();
  if(err!=0){
    sprintf(buff,"sensor[%d:%02x] Conversion Start Failed=%d\n",sensors[i].limb,sensors[i].addr,err);
    Serial.print(buff);
    }
  i++;
  }
}

void readConversion(){
uint8_t i=0;
char buff[100];
while(i<sensorCount){
  branch(sensors[i].limb);
  uint32_t timeout=millis();
  bool ready=false;
  uint8_t err=0;
  while((!ready)&&(millis()-timeout<1000)){ // wait up to 1 second for sensor to convert reading
    Wire.beginTransmission(sensors[i].addr);
    err=Wire.endTransmission();
    ready = err==0;
    }
  if(ready){
    err=Wire.requestFrom(sensors[i].addr,(uint8_t)3);
    if(err==3){// sensor returned 3 bytes
      sprintf(buff,"Sensor[%d:%02x] reading: %02x %02x %02x\n",sensors[i].limb,sensors[i].addr,Wire.read(),Wire.read(),Wire.read());
      Serial.print(buff);
      }
    else {
      sprintf(buff,"Reading Sensor[%d:%02x] read failed\n",sensors[i].limb,sensors[i].addr);
      Serial.print(buff);
      }
    }
  else {
    sprintf(buff,"Reading Sensor[%d:%02x] timed out\n",sensors[i].limb,sensors[i].addr);
    Serial.print(buff);
    }
  i++;
  }
}

void loop(){
resetSensors();
startConversion();
readConversion();
}

Chuck.