Go Down

Topic: Arduino Due Wire1 and Wire Problems (Read 1 time) previous topic - next topic


Hello Everyone!

I'm currently working on a project where I use the Wire (I2C) library to communicate with the Adafruit BNO055 Absolute Orientation Sensor on one side and the Wire1 library with a Arduino Uno slave device, which is sending a data string to my Arduino Due master device. Both devices are connected via a i2C save level shifter with 3.3kOhm pullups.

Additional, the Arduino Due master is communicating via Ethernet with Matlab Simulink.

The master Arduino is also controlling a BLCD motor which spins very fast and uses a high current. Everything is packed next to each other.

My problem is that my code workes fine when the BLDC motor is not running but when i switch on the motor, after a random time the communication with the slave device break and freeze. I recognize that because the sampling time in Matlab Simulink drops dramatically.

The IC2 Communication on the Master works like:

Code: [Select]

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

// ---------- Interboard I2C Communication ----------
class I2C_CommunicationClass
    const int Slave_Address = 42;     // I2C Slave Address
    static const int BufferSize = 13; // I2C Buffer Size

    char recChar;
    bool seperatorTrigger;  // Seperator Detected - Trigger
    int seperatorPos = 0;   // Seperator Detected - Position

    volatile bool toggleI2C;

    // Buffer -> max. I2C Size to avoid overflow if Seperator is not detected
    char I2C_Buffer1[BufferSize + 1]; // I2C Data Puffer 1
    char I2C_Buffer2[BufferSize + 1]; // I2C Data Puffer 2

    void readData()
      // Empty Char Array Buffers
      this->I2C_Buffer1[0] = '0';
      this->I2C_Buffer2[0] = '0';
      seperatorTrigger = false;

      // Stop Active Wire Communication

      // Request Data from the I2C Slave
      Wire1.requestFrom(Slave_Address, BufferSize);

      // Receive Data from I2C Slave
      // Slave may Send Less than Requested
      if (Wire1.available() == BufferSize) {

        // Loop through Buffer Size
        for (int i = 0; i < BufferSize; i++) {
          // Read each Char from I2C
          recChar = Wire1.read(); // receive a byte as character

          // Check for Char Seperator -> Set trigger
          if (recChar == ';') {
            seperatorTrigger = true;
            seperatorPos = i + 1;
          else {
            // Write Data to de dependent Buffer
            if (!seperatorTrigger) {
              // Write I2C Value to Buffer 1
              this->I2C_Buffer1[i] = recChar;
            else {
              // Write I2C Value to Buffer 2
              this->I2C_Buffer2[i - seperatorPos] = recChar;

        // Convert Char Array to Float if Value is not Out of Range
        if (atof(this->I2C_Buffer1) <= 360 && atof(this->I2C_Buffer1) > 0.05) {
          encoder1.Angle = atof(this->I2C_Buffer1);

        if (atof(this->I2C_Buffer2) <= 360 && atof(this->I2C_Buffer2) > 0.05) {
          encoder2.Angle = atof(this->I2C_Buffer2);

For the communication with my IMU the code works like:
Code: [Select]
//  ---------- Adafruit BNO055 IMU ----------
class IMU_BNO055
    // Sensor Events
    sensors_event_t event;
    imu::Quaternion quat;

    // Adafruit BNO055 9-DOF IMU
    Adafruit_BNO055 AdafruitBNO = Adafruit_BNO055(55);

    // Orientation variables
    float phi, theta, psi;
    float Quat_W, Quat_X, Quat_Y, Quat_Z;

    // Help variables
    bool noBNO055 = false;
    volatile bool toggleIMU = false;

    // ------------------ Read BNO055 IMU Values -----------------------------
    void readBNO055 () {

      // ------------------------ Read IMU BNO055 Data -----------------------
      // Check if Sensor is Active and IMU toggle is True
      if (!noBNO055 && toggleIMU) {
        // ---------- Read EULER Angles Adafruit BNO055 IMU Data -------------

        phi = event.orientation.y;
        theta = event.orientation.z;
        psi = event.orientation.x;

        // -------------- Read RAW Adafruit BNO055 IMU Data ------------------
        quat = this->AdafruitBNO.getQuat();

        Quat_W = quat.w();
        Quat_X = quat.x();
        Quat_Y = quat.y();
        Quat_Z = quat.z();

        // Toggle IMU read trigger False until next call
        this->toggleIMU = false;

In the main loop I'm just calling the regarding functions from the classes.

The code for the slave device looks like:
Code: [Select]

void loop()
  // ----------------- Generate I2C Buffer String -----------------------------
  // Convertion from Float to Char-String (For Uno not supported in sprintf)
  dtostrf(encoder1.Angle, 5, 2, strEncoder1_Angle);
  dtostrf(encoder2.Angle, 5, 2, strEncoder2_Angle);
  sprintf(I2C_Buffer, "%s;%s", strEncoder1_Angle, strEncoder2_Angle);

// --------------- I2C Communication Event Handler ---------------------------
void requestEvent_I2C() {
  // Write I2C Buffer to Connection
  Wire.write(I2C_Buffer); // respond with message of 13 bytes

I'm not sure what the problem could be. On one hand side i thought about that the i have a buffer overflow if the received string on the master Arduino is wrong or too long. On the other hand side it could be electromagnetic noise from the BLCD motor which influence the I2C communication. I also have some concerns that the wire1 and wire on the Arduino Due are not working proper. I read some topics about bugs in the library.

The strange thing is that if the IMU is physically not connected with the Arduino the master-slave communication does not even work and another thing is that everything works sometimes for 30 seconds or longer and then stops, or sometimes it stops immediately.

Thanks for your input and I appreciate every help. I work on that since 1,5 months and have still no solution.



Have you found out anything yourself yet? I am currently experiencing the same problem only having a NodeMCU as master communicating with a BNO055. For me the programm just stops at some time and the BNO055 does not respond again. Even if I press the reset button for the board i get stuck in the initialization of the sensor because the BNO055 isnt returning anything.


There is no glitch filtering on the I2C bus of the Arduino DUE.

Firstly you can add e.g. a 10 Ohms resistor in serie on SDA, idem on SCL, and secondly set a timeout. In case the I2C hangs (the timeout is reached), you can reset the I2C bus (see in the DUE sub forum how to do that by sending 9 pulses on the bus). If that's not suffcient, reset the I2C slave with a reset line activated from the I2C Master.

Go Up