TCA9548A with 5 9DOF IMU sensors

Hi everyone,

I have a project in which i need to get data from 5 IMU sensors (LSM9DS1) in order to track motion. I already have a working prototype: i can read all 5 of them and pass the data through to an Arduino Uno and read everything through serial. The thing is... I've run into a weird problem: it all works just fine when I have the VIN of the I2C MUX connected to the 5V of the Arduino, but when I connect it to the 3,3V pin it just doesn't work anymore. I tested the sensors alone on 3,3V and they work just fine, I tested the MUX on 3,3V and it works fine, but when i put them together there's no more data that passes through. If I run an I2C Scanner the MUX still shows up, and if I run the MUX Scanner every individual sensor shows up, so I'm really confused.
I also uploaded the schematics of how everything is connected, i hope it shows up fine. If anyone has any idea, please let me know because i realy can't figure this one out.
Thank you in advance!

How do you know it's working if you don't have any sensors connected to it?

That makes me wonder if there is an error in your code and it is not using the mux correctly. Post your complete code.

By that I mean that i connected the MUX to 3.3V and it showed up, i have indeed not been able to test the MUX on 3.3V with a sensor attached.

Here is the code:

//Libraries
#include <Wire.h>
#include <Adafruit_LSM9DS1.h>
#include <Adafruit_Sensor.h>

//Define multiplexer TCA9548A and the 5 LSM9DS1 IMUs
#define TCAADDR 0x70
Adafruit_LSM9DS1 lsm1 = Adafruit_LSM9DS1();
Adafruit_LSM9DS1 lsm2 = Adafruit_LSM9DS1();
Adafruit_LSM9DS1 lsm3 = Adafruit_LSM9DS1();
Adafruit_LSM9DS1 lsm4 = Adafruit_LSM9DS1();
Adafruit_LSM9DS1 lsm5 = Adafruit_LSM9DS1();

//Bus select function for the multiplexer
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

//Setup sensor parameters (range, sensibility, ...); later called on in setup
void setupSensor() {
  tcaselect(1);
  lsm1.begin();
  lsm1.setupAccel(lsm1.LSM9DS1_ACCELRANGE_8G, lsm1.LSM9DS1_ACCELDATARATE_119HZ);
  lsm1.setupMag(lsm1.LSM9DS1_MAGGAIN_16GAUSS);
  lsm1.setupGyro(lsm1.LSM9DS1_GYROSCALE_2000DPS);

  tcaselect(2);
  lsm2.begin();
  lsm2.setupAccel(lsm2.LSM9DS1_ACCELRANGE_8G, lsm2.LSM9DS1_ACCELDATARATE_119HZ);
  lsm2.setupMag(lsm2.LSM9DS1_MAGGAIN_16GAUSS);
  lsm2.setupGyro(lsm2.LSM9DS1_GYROSCALE_2000DPS);

  tcaselect(3);
  lsm3.begin();
  lsm3.setupAccel(lsm3.LSM9DS1_ACCELRANGE_8G, lsm3.LSM9DS1_ACCELDATARATE_119HZ);
  lsm3.setupMag(lsm3.LSM9DS1_MAGGAIN_16GAUSS);
  lsm3.setupGyro(lsm3.LSM9DS1_GYROSCALE_2000DPS);

  tcaselect(4);
  lsm4.begin();
  lsm4.setupAccel(lsm4.LSM9DS1_ACCELRANGE_8G, lsm4.LSM9DS1_ACCELDATARATE_119HZ);
  lsm4.setupMag(lsm4.LSM9DS1_MAGGAIN_16GAUSS);
  lsm4.setupGyro(lsm4.LSM9DS1_GYROSCALE_2000DPS);

  tcaselect(5);
  lsm5.begin();
  lsm5.setupAccel(lsm5.LSM9DS1_ACCELRANGE_8G, lsm5.LSM9DS1_ACCELDATARATE_119HZ);
  lsm5.setupMag(lsm5.LSM9DS1_MAGGAIN_16GAUSS);
  lsm5.setupGyro(lsm5.LSM9DS1_GYROSCALE_2000DPS);*/
}

void setup() {
  //Go to setup for the sensor parameters
  setupSensor();

  //Start serial communication and wait on initialisation
  Serial.begin(115200);
  while (!Serial) {
    delay(1);
  }
  Serial.println(F("LSM9DS1 data read demo"));
  delay(100);
  
  //Try to initialise and warn if the chip wasn't detected
  if (!lsm1.begin()) {
    Serial.println(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_1. Check your wiring!"));
    while (1);
  }
  Serial.println(F("Found LSM9DS1 9DOF on MPX_Line_1"));

  if (!lsm2.begin()) {
    Serial.println(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_2. Check your wiring!"));
    while (1);
  }
  Serial.println(F("Found LSM9DS1 9DOF on MPX_Line_2"));

  if (!lsm3.begin()) {
    Serial.println(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_3. Check your wiring!"));
    while (1);
  }
  Serial.println(F("Found LSM9DS1 9DOF on MPX_Line_3"));

  if (!lsm4.begin()) {
    Serial.println(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_4. Check your wiring!"));
    while (1);
  }
  Serial.println(F("Found LSM9DS1 9DOF on MPX_Line_4"));

  if (!lsm5.begin()) {
    Serial.println(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_5. Check your wiring!"));
    while (1);
  }
  Serial.println(F("Found LSM9DS1 9DOF on MPX_Line_5"));

  //Setup redundancy
  setupSensor();
}

void valSensor1() {
  //select the bus on the multiplexer and ask the sensor on that bus to read in the data (done the same for the rest of the busses/sensors)
  tcaselect(1);
  lsm1.read();   

  //Get a new sensor event
  sensors_event_t a, m, g, temp;
  lsm1.getEvent(&a, &m, &g, &temp); 

  //Print the data from the sensor
  Serial.print("Accel 1 X: "); Serial.print(a.acceleration.x); Serial.print(" m/s^2");
  Serial.print("\tY: "); Serial.print(a.acceleration.y);     Serial.print(" m/s^2 ");
  Serial.print("\tZ: "); Serial.print(a.acceleration.z);     Serial.println(" m/s^2 ");

  Serial.print("Mag 1 X: "); Serial.print(m.magnetic.x);   Serial.print(" uT");
  Serial.print("\tY: "); Serial.print(m.magnetic.y);     Serial.print(" uT");
  Serial.print("\tZ: "); Serial.print(m.magnetic.z);     Serial.println(" uT");

  Serial.print("Gyro 1 X: "); Serial.print(g.gyro.x);   Serial.print(" rad/s");
  Serial.print("\tY: "); Serial.print(g.gyro.y);      Serial.print(" rad/s");
  Serial.print("\tZ: "); Serial.print(g.gyro.z);      Serial.println(" rad/s");

  Serial.println();
}

void valSensor2() {
  tcaselect(2);
  lsm2.read();

  sensors_event_t a, m, g, temp;
  lsm2.getEvent(&a, &m, &g, &temp); 

  Serial.print("Accel 2 X: "); Serial.print(a.acceleration.x); Serial.print(" m/s^2");
  Serial.print("\tY: "); Serial.print(a.acceleration.y);     Serial.print(" m/s^2 ");
  Serial.print("\tZ: "); Serial.print(a.acceleration.z);     Serial.println(" m/s^2 ");

  Serial.print("Mag 2 X: "); Serial.print(m.magnetic.x);   Serial.print(" uT");
  Serial.print("\tY: "); Serial.print(m.magnetic.y);     Serial.print(" uT");
  Serial.print("\tZ: "); Serial.print(m.magnetic.z);     Serial.println(" uT");

  Serial.print("Gyro 2 X: "); Serial.print(g.gyro.x);   Serial.print(" rad/s");
  Serial.print("\tY: "); Serial.print(g.gyro.y);      Serial.print(" rad/s");
  Serial.print("\tZ: "); Serial.print(g.gyro.z);      Serial.println(" rad/s");

  Serial.println();
}

void valSensor3() {
  tcaselect(3);
  lsm3.read();  

  sensors_event_t a, m, g, temp;
  lsm3.getEvent(&a, &m, &g, &temp); 

  Serial.print("Accel 3 X: "); Serial.print(a.acceleration.x); Serial.print(" m/s^2");
  Serial.print("\tY: "); Serial.print(a.acceleration.y);     Serial.print(" m/s^2 ");
  Serial.print("\tZ: "); Serial.print(a.acceleration.z);     Serial.println(" m/s^2 ");

  Serial.print("Mag 3 X: "); Serial.print(m.magnetic.x);   Serial.print(" uT");
  Serial.print("\tY: "); Serial.print(m.magnetic.y);     Serial.print(" uT");
  Serial.print("\tZ: "); Serial.print(m.magnetic.z);     Serial.println(" uT");

  Serial.print("Gyro 3 X: "); Serial.print(g.gyro.x);   Serial.print(" rad/s");
  Serial.print("\tY: "); Serial.print(g.gyro.y);      Serial.print(" rad/s");
  Serial.print("\tZ: "); Serial.print(g.gyro.z);      Serial.println(" rad/s");

  Serial.println();
}

void valSensor4() {
  tcaselect(4);
  lsm4.read();  

  sensors_event_t a, m, g, temp;
  lsm4.getEvent(&a, &m, &g, &temp); 

  Serial.print("Accel 4 X: "); Serial.print(a.acceleration.x); Serial.print(" m/s^2");
  Serial.print("\tY: "); Serial.print(a.acceleration.y);     Serial.print(" m/s^2 ");
  Serial.print("\tZ: "); Serial.print(a.acceleration.z);     Serial.println(" m/s^2 ");

  Serial.print("Mag 4 X: "); Serial.print(m.magnetic.x);   Serial.print(" uT");
  Serial.print("\tY: "); Serial.print(m.magnetic.y);     Serial.print(" uT");
  Serial.print("\tZ: "); Serial.print(m.magnetic.z);     Serial.println(" uT");

  Serial.print("Gyro 4 X: "); Serial.print(g.gyro.x);   Serial.print(" rad/s");
  Serial.print("\tY: "); Serial.print(g.gyro.y);      Serial.print(" rad/s");
  Serial.print("\tZ: "); Serial.print(g.gyro.z);      Serial.println(" rad/s");

  Serial.println();
}

void valSensor5() {
  tcaselect(5);
  lsm5.read();  

  sensors_event_t a, m, g, temp;
  lsm5.getEvent(&a, &m, &g, &temp); 

  Serial.print("Accel 5 X: "); Serial.print(a.acceleration.x); Serial.print(" m/s^2");
  Serial.print("\tY: "); Serial.print(a.acceleration.y);     Serial.print(" m/s^2 ");
  Serial.print("\tZ: "); Serial.print(a.acceleration.z);     Serial.println(" m/s^2 ");

  Serial.print("Mag 5 X: "); Serial.print(m.magnetic.x);   Serial.print(" uT");
  Serial.print("\tY: "); Serial.print(m.magnetic.y);     Serial.print(" uT");
  Serial.print("\tZ: "); Serial.print(m.magnetic.z);     Serial.println(" uT");

  Serial.print("Gyro 5 X: "); Serial.print(g.gyro.x);   Serial.print(" rad/s");
  Serial.print("\tY: "); Serial.print(g.gyro.y);      Serial.print(" rad/s");
  Serial.print("\tZ: "); Serial.print(g.gyro.z);      Serial.println(" rad/s");

  Serial.println();
}

void loop() {
  valSensor1();
  valSensor2();
  valSensor3();
  valSensor4();
  valSensor5();
}

Thank you for your time!:slight_smile:

Why is your code calling lsm1.begin() again here?

  1. Your code has already done that in the setupSensor() function. If you want to check the result, that would be the place to do it.
  2. In setup(), you are not setting the mux for each sensor. You are doing that in setupSensor() but not in setup().

Once you have fixed that, I will help you to reduce your code down to 20% of it's current size.

Problem: your first sensor is connected to SDA0 & SCL0 pins of the mux, not SDA1 & SCL1.

It's checking if lsm1 was actually activated en it lets me know if it wasn't triggered/activated, hence the warning:

if (!lsm1.begin()) {
    Serial.println(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_1. Check your wiring!"));
    while (1);

I had some issues in the beginning with reading them all at the same time, so I wrote a lot of checks to make sure everything goes correctly. They can be deleted as they wouldn't serve any more purpouse once it all works well.

That's correct, I set each sensor in setupSensor() and than i call my function setupSensor() inside setup(). I thought it provided more clarity in my code, but I will change it if this isn't the proper way to do it.

Edit: Yeah I forgot to change the schematics, but my sensors are now soldered to MUX channels 1 through 5. Sorry for that!

No, it's re-activating lsm1, but this time it won't work because you forgot to set the mux channel.

//Libraries
#include <Wire.h>
#include <Adafruit_LSM9DS1.h>
#include <Adafruit_Sensor.h>

//Define multiplexer TCA9548A and the 5 LSM9DS1 IMUs
#define TCAADDR 0x70
const byte sensorCount = 5;
Adafruit_LSM9DS1 lsm[sensorCount];

//Bus select function for the multiplexer
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

//Setup sensor parameters (range, sensibility, ...); later called on in setup
void setupSensor() {
  for (byte s=0; s<sensorCount; s++) {
    tcaselect(s+1);
    //Try to initialise and warn if the chip wasn't detected
    if (!lsm[s].begin()) {
      Serial.print(F("Oops ... unable to initialize the LSM9DS1 on MPX_Line_"));
      Serial.print(s);
      Serial.println(F(". Check your wiring!"));
      while (1);
    }
    Serial.print(F("Found LSM9DS1 9DOF on MPX_Line_"));
    Serial.println(s);
    lsm[s].setupAccel(lsm[s].LSM9DS1_ACCELRANGE_8G, lsm[s].LSM9DS1_ACCELDATARATE_119HZ);
    lsm[s].setupMag(lsm[s].LSM9DS1_MAGGAIN_16GAUSS);
    lsm[s].setupGyro(lsm[s].LSM9DS1_GYROSCALE_2000DPS);
  }
}

void setup() {
  //Start serial communication and wait on initialisation
  Serial.begin(115200);
  while (!Serial) {
    delay(1);
  }
  Serial.println(F("LSM9DS1 data read demo"));
  delay(100);
  
  //Go to setup for the sensor parameters
  setupSensor();
  //Setup redundancy ???
  //setupSensor();
}

void printSensorVal(byte s, char *name, char *units, sensors_vec_t *v) {
  Serial.print(name);
  Serial.print(s);
  Serial.print("\tX: ");
  Serial.print(v->x);
  Serial.print(units);
  Serial.print("\tY: ");
  Serial.print(v->y);
  Serial.print(units);
  Serial.print("\tZ: ");
  Serial.print(v->z);
  Serial.println(units);
}

void valSensor(byte s) {
  //select the bus on the multiplexer and ask the sensor on that bus to read in the data (done the same for the rest of the busses/sensors)

  tcaselect(s+1);
  lsm[s].read();   

  //Get a new sensor event
  sensors_event_t a, m, g, temp;
  lsm[s].getEvent(&a, &m, &g, &temp); 

  //Print the data from the sensor
  printSensorVal(s, "Accel ", " m/s^2", &a.acceleration);
  printSensorVal(s, "Mag ", " uT", &m.magnetic);
  printSensorVal(s, "Gyro ", " rad/s", &g.gyro);

  Serial.println();
}

void loop() {
  for (byte s=0; s<sensorCount; s++) valSensor(s);
}

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