Go Down

Topic: Arduino Due Wire1 and Wire Problems (Read 766 times) previous topic - next topic

StMaster

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
{
  private:
    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

  public:
    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


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

      // Stop Active Wire Communication
      Wire1.endTransmission();

      // 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
{
  private:
    // Sensor Events
    sensors_event_t event;
    imu::Quaternion quat;

  public:
    // 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 -------------
        this->AdafruitBNO.getEvent(&this->event);

        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.

Best,
Stefan



Go Up