i2c multiplexeur and IMUs ... eratic behaviour

Hi all,

I'm facing a new issue which I do no understand.
On a Arduino mega 2560, I got 4 things connected:

  • 3 BNO055 in i2c, each of them has the same i2c addresse 0x28
  • 1 i2c multiplexer (TCA9548A)

I got two pieces of codes to check them.

A first one here, scanning i2c address on the different ports of the multiplexer:

    /**
     * TCA9548 I2CScanner.pde -- I2C bus scanner for Arduino
     *
     * Based on code c. 2009, Tod E. Kurt, http://todbot.com/blog/
     *
     */
     
    #include "Wire.h"
    extern "C" { 
    #include "utility/twi.h"  // from Wire library, so we can do bus scanning
    }
    int i = 0;
     
    #define TCAADDR 0x70
     
    void tcaselect(uint8_t i)
    {
      if (i > 7) return;
     
      Wire.beginTransmission(TCAADDR);
      Wire.write(1 << i);
      Wire.endTransmission();  
    }
     
     
    // standard Arduino setup()
    void setup()
    {
        while (!Serial);
        delay(1000);
     
        Wire.begin();
        
        Serial.begin(115200);
        Serial.println("\nTCAScanner ready!");
              scanIMUs();
        Serial.println("\ndone");
    }
     
void loop() 
    {
      Serial.println("\nTCAScanner ready!");
      scanIMUs();
      Serial.println("\ndone");
      delay(1000);
      i++;
      Serial.println(i);
    }

void scanIMUs()
    {
      for (uint8_t t=0; t<8; 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);
            }
        }
      }
    }

Which is able to check, for at least 6080 runs that the three IMUs are conencted to port 0,1 and 2 of the multiplexer (See 6080 successfullruns.png).

Another code, doing the same but with something extra: conenction to the IMUs once the adresse has been found.

    /**
     * TCA9548 I2CScanner.pde -- I2C bus scanner for Arduino
     *
     * Based on code c. 2009, Tod E. Kurt, http://todbot.com/blog/
     *
     */
     
    #include "Wire.h"
    extern "C" { 
    #include "utility/twi.h"  // from Wire library, so we can do bus scanning
    }
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BNO055.h>
    #include <utility/imumaths.h>
     
    #define TCAADDR 0x70

    Adafruit_BNO055 bno1 = Adafruit_BNO055(55);
    Adafruit_BNO055 bno2 = Adafruit_BNO055(55);
    Adafruit_BNO055 bno3 = Adafruit_BNO055(55);
    int i = 0;
     
    void tcaselect(uint8_t i)
    {
      if (i > 7) return;
     
      Wire.beginTransmission(TCAADDR);
      Wire.write(1 << i);
      Wire.endTransmission();  
    }
     
     
    // standard Arduino setup()
    void setup()
    {
        while (!Serial);
        delay(1000);
     
        Wire.begin();
        
        Serial.begin(115200);
        Serial.println("\nTCAScanner ready!");
        scanIMUs();
        tcaselect(2);
        delay(1000);
        bno1.begin();
        if (!bno1.begin())
        {
          Serial.println("BNO055 1 not detected");
        }
        else
        {
        Serial.println("BNO055 1 detected");
        }
        tcaselect(1);
        delay(1000);
        bno2.begin();
        if (!bno2.begin())
        {
          Serial.println("BNO055 2 not detected");
        }
        else
        {
        Serial.println("BNO055 2 detected");
        }
        tcaselect(0);
        delay(1000);
        bno3.begin();
        if (!bno3.begin())
        {
          Serial.println("BNO055 3 not detected");
        }
        else
        {
        Serial.println("BNO055 3 detected");
        }
        Serial.println("\ndone");
    }
     
void loop() 
    {
      scanIMUs();
        tcaselect(2);
        delay(1000);
        bno1.begin();
        if (!bno1.begin())
        {
          Serial.println("BNO055 1 not detected");
        }
        else
        {
        Serial.println("BNO055 1 detected");
        }
        tcaselect(1);
        delay(1000);
        bno2.begin();
        if (!bno2.begin())
        {
          Serial.println("BNO055 2 not detected");
        }
        else
        {
        Serial.println("BNO055 2 detected");
        }
        tcaselect(0);
        delay(1000);
        bno3.begin();
        if (!bno3.begin())
        {
          Serial.println("BNO055 3 not detected");
        }
        else
        {
        Serial.println("BNO055 3 detected");
        }
        Serial.println("\ndone");
      i++;
      Serial.println(i);
      Serial.println("");
    }

void scanIMUs()
    {
      for (uint8_t t=0; t<8; 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);
            }
        }
      }
    }

This code shows an eratic behaviour (part 1 and part 2.png):

  1. From the start, the three 0x28 are detected
  2. Then, I tried to connect to the IMUs:
  • 2a. At the start, no conenction is possible
  • 2b. Everytime I press the reset button of the arduino, I'm loosing a 0x28
  • 2c. When I unplug and replug the 5V pin supplying the multiplexer and the IMUs, I can find all of them and the connection are working for a single run.

I was first guessing this behavior was due to few poor connection on the classical white female pins board. I bought PCB board, solder everything together and the problem still remains.

Having the three IMUs connected with bno.begin tells me the Imus are fine.
Having some eratic connections with the IMUs (even when reset and +5v are pushed or disccoencted) leads to first hypothesis: it seems to the be a software issues, maybe IMUs should be disconnected once used of the TCA port msut be closed, I do not know.

I'm really lost to find the solution. Signal looks ratehr fine with the scope.
Any idea how to solve this issue or test to perform?

Kind regards

Please don't use low-level functions directly. Don't include utility/twi.h and don't call twi_writeTo(). Use the normal functions from the Wire library.

The best I can do is take a SWAG and be sure you have pull up resistors on each I2C channel. It would be much easier to answer if you had included a schematic, not a frizzy thing. Kopel is giving good advice, best to follow it.

Hi,

Thank you for yours answers. I’m rather new in Arduino and but I tried the following:

  • not include te utility/twi
  • remove the i2c scanner part (since I know the adresses and theirs locations on the TCA9548A).

The code is now as following:

    #include "Wire.h"
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BNO055.h>
    #include <utility/imumaths.h>
     
    #define TCAADDR 0x70

    Adafruit_BNO055 bno1 = Adafruit_BNO055(55);
    Adafruit_BNO055 bno2 = Adafruit_BNO055(55);
    Adafruit_BNO055 bno3 = Adafruit_BNO055(55);
    int i = 0;
     
    void tcaselect(uint8_t i)
    {
      if (i > 7) return;
     
      Wire.beginTransmission(TCAADDR);
      Wire.write(1 << i);
      Wire.endTransmission();  
    }
     
     
    // standard Arduino setup()
    void setup()
    {
        while (!Serial);
        delay(1000);
     
        Wire.begin();
        
        Serial.begin(115200);
        Serial.println("\nTCAScanner ready!");
        
        tcaselect(0);
        delay(1000);
        bno1.begin();
        if (!bno1.begin())
        {
          Serial.println("BNO055 1 not detected");
        }
        else
        {
        Serial.println("BNO055 1 detected");
        }
        tcaselect(2);
        delay(1000);
        bno2.begin();
        if (!bno2.begin())
        {
          Serial.println("BNO055 2 not detected");
        }
        else
        {
        Serial.println("BNO055 2 detected");
        }
        tcaselect(1);
        delay(1000);
        bno3.begin();
        if (!bno3.begin())
        {
          Serial.println("BNO055 3 not detected");
        }
        else
        {
        Serial.println("BNO055 3 detected");
        }
        Serial.println("\ndone");
    }
     
void loop() 
    {
        tcaselect(0);
        delay(1000);
        bno1.begin();
        if (!bno1.begin())
        {
          Serial.println("BNO055 1 not detected");
        }
        else
        {
        Serial.println("BNO055 1 detected");
        }
        tcaselect(2);
        delay(1000);
        bno2.begin();
        if (!bno2.begin())
        {
          Serial.println("BNO055 2 not detected");
        }
        else
        {
        Serial.println("BNO055 2 detected");
        }
        tcaselect(1);
        delay(1000);
        bno3.begin();
        if (!bno3.begin())
        {
          Serial.println("BNO055 3 not detected");
        }
        else
        {
        Serial.println("BNO055 3 detected");
        }
        Serial.println("\ndone");
      i++;
      Serial.println(i);
      Serial.println("");
    }

The behaviour remains eratic: connection failed.

When I tried only a llop fundtion like that:

void loop
{
tcaselect(0);
tcaselect(1);
tcaselect(2);
}

it is working perfectly. So I guess there are issues with the conenction to the BNO055. I do not have any pull-up resistors since I never saw such a setup on the web and the cable are really short. But I could add some, any advice for their values ?
With respect to SWAG, I have no idea what it is.
Kind regards

I did not know what SWAG is either :confused: It is probably this: Scientific wild-ass guess - Wikipedia.

I noticed that even Adafruit still has that example with twi_WriteTo(): Wiring & Test | Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout | Adafruit Learning System. That is not okay.

To scan for a I2C device, you can do this:

Wire.beginAddress( i2c_address);
int error = Wire.endTransmission();
if( error == 0)
{
  Serial.print( "Something found at 0x");
  Serial.println( i2c_address, HEX);
}

The I2C Scanner sketch is based on that.
In the Arduino IDE menu: File / Examples / Wire / i2c_scanner.
There is also the I2C Scanner sketch by Nick Gammon: Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino.

Can you give a link to where you bought the TCA9548 and the BNO055 modules ? Can you also tell how it is connected ? Then we can check for voltage levels and pullup resistors.

Can you show a copy of the Serial Monitor from the start ? Please copy the text, not the image. Do they all three fail, do they show the message "BNO055 x not detected" ?

At this moment I can not tell what the problem is. However, the function bnox.begin() is supposed to be called just once in setup(). When the three sensors are detected in setup(), then the rest should work. Can you find an example with .getSystemStatus() ? or perhaps this example for all three of the sensors: Adafruit_BNO055/sensorapi.ino at master · adafruit/Adafruit_BNO055 · GitHub.

We can check the voltage levels and pullup, if that is okay, and a sketch is running okay when bnox.begin() is not being called in the loop(), then it is fine with me. Even if did run in the first sketch that you showed.

Hi,

The links are here:

Connections:

  • 1st BNO055 to SD0 and SC0
  • 2nd BNO055 to SD1 and SC1
  • 3rd BNO055 to SD2 and SC2
  • I checked the volatages and continuity, they seem ok.
    I have no pull-up resistors, cables are max 10 cm between BNO055 and the TCA.

Here I got a copy-paste from the stick seriel monitor:

TCAScanner ready!
BNO055 1 detected
BNO055 2 detected
BNO055 3 detected

done
BNO055 1 detected

So the BNO055 fails in the first llop. It was working in the setup … I do not understand why …

Really good advise for to check them one-by-one. I adapted the rawdata example:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

/* This driver reads raw data from the BNO055

   Connections
   ===========
   Connect SCL to analog 5
   Connect SDA to analog 4
   Connect VDD to 3.3V DC
   Connect GROUND to common ground

   History
   =======
   2015/MAR/03  - First release (KTOWN)
*/

/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (100)
#define TCAADDR 0x70

// Check I2C device address and correct line below (by default address is 0x29 or 0x28)
//                                   id, address
Adafruit_BNO055 bno = Adafruit_BNO055(-1, 0x28);

/**************************************************************************/
/*
    Arduino setup function (automatically called at startup)
*/
/**************************************************************************/
void setup(void)
{
  Serial.begin(115200);
  Serial.println("Orientation Sensor Raw Data Test"); Serial.println("");
  Wire.begin();
  /* Initialise the sensor */
  tcaselect(2);
        delay(1000);
        bno.begin();
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }

  delay(1000);

  /* Display the current temperature */
  int8_t temp = bno.getTemp();
  Serial.print("Current Temperature: ");
  Serial.print(temp);
  Serial.println(" C");
  Serial.println("");

  bno.setExtCrystalUse(true);

  Serial.println("Calibration status values: 0=uncalibrated, 3=fully calibrated");
}

/**************************************************************************/
/*
    Arduino loop function, called once 'setup' is complete (your own code
    should go here)
*/
/**************************************************************************/
void loop(void)
{
  // Possible vector values can be:
  // - VECTOR_ACCELEROMETER - m/s^2
  // - VECTOR_MAGNETOMETER  - uT
  // - VECTOR_GYROSCOPE     - rad/s
  // - VECTOR_EULER         - degrees
  // - VECTOR_LINEARACCEL   - m/s^2
  // - VECTOR_GRAVITY       - m/s^2
  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(euler.x());
  Serial.print(" Y: ");
  Serial.print(euler.y());
  Serial.print(" Z: ");
  Serial.print(euler.z());
  Serial.print("\t\t");

  /*
  // Quaternion data
  imu::Quaternion quat = bno.getQuat();
  Serial.print("qW: ");
  Serial.print(quat.w(), 4);
  Serial.print(" qX: ");
  Serial.print(quat.x(), 4);
  Serial.print(" qY: ");
  Serial.print(quat.y(), 4);
  Serial.print(" qZ: ");
  Serial.print(quat.z(), 4);
  Serial.print("\t\t");
  */

  /* Display calibration status for each sensor. */
  uint8_t system, gyro, accel, mag = 0;
  bno.getCalibration(&system, &gyro, &accel, &mag);
  Serial.print("CALIBRATION: Sys=");
  Serial.print(system, DEC);
  Serial.print(" Gyro=");
  Serial.print(gyro, DEC);
  Serial.print(" Accel=");
  Serial.print(accel, DEC);
  Serial.print(" Mag=");
  Serial.println(mag, DEC);

  delay(BNO055_SAMPLERATE_DELAY_MS);
}

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

I got this for all three of them:

⸮⸮POrientation Sensor Raw Data Test

Current Temperature: 31 C

Calibration status values: 0=uncalibrated, 3=fully calibrated
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: 0.00 Y: 0.00 Z: 0.00 CALIBRATION: Sys=0 Gyro=0 Accel=0 Mag=0
X: -0.06 Y: -0.06 Z: -0.06 CALIBRATION: Sys=3 Gyro=3 Accel=3 Mag=3
X: -0.06 Y: -0.06 Z: -0.06 CALIBRATION: Sys=3 Gyro=3 Accel=3 Mag=3
X: -0.06 Y: -0.06 Z: -0.06 CALIBRATION: Sys=3 Gyro=3 Accel=3 Mag=3

This rawdata example is working fine with a single BNO055, I got consistent data.
With this TCA, the conenction can be made, but the answer are strange …

Maybe the pull-up resistors … I really don’t know. llokign for any advice, tip, etc.

Kind regards

The Arduino Mega 2560 is 5V board with a 5V I2C bus. It has already onboard pullup resistors.
Your BNO055 modules are very nice. Even a schematic is provided. The modules work with 3.3V and with 5V Arduino boards. It has a voltage regulator and also a I2C level shifter with pullup resistors on both side of the level shifter.
You may connect those BNO055 modules to the Arduino Mega. Apply 5V to the VCC of the BNO055 module.
There is no need for extra pullup resistors.

The multiplexer is a cheap copy of the Adafruit TCA9548 module: TCA9548A I2C Multiplexer : ID 2717 : $6.95 : Adafruit Industries, Unique & fun DIY electronics and kits.
You also need to apply 5V to VIN of the TCA9548 module.

Your I2C multiplexer keeps causing all the problems, so there must be something wrong or it is damaged or the module is bad.
Did you test everything with 5V power to all the modules ? If you used 3.3V, then the level shifters did not work.
Do you use a breadboard ? Those have often bad contacts. Move everything to another location on the breadboard. Check the wires if they are not broken. Check if the GNDs are connected.

You probably have done all of that.
Can you check the I2C multiplexer with a magnifier ? Look for pins that are not soldered or shortcuts.
The only thing that is left is to buy another I2C multiplexer from another seller.

Hi all,

Sorry for the delay … I bought new IMus and a New myultiplexer: same models but fresh new…
It is working perfeclty since then.

I didn’t succeed to un-solder properly the components, So I don’t know if it was coming from the components or the soldering…

Anyway, not a software issue :slight_smile:

Cheers

Thanks for letting us know. I'm glad it is working.

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