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.
BNO055 axes
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO055 axes
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.
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.
- ZAID_ALANI
- Posts: 14
- Joined: Thu Jul 19, 2018 6:22 am
Re: BNO055 axes
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
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
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");
}
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
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO055 axes
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.
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.
- ZAID_ALANI
- Posts: 14
- Joined: Thu Jul 19, 2018 6:22 am
Re: BNO055 axes
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
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
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO055 axes
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.
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.
- ZAID_ALANI
- Posts: 14
- Joined: Thu Jul 19, 2018 6:22 am
Re: BNO055 axes
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.
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.
Please be positive and constructive with your questions and comments.