sparkfun / SparkFun_BNO080_Arduino_Library

An Arduino Library for the BNO080 IMU combination triple axis accelerometer/gyro/magnetometer packaged with an ARM Cortex M0+ running powerful algorithms.
Other
81 stars 62 forks source link

Intermittent I2C problem between Artemis RedBoard and BNO080 #69

Closed jerabaul29 closed 3 years ago

jerabaul29 commented 3 years ago

Setup

Code

#include "Arduino.h"
#include <Wire.h>
#include "SparkFun_BNO080_Arduino_Library.h"

BNO080 bno080_imu;

//--------------------------------------------------------------------------------
// a few helper functions

void printAccuracyLevel(byte accuracyNumber){          // accuracy is:
  if (accuracyNumber == 0) Serial.print(F("U"));       // Unreliable
  else if (accuracyNumber == 1) Serial.print(F("L"));  // Low
  else if (accuracyNumber == 2) Serial.print(F("M"));  // Medium
  else if (accuracyNumber == 3) Serial.print(F("H"));  // High
}

//------------------------------------------------------------------------
// some parameters
constexpr unsigned long imu_output_period = 5;  // high frequency, to make sure we acquire as much data as possible

//------------------------------------------------------------------------
void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println("---------- booted ----------");
  delay(10);

  Wire.begin();
  delay(50);

  Wire.setClock(100000);
  delay(1000);

  bno080_imu.begin();
  delay(50);
  bno080_imu.enableDebugging(Serial);
  delay(50);

  bno080_imu.enableAccelerometer(imu_output_period);
  bno080_imu.enableMagnetometer(imu_output_period);
  bno080_imu.enableGyro(imu_output_period);
  bno080_imu.enableRotationVector(imu_output_period);
  delay(5000);

  Serial.println(F("sensor set up, start measuring"));
}

//------------------------------------------------------------------------
void loop() {
    if (bno080_imu.dataAvailable() == true){
      float accel_x = bno080_imu.getAccelX();
      float accel_y = bno080_imu.getAccelY();
      float accel_z = bno080_imu.getAccelZ();
      byte accel_accuracy = bno080_imu.getLinAccelAccuracy();

      float gyro_x = bno080_imu.getGyroX();
      float gyro_y = bno080_imu.getGyroY();
      float gyro_z = bno080_imu.getGyroZ();
      byte gyro_accuracy = bno080_imu.getGyroAccuracy();

      float mag_x = bno080_imu.getMagX();
      float mag_y = bno080_imu.getMagY();
      float mag_z = bno080_imu.getMagZ();
      byte mag_accuracy = bno080_imu.getMagAccuracy();

      float quat_i = bno080_imu.getQuatI();
      float quat_j = bno080_imu.getQuatJ();
      float quat_k = bno080_imu.getQuatK();
      float quat_real = bno080_imu.getQuatReal();
      byte quat_accuracy = bno080_imu.getQuatAccuracy();
      float quat_radian_accuracry = bno080_imu.getQuatRadianAccuracy();

    Serial.print(F(" -accel: "));
    Serial.print(accel_x, 4);
    Serial.print(F(", "));
    Serial.print(accel_y, 4);
    Serial.print(F(", "));
    Serial.print(accel_z, 4);
    Serial.print(F(", pres: "));
    printAccuracyLevel(accel_accuracy);

    Serial.print(F(" -gyro: "));
    Serial.print(gyro_x, 4);
    Serial.print(F(", "));
    Serial.print(gyro_y, 4);
    Serial.print(F(", "));
    Serial.print(gyro_z, 4);
    Serial.print(F(", pres: "));
    printAccuracyLevel(gyro_accuracy);

    Serial.print(F(" -mag: "));
    Serial.print(mag_x, 4);
    Serial.print(F(", "));
    Serial.print(mag_y, 4);
    Serial.print(F(", "));
    Serial.print(mag_z, 4);
    Serial.print(F(", pres: "));
    printAccuracyLevel(mag_accuracy);

    Serial.print(F(" -quat: "));
    Serial.print(quat_i, 4);
    Serial.print(F(", "));
    Serial.print(quat_j, 4);
    Serial.print(F(", "));
    Serial.print(quat_k, 4);
    Serial.print(F(", "));
    Serial.print(quat_real, 4);
    Serial.print(F(", pres: "));
    printAccuracyLevel(quat_accuracy);
    Serial.print(F(", "));
    Serial.print(quat_radian_accuracry, 4);

    Serial.println();
  }

}

Problem

I have an intermittent problem with getting I2C connection to the chip. Sometimes (around 20% of the time I would say), uploading gives me what I want:

--------- booted ----------
sensor set up, start measuring
 -accel: 0.0000, 0.0000, 0.0000, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: 0.0000, 0.0000, 0.0000, pres: U -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.0000, 0.0000, 0.0000, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.0000, 0.0000, 0.0000, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4961, -1.4922, 9.4609, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4961, -1.4922, 9.4609, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4961, -1.4922, 9.4609, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4961, -1.3789, 9.3867, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4961, -1.3789, 9.3867, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4961, -1.3789, 9.3867, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581
 -accel: 0.4609, -1.4570, 9.4609, pres: U -gyro: 0.0000, 0.0000, 0.0000, pres: U -mag: -0.3125, -14.3125, -35.2500, pres: H -quat: 0.0222, -0.0773, 0.9954, 0.0521, pres: H, 0.0581

Sometimes I get some errors:

---------- booted ----------
sendPacket(I2C): endTransmission returned: 4
sendPacket(I2C): endTransmission returned: 4
sendPacket(I2C): endTransmission returned: 4
sendPacket(I2C): endTransmission returned: 4
sensor set up, start measuring
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout
I2C timeout

It seems that when I get some errors, it does not help much to use the reset button on the board nor to re-upload the firmware nor to disconnect and reconnect the BNO080 breakout board. But it seems powering the Artemis board on and off helps.

Any idea how to fix this? I have an application for which I do need to be able to reliably turn on and off and get data from the BNO080.

jerabaul29 commented 3 years ago

(may be related to #68 ).

PaulZC commented 3 years ago

Hi JR, I suspect this is indeed the same as #68 ? Best wishes, Paul

jerabaul29 commented 3 years ago

Mmh, the result is the same, but I am not completely sure that it is the same problem. In one case I cannot begin (seems the begin never gets through), in the other case I skip checking the begin and intermittently get some issues. At least the error messages look different ^^ . But agree this may be a common root cause.

jerabaul29 commented 3 years ago

closing in favor of #72 .