BNO055 axes

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
ZAID_ALANI
 
Posts: 14
Joined: Thu Jul 19, 2018 6:22 am

Re: BNO055 axes

Post by ZAID_ALANI »

I do not know how to thank you for your cooperation.
I will follow your procedure tomorrow
(since I left the office now) and will tell you
about the results.
I hope I can get the right results this time and get the right rotation for my moving object.


Thanks again.

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: BNO055 axes

Post by gammaburst »

You're welcome!

If you get the same results as mine, and if the results seem bizarre or wrong to you, then that's a very common reaction to Euler angle behavior. It's NOT intuitive, and it's rather difficult to explain in words. Many folks find it helpful to see a 3D visualization alongside the Euler angles.

User avatar
ZAID_ALANI
 
Posts: 14
Joined: Thu Jul 19, 2018 6:22 am

Re: BNO055 axes

Post by ZAID_ALANI »

I have done what you mentioned and I got good results.
thank you gammaburst.
I also use your code with other just to save the calibration data and use it again so that I do not have to do the calibration each time. The code I am using right now is

Code: Select all

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


char flag;
const uint16_t t1_comp = 20000;
const int led_pin = PB5;
// Counter and compare values
const uint16_t t1_load = 0;

/*To get calibration values, comment out "setCal();" , uncomment "setCalStat();" 
 Start the Serial Monitor and move the sensor around until all calibration status 
 reach a value of 3. When the calibration status of each are 3, the calibration values will print 
than the sketch stops so you can copy the values. 
Put these values into the setCal() function of the sketch.
To use, uncomment "setCal();", uncomment "setCalStat();", load and run.*/



/* This driver uses the Adafruit unified sensor library (Adafruit_Sensor),
   which provides a common 'type' for sensor data and some helper functions.
   
   To use this driver you will also need to download the Adafruit_Sensor
   library and include it in your libraries folder.

   You should also assign a unique ID to this sensor for use with
   the Adafruit Sensor API so that you can identify this particular
   sensor in any data logs, etc.  To assign a unique ID, simply
   provide an appropriate value in the constructor below (12345
   is used by default in this example).
   
   Connections
   ===========
   Connect SCL to analog 5
   Connect SDA to analog 4
   Connect VDD to 3-5V DC
   Connect GROUND to common ground
    
   History
   =======
   2015/MAR/03  - First release (KTOWN)
   2015/Mar/12  - Dave's mod - calibration
*/

/* Set the delay between fresh samples */
#define BNO055_SAMPLERATE_DELAY_MS (100)
   
Adafruit_BNO055 bno = Adafruit_BNO055(55);


/**************************************************************************/
/*
    Displays some basic information on this sensor from the unified
    sensor API sensor_t type (see Adafruit_Sensor for more information)
*/
/**************************************************************************/
void displaySensorDetails(void)
{
  sensor_t sensor;
  bno.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" xxx");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" xxx");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" xxx");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

/**************************************************************************/
/*
    Arduino setup function (automatically called at startup)
*/
/**************************************************************************/
void setup(void) 
{
  Serial.begin(115200);
  Serial.println("Orientation Sensor Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
  setCal();       // Set Calibration Values - Comment out to read calibration values

  delay(1000);

    
    
  /* Display some basic information on this sensor */
  displaySensorDetails();

  bno.setExtCrystalUse(true);  
//////////////////////
  flag=0;
    int eeAddress = 0;
    long bnoID;
    bool foundCalib = false;
    EEPROM.get(eeAddress, bnoID);

  //Set LED pin to be output
     DDRB |= (1 << led_pin);
     
  // Reset Timer1 control Reg A
     TCCR1A = 0;
// Set to prescalee of 8
     TCCR1B &= ~(1 << CS12); 
     TCCR1B |= (1 << CS11);
     TCCR1B &= ~(1 << CS10);
     // Reset Timer1 and set compare value
     TCNT1 = t1_load;
     OCR1A = t1_comp;
 // Enable Timer1 compare Interrupt
     TIMSK1 = (1 << OCIE1A);
     
  // Enable global interupt
     sei();
}

/**************************************************************************/
/*
    Arduino loop function, called once 'setup' is complete (your own code
    should go here)
*/
/**************************************************************************/
void loop(void) 
{
  
if (flag == 1)
  {
  /* Get a new sensor event */ 
//  getCalStat();                  // Uncomment to get calibration values

/* Convert quaternion to Euler, because BNO055 Euler data is broken */
            sensors_event_t event;
            bno.getEvent(&event);

            Serial.print(event.orientation.x);    Serial.print("   ");
            Serial.print(event.orientation.y);    Serial.print("   ");
            Serial.print(event.orientation.z);    Serial.print("   ");

            
  imu::Quaternion q = bno.getQuat();

  float temp = q.x();  q.x() = q.y();  q.y() = temp;   q.z() = -q.z(); q.normalize();
  float heading = 180/M_PI * atan2(q.x()*q.y() + q.w()*q.z(), 0.5 - q.y()*q.y() - q.z()*q.z());
  float pitch   = 180/M_PI * asin(-2.0 * (q.x()*q.z() - q.w()*q.y()));
  float roll    = 180/M_PI * atan2(q.w()*q.x() + q.y()*q.z(), 0.5 - q.x()*q.x() - q.y()*q.y());
  heading = heading < 0 ? heading+360 : heading;  // wrap heading to 0..360 convention

  //Serial.print(F("HeadingPitchRoll: "));
    Serial.print(heading);  // heading, nose-right is positive
    Serial.print(F("   "));
    Serial.print(pitch);    // pitch, nose-up is positive
    Serial.print(F("   "));
    Serial.print(roll);     // roll, leftwing-up is positive
    Serial.print(F("   "));

//  double yy = q.y() * q.y(); // 2 Uses below
//  double roll = atan2(2 * (q.w() * q.x() + q.y() * q.z()), 1 - 2*(q.x() * q.x() + yy));
//  double pitch = asin(2 * q.w() * q.y() - q.x() * q.z());
//  double yaw = atan2(2 * (q.w() * q.z() + q.x() * q.y()), 1 - 2*(yy+q.z() * q.z()));
//  float rollDeg  = 57.2958 * roll;
//  float pitchDeg = 57.2958 * pitch;
//  float yawDeg   = 57.2958 * yaw;
                            
 /*  Display Roll, Pitch, and Yaw in Radians and Degrees*/
//  Serial.print(rollDeg,3);    Serial.print("   ");
//  Serial.print(pitchDeg,3);   Serial.print("   ");
//  Serial.print(yawDeg,3);     Serial.print("   ");
//
//  imu::Vector<3> euler = q.toEuler();
////  Serial.print(F("Orientation: "));
//  Serial.print(-180/M_PI * euler.x(),3);  // heading, nose-right is positive, z-axis points up
//  Serial.print(F("   "));
//  Serial.print(-180/M_PI * euler.y(),3);  // roll, rightwing-up is positive, y-axis points forward
//  Serial.print(F("   "));
//  Serial.print(-180/M_PI * euler.z(),3);  // pitch, nose-down is positive, x-axis points right
//  Serial.print(F("   "));

  imu::Vector<3> Acc = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
  Serial.print(Acc.x());    Serial.print("  ");
  Serial.print(Acc.y());    Serial.print("  ");
  Serial.print(Acc.z());   Serial.println("  ");
  flag = 0;
  }
}


void setCal(){
  // DAVES MOD - Writes calibration data to sensor//
  byte calData;
  bno.setMode( bno.OPERATION_MODE_CONFIG );    // Put into CONFIG_Mode
  delay(25);
  
  calData = bno.setCalvalARL(232);
  
  calData = bno.setCalvalARM(3);
  
  calData = bno.setCalvalMRL(190);
  
  calData = bno.setCalvalMRM(2);
  
  calData = bno.setCalvalAOXL(253);
  
  calData = bno.setCalvalAOXM(255);
  
  calData = bno.setCalvalAOYL(243);
  
  calData = bno.setCalvalAOYM(255);
  
  calData = bno.setCalvalAOZL(22);
 
  calData = bno.setCalvalAOZM(0);
  
  calData = bno.setCalvalMOXL(221);
  
  calData = bno.setCalvalMOXM(0);
  
  calData = bno.setCalvalMOYL(204);
 
  calData = bno.setCalvalMOYM(0);
 
  calData = bno.setCalvalMOZL(4);
  
  calData = bno.setCalvalMOZM(0);
  
  calData = bno.setCalvalGOXL(255);
  
  calData = bno.setCalvalGOXM(255);
  
  calData = bno.setCalvalGOYL(253);
  
  calData = bno.setCalvalGOYM(255);
  
  calData = bno.setCalvalGOZL(0);
  
  calData = bno.setCalvalGOZM(0);
  
  bno.setMode( bno.OPERATION_MODE_NDOF );    // Put into NDOF Mode
  delay(25);
}

void getCal(){
  // Dave's Mod - Reads Calibration Data when sensors are calibrated
  byte calData;
  bno.setMode( bno.OPERATION_MODE_CONFIG );    // Put into CONFIG_Mode
  
  calData = bno.getCalvalARL();
  Serial.println(calData);
  
  calData = bno.getCalvalARM();
  Serial.println(calData);
  
  calData = bno.getCalvalMRL();
  Serial.println(calData);
  
  calData = bno.getCalvalMRM();
  Serial.println(calData);
  
  calData = bno.getCalvalAOXL();
  Serial.println(calData);
  
  calData = bno.getCalvalAOXM();
  Serial.println(calData);
  
  calData = bno.getCalvalAOYL();
  Serial.println(calData);
  
  calData = bno.getCalvalAOYM();
  Serial.println(calData);
  
  calData = bno.getCalvalAOZL();
  Serial.println(calData);
 
  calData = bno.getCalvalAOZM();
  Serial.println(calData);
  
  calData = bno.getCalvalMOXL();
  Serial.println(calData);
  
  calData = bno.getCalvalMOXM();
  Serial.println(calData);
  
  calData = bno.getCalvalMOYL();
  Serial.println(calData);
 
  calData = bno.getCalvalMOYM();
  Serial.println(calData);
 
  calData = bno.getCalvalMOZL();
  Serial.println(calData);
  
  calData = bno.getCalvalMOZM();
  Serial.println(calData);
  
  calData = bno.getCalvalGOXL();
  Serial.println(calData);
  
  calData = bno.getCalvalGOXM();
  Serial.println(calData);
  
  calData = bno.getCalvalGOYL();
  Serial.println(calData);
  
  calData = bno.getCalvalGOYM();
  Serial.println(calData);
  
  calData = bno.getCalvalGOZL();
  Serial.println(calData);
  
  calData = bno.getCalvalGOZM();
  Serial.println(calData);
  
  while(1){                              // Stop
    delay(1000);
  }
  
  
}
void getCalStat(){
  // Dave's Mod - Move sensor to calibrate, when status shows calibration, read values
byte cal = bno.getCalib();
  byte calSys = (0xC0 & cal) >> 6;
  byte calGyro = (0x30 & cal) >> 4;
  byte calAccel = (0x0C & cal) >> 2;
  byte calMag = (0x03 & cal) >> 0;
  
  Serial.println(cal);
  Serial.print("System calibration status "); Serial.println(calSys);
  Serial.print("Gyro   calibration status "); Serial.println(calGyro);
  Serial.print("Accel  calibration status "); Serial.println(calAccel);
  Serial.print("Mag    calibration status "); Serial.println(calMag);
  
  delay(1000);
  if (cal==255){
    getCal();
  }
}

ISR(TIMER1_COMPA_vect)
{
  TCNT1 = t1_load;
  //PORTB ^=(1 << led_pin);
  flag = 1;
//  time = millis();
//  Serial.print(time);
//  Serial.print("\t\t");
}
Do you have any comment about this code?
Also, I am trying to get the acceleration ( as you can see from the code) so that I can integrate it twice to get the position but unfortunately the results of integration are not right. I did three sessions of moving a body for a same short distance in 1 D ( about 60 cm in one direction) and when I integrated the acceleration I got very strange results like there is no indication about that distance. Do you have any suggestion?

thank you in advance

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: BNO055 axes

Post by gammaburst »

I commented-out your lines related to setcal* and getcal* because my Arduino installation doesn't have those functions.

I see your sketch outputs BNO Euler angles, quaternion-converted Euler angles, and linear acceleration.

I don't see any integration code in your project.

To integrate a sampled signal, you basically sum the data samples, multiply by the time increment, and add the initial condition.

Remember, with double-integration, small sensor errors accumulate rapidly and severely.

User avatar
ZAID_ALANI
 
Posts: 14
Joined: Thu Jul 19, 2018 6:22 am

Re: BNO055 axes

Post by ZAID_ALANI »

Thank you for all your cooperation, yes I know about the integration, actually I take the acceleration data the I do the integration using MATLAB and as I told you the resulting position is not right. Do you have any suggestion about that?

Also, I will post the modified library for BNO055 tomorrow to enable you to work with code and I will be happy to know your opinion about it.

Best regards

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: BNO055 axes

Post by gammaburst »

It sounds like you now have good Euler data from the BNO055.
If that's correct, then it's time to close this discussion rather than continuing to new topics.
This forum is for discussing Adafruit products. Math and coding belong somewhere else.

User avatar
ZAID_ALANI
 
Posts: 14
Joined: Thu Jul 19, 2018 6:22 am

Re: BNO055 axes

Post by ZAID_ALANI »

Yes, you are right and thank you for your help.
I am now trying to get the position as I mentioned before, the problem is I can not get a correct data for that. I am using the same code I posted before to get LINEARACCEL. then after integration twice I got a position data that are not even near my real movement. ( I applied low pass filter for acceleration, velocity, and position data).
Please if you have any suggestion posted here.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”