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
77 stars 62 forks source link

problems connecting to the BNO080 from Artemis RedBoard #68

Closed jerabaul29 closed 3 years ago

jerabaul29 commented 3 years ago

Setup

I am using:

Fail to run example

I have attempted many times to run the Example1-RotationVector.ino:

#include <Wire.h>

#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080
BNO080 myIMU;

void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("BNO080 Read Example");

  Wire.begin();

  if (myIMU.begin() == false)
  {
    Serial.println("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
    while (1);
  }

  Wire.setClock(400000); //Increase I2C data rate to 400kHz

  myIMU.enableRotationVector(50); //Send data update every 50ms

  Serial.println(F("Rotation vector enabled"));
  Serial.println(F("Output in form i, j, k, real, accuracy"));
}

void loop()
{
  //Look for reports from the IMU
  if (myIMU.dataAvailable() == true)
  {
    float quatI = myIMU.getQuatI();
    float quatJ = myIMU.getQuatJ();
    float quatK = myIMU.getQuatK();
    float quatReal = myIMU.getQuatReal();
    float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();

    Serial.print(quatI, 2);
    Serial.print(F(","));
    Serial.print(quatJ, 2);
    Serial.print(F(","));
    Serial.print(quatK, 2);
    Serial.print(F(","));
    Serial.print(quatReal, 2);
    Serial.print(F(","));
    Serial.print(quatRadianAccuracy, 2);
    Serial.print(F(","));

    Serial.println();
  }
}

I have never managed to get it to work, I get the error message:

BNO080 Read Example
BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...

'Fix' for the example

However, if I just ignore the check, things work "quite often". I.e., if I run:

#include <Wire.h>

#include "SparkFun_BNO080_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_BNO080
BNO080 myIMU;

void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("BNO080 Read Example");

  Wire.begin();
  delay(100);

  /*
  if (myIMU.begin() == false)
  {
    Serial.println("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
    while (1);
  }
  */

  myIMU.begin();

  Wire.setClock(400000); //Increase I2C data rate to 400kHz

  myIMU.enableRotationVector(50); //Send data update every 50ms

  Serial.println(F("Rotation vector enabled"));
  Serial.println(F("Output in form i, j, k, real, accuracy"));
}

void loop()
{
  //Look for reports from the IMU
  if (myIMU.dataAvailable() == true)
  {
    float quatI = myIMU.getQuatI();
    float quatJ = myIMU.getQuatJ();
    float quatK = myIMU.getQuatK();
    float quatReal = myIMU.getQuatReal();
    float quatRadianAccuracy = myIMU.getQuatRadianAccuracy();

    Serial.print(quatI, 2);
    Serial.print(F(","));
    Serial.print(quatJ, 2);
    Serial.print(F(","));
    Serial.print(quatK, 2);
    Serial.print(F(","));
    Serial.print(quatReal, 2);
    Serial.print(F(","));
    Serial.print(quatRadianAccuracy, 2);
    Serial.print(F(","));

    Serial.println();
  }
}

I get a valid output.

Question / possible bug

I suppose this means that there is a potential problem / bug using the library with the Artemis RedBoard? Any idea how to fix this?

jerabaul29 commented 3 years ago

PS: I tried to apply the "ESP32" fix present in the sketch, it did not work.

PaulZC commented 3 years ago

Hi JR, Please have a look at this issue (on OpenLog Artemis): https://github.com/sparkfun/OpenLog_Artemis/issues/67#issuecomment-771473645 It sounds like you may be encountering the same issue (that the BNO080 and Artemis just do not play nicely together)? Best wishes, Paul

jerabaul29 commented 3 years ago

Hi @PaulZC ,

Many thanks for your help :) (and sorry for skipping politeness formula etc on most of my post, having busy days :) ).

I think this looks quite similar to what I experience indeed. I wonder if this is actually different from #69 , but I can well be wrong.

So if I understand correctly, the fix you implemented on the OpenLog_Artemis was to do a "hard" reset. Was it by re-starting the whole chip, or only the I2C bus? Would it be possible to restart only the I2C bus, I have some data in RAM I do not want to loose... Could you show how you did the fix last time?

How do you want to proceed further here? Do you think you could push a .begin_with_OLA_reset(unsigned long timeout_millis) or something like that into the BNO080 class, that would perform the restart (of the I2C bus if I understand well? if it is the whole chip this is more annoying, as I have some user data I do not want to loose)? Or do you think I should handle it myself as a user? (and if so, do you have a snippet / example)?

Thanks in advance!

Cheers,

JR

PaulZC commented 3 years ago

Hi JR, On OLA we turn the Qwiic bus power off and on again and do a hard reset of the Artemis (via the Watchdog timer). We only do this if the .begin fails - on the SCD30. We don’t support the BNO080 on OLA as we see .begin fail more than one time in two... I have spent hours looking at the core to try and find the root cause, but have failed so far... Best wishes, Paul

PaulZC commented 3 years ago

The reset function is here: https://github.com/sparkfun/OpenLog_Artemis/blob/master/Firmware/OpenLog_Artemis/lowerPower.ino#L157

jerabaul29 commented 3 years ago

Ok, so that means that the way you perform the reset is by resetting the whole board, right? That sounds tough. I can do it, but then I will need to do some dumping to EEPROM first ^^ .

jerabaul29 commented 3 years ago

Or "EEPROM" as this is flash if I understand well :) .

jerabaul29 commented 3 years ago

Thanks for the link :) .

jerabaul29 commented 3 years ago

@PaulZC many thanks for your help, that was very helpful :)

With something like this (sorry, using the Adafruit code at the moment, due to the issue #70 ), I always end up being able to log in the end ^^

#include "Arduino.h"
#include "WDT.h"

#include <Adafruit_BNO08x.h>

Adafruit_BNO08x bno08x{};
sh2_SensorValue_t sensorValue;

unsigned long micros_last;
unsigned long micros_crrt;

void setReports(void) {
  if (!bno08x.enableReport(SH2_ROTATION_VECTOR), 5000UL) {
    Serial.println("Could not enable rotation vector");
  }
}

APM3_WDT wdt;

void resetArtemis(void)
{
  Wire.end(); //Power down I2C

  SPI.end(); //Power down SPI

  power_adc_disable(); //Power down ADC. It it started by default before setup().

  Serial.end(); //Power down UART

  //Force the peripherals off
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
  am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);

  while (1) // That's all folks! Artemis will watchdog reset in 1.25 seconds
    ;
}

void setup(void) {
  wdt.start();

  Serial.begin(115200);
  while (!Serial){
    delay(10);
  }

  Serial.println();
  Serial.println("------ booted ------");
  Serial.println();

  // initialize
  for (int i=0; i<20;i++){
    wdt.restart();
    if (bno08x.begin_I2C(0x4B, &Wire, 0)){
      break;
    }
    else{
      Serial.print("Failed to find BNO08x chip "); Serial.println(i+1);
      if (i == 19){
        Serial.println(F("reset Artemis"));
        resetArtemis();
      }
      delay(500);
    }
  }

  Wire.setClock(400000);
  delay(50);

  setReports();

  micros_last = micros();

  Serial.println("----- Reading events -----");
  delay(100);
}

void loop() {
  wdt.restart();
  Serial.println(F("start reading"));

  while(true){
    wdt.restart();
    if (bno08x.wasReset()) {
      Serial.print("sensor was reset ");
      setReports();
      continue;
    }

    if (!bno08x.getSensorEvent(&sensorValue)) {
      continue;
    }
    else{
      switch (sensorValue.sensorId) {
      case SH2_ROTATION_VECTOR:
        micros_crrt = micros();
        Serial.print(F("micros: ")); Serial.print(micros_crrt); Serial.println(F(" | micros elapsed: ")); Serial.println(micros_crrt-micros_last);
        micros_last = micros_crrt;

        Serial.print("Rotation Vector - r: ");
        Serial.print(sensorValue.un.rotationVector.real);
        Serial.print(" i: ");
        Serial.print(sensorValue.un.rotationVector.i);
        Serial.print(" j: ");
        Serial.print(sensorValue.un.rotationVector.j);
        Serial.print(" k: ");
        Serial.println(sensorValue.un.rotationVector.k);
        break;
      }
    }
  }
}

It fails (and reboots) in the two different ways that were described both here and in #69 (not sure if it is the same issue showing up in 2 different ways, or 2 different issues):

------ booted ------

I2C address not found
Failed to find BNO08x chip 1
I2C address not found
Failed to find BNO08x chip 2
I2C address not found
Failed to find BNO08x chip 3
I2C address not found
Failed to find BNO08x chip 4
I2C address not found
Failed to find BNO08x chip 5
I2C address not found
Failed to find BNO08x chip 6
I2C address not found
Failed to find BNO08x chip 7
I2C address not found
Failed to find BNO08x chip 8
I2C address not found
Failed to find BNO08x chip 9

------ booted ------
------ booted ------

I2C address not found
Failed to find BNO08x chip 1
I2C address not found
Failed to find BNO08x chip 2
I2C address not found
Failed to find BNO08x chip 3
I2C address not found
Failed to find BNO08x chip 4
I2C address not found
Failed to find BNO08x chip 5
I2C address not found
Failed to find BNO08x chip 6
I2C address not found
Failed to find BNO08x chip 7
I2C address not found
Failed to find BNO08x chip 8
I2C address not found
Failed to find BNO08x chip 9
Failed to find BNO08x chip 10
Failed to find BNO08x chip 11
Failed to find BNO08x chip 12
Failed to find BNO08x chip 13
Failed to find BNO08x chip 14
Failed to find BNO08x chip 15
Failed to find BNO08x chip 16
Failed to find BNO08x chip 17
Failed to find BNO08x chip 18
Failed to find BNO08x chip 19
Failed to find BNO08x chip 20
reset Artemis

------ booted ------

But a good watchdog fixes it (I just loose all the data in RAM of course, so I will need to dump useful data to "EEPROM in flash"; any hidden dragons I should know about there? ^^ ) .

jerabaul29 commented 3 years ago

closing in favor of #72 .