SWDUDE

Member Since: May 16, 2011

Country: United States

  • I don't have the same issue. However, I am using the Spark X version with the Spark X Arduino UNO clone. When using Euler angles there is what is call a gimbal lock where a degree of freedom will be lost. I am simply using it for heading so Euler angles work well for me as it is laying flat in the horizontal. I have to first do a figure 8 with the board and then it points to North as zero. This sensor is really stable for me even when I have a strong magnet near it (which is a lot better than my phone compass). Here is my full set of code:

    /*
      Using the BNO080 IMU
      By: Nathan Seidle
      SparkFun Electronics
      Date: December 21st, 2017
      License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
    
      Feel like supporting our work? Buy a board from SparkFun!
      https://www.sparkfun.com/products/14586
    
      This example shows how to output the i/j/k/real parts of the rotation vector.
      https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
    
      It takes about 1ms at 400kHz I2C to read a record from the sensor, but we are polling the sensor continually
      between updates from the sensor. Use the interrupt pin on the BNO080 breakout to avoid polling.
    
      Hardware Connections:
      Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
      Plug the sensor onto the shield
      Serial.print it out at 9600 baud to serial monitor.
    */
    
    #include <math.h>
    #include <Wire.h>
    
    #include "SparkFun_BNO080_Arduino_Library.h"
    BNO080 myIMU;
    
    // Get the euler angles 
    struct Euler{ float yaw; float pitch; float roll; };
    struct Quat{ float i; float j; float k; float real; };
    
    
    Euler getAngles(Quat q, bool degrees);
    
    Quat myQuat; 
    Euler eul;
    
    void setup()
    {
      Serial.begin(115200);
      Serial.println();
      Serial.println("BNO080 Read Example");
    
      Wire.begin();
      Wire.setClock(400000); //Increase I2C data rate to 400kHz
    
      myIMU.begin();
    
      myIMU.enableRotationVector(10); //Send data update every 50ms
    
      Serial.println(F("Rotation vector enabled"));
      //Serial.println(F("Output in form i, j, k, real, accuracy"));
      Serial.println(F("Output in form time(ms), yaw, pitch, roll, 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(","));
        */
        myQuat.i = quatI;
        myQuat.j = quatJ;
        myQuat.k = quatK;
        myQuat.real = quatReal;
    
        eul = getAngles(myQuat);
        Serial.print(millis());
        Serial.print(F(","));
        Serial.print(eul.yaw, 2);
        Serial.print(F(","));
        Serial.print(eul.pitch, 2);
        Serial.print(F(","));
        Serial.print(eul.roll, 2);  
        Serial.print(F(","));
        Serial.print(quatRadianAccuracy, 2);
        Serial.println();
      }
    }
    
    
    // Return the Euler angle structure from a Quaternion structure 
    Euler getAngles(Quat q){
    
      Euler ret_val;
      float x; float y;
    
      /* YAW */ 
      x = 2 * ((q.i * q.j) + (q.real * q.k)); 
      y = square(q.real) - square(q.k) - square(q.j) + square(q.i); 
      ret_val.yaw = degrees(atan2(y, x));
    
      /* PITCH */ 
      ret_val.pitch = degrees(asin(-2 * (q.i * q.k - q.j * q.real)));
    
      /* ROLL */ 
      x = 2 * ((q.j * q.k) + (q.i * q.real)); 
      y = square(q.real) + square(q.k) - square(q.j) - square(q.i); 
      ret_val.roll = degrees(atan2(y , x));
    
      return ret_val;
    
    }
    
  • Cool device!

    If you want to use the Euler angles this is a good reference: https://www.vectornav.com/docs/default-source/documentation/vn-100-documentation/AN002.pdf

    Or... struct Euler{ float yaw; float pitch; float roll; };

    struct Quant{
      float i;
      float j;
      float k;
      float real;
    };
    
    Quant myQuant;
    Euler eul;
    
    // Return the Euler angle structure from a Quanterion structure
    Euler getAngles(Quant q){
    
      Euler ret_val;
    
      float x;
      float y;
    
      /* YAW */
      x = 2 * ((q.i * q.j) + (q.real * q.k));
      y = square(q.real) - square(q.k) - square(q.j) + square(q.i);
      ret_val.yaw = degrees(atan2(y, x));
    
      /* PITCH */
      ret_val.pitch = degrees(asin(-2 * (q.i * q.k - q.j * q.real)));
    
      /* ROLL */
      x = 2 * ((q.j * q.k) + (q.i * q.real));
      y =  square(q.real) + square(q.k) - square(q.j) - square(q.i);
      ret_val.roll = degrees(atan2(y , x));
    
      return ret_val;
    
    }
    
  • Okay... So I was finally able to get this working using the Mode Select as an interrupt connected to pin 2 on the Arduino UNO. The 'waitForBusy' function will not let me receive samples nearly as fast as using the interrupt. Using the interrupt, I am now able to receive distance measurements at about 1000 Hz. 1500 Hz anyone?

  • Has anyone been able to receive 1000+ samples per second with this device? Setting the configuration parameter from 0 to 5 yields similar results for me where I will receive a sample (on average) every 3000 microseconds. Setting "sigCountMax" (Maximum acquisition count) to 1 I am able to get almost 500hz which is not 1500hz. I am using an Arduino UNO at 1Mbaud and the git library for the v3HP. I also setup the external interrupt for busy status (instead of using the waitForBusy funtion) which didn't help much.

  • Jetson tk-1?

  • Okay... So I found this:
    tutorials_93
    Anyone want to modify it to suit our purpose?

  • To help users like BScode this wiki link may be of some use:
    WIKI - Serial_Peripheral_Interface_Bus
    I see a lot of comments about how to re-program the device and I am sure someone knows how. I would also like to change some aspects of the program to properly suit my testing application. Can someone come up with a device programming tutorial?
    From what I can tell there was no boot loader included but according to the ATmega168 specification a boot loader for this device is possible. However, without a boot loader all hope is not lost because it would seem you can program the device using SPI. Is this how you do it Sparkfun? Boot loader anyone?
    Here is the ATmega168 specification:
    ATmega168

No public wish lists :(