Problem using 2 Adafruit BNO055 sensors

Hi everyone, I'm working on a project that involves 2 BNO055 sensors for getting the angle of one sensor relative to the other. Indeed, the project consist in understanding if the bow used by the cellist is in in the correct position (that should be always perpendicular to the strings).

Specifically for this project I'm using Teensy 3.6, but I think it shouldn't be an issue. Each sensor is connected to a different I2C port of the Teensy.

The 2 sensors are used in the following way:

  • sensor 1 is ideally mounted on the instrument body;
  • sensor 2 is ideally mounted on the bow.

I'm having some issues regarding the "roll" angle data that I get. I don't know why sometimes the "roll" value (that is the one I'm using for getting the angle among sensors) change "scale", turning from 0° to something else without actually changing its inclination in that axis.

So, for example, at the beginning the "roll" value in a certain position is 0°:

Then, I start using it, it displays correct data, for instance here it's correctly displaying 45° (more or less):

But then, it becomes 100° when I perform broad movements (especially on the pitch) and it "decides" that the "new value" in that same specific position is 100°:

Since I'm not very familiar with quaternions calculation, I suspect it might be something related to the translation process (quaternions -> degrees) but I'm not sure.

If you could help me, it would be super nice! Thank you :slight_smile:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>

Adafruit_BNO055 bno1 = Adafruit_BNO055(55, 0x28, &Wire);
Adafruit_BNO055 bno2 = Adafruit_BNO055(55, 0x28, &Wire1);

//original quaternions obtained from the sensor
imu::Quaternion quaternion1;
imu::Quaternion quaternion2;

//reference quaternions, for setting the "0"
imu::Quaternion quaternion_reference_1;
imu::Quaternion quaternion_reference_2;

//actual quaternion zero
imu::Quaternion quaternion_zero_1;
imu::Quaternion quaternion_zero_2;

void setup() {
  Serial.begin(9600);

  Wire.begin();
  Wire1.begin();

  //control if everything is well connected
  if (!bno1.begin()) {
    Serial.println("Failed to initialize BNO055 sensor 1. Check your wiring!");
    while (1)
      ;
  }

  if (!bno2.begin()) {
    Serial.println("Failed to initialize BNO055 sensor 2. Check your wiring!");
    while (1)
      ;
  }

  /* Use external crystal for better accuracy */
  bno1.setExtCrystalUse(true);
  bno2.setExtCrystalUse(true);

  delay(1000);
}

void loop() {
  sensors_event_t event1;
  sensors_event_t event2;

  // Get the first quaternion orientation from BNO055 sensor 1
  bno1.getEvent(&event1);
  imu::Quaternion quaternion_1 = bno1.getQuat();

  // Get the second quaternion orientation from BNO055 sensor 2
  bno2.getEvent(&event2);
  imu::Quaternion quaternion_2 = bno2.getQuat();

  // set "0" during the first 5 seconds of activity
  if (millis() < 5000) {
    quaternion_reference_1 = bno1.getQuat();
    quaternion_reference_2 = bno2.getQuat();
  }

  // Set the zero-point quaternion
  quaternion_zero_1 = quaternion_reference_1.conjugate();
  quaternion_zero_2 = quaternion_reference_2.conjugate();

  // Set zero for quaternion 1 and 2
  imu::Quaternion quaternion_relative_1 = quaternion_1 * quaternion_zero_1;
  imu::Quaternion quaternion_relative_2 = quaternion_2 * quaternion_zero_2;

  // Calculate the angular difference between relative quaternions
  imu::Quaternion quaternion_difference = quaternion_relative_1 * quaternion_relative_2.conjugate();

  // Convert quaternion to Euler angles
  imu::Vector<3> eul = quaternion_difference.toEuler();

  double roll = eul.x();
  double pitch = eul.y();
  double yaw = eul.z();

  //from rad to deg
  roll = roll * (180 / 3.1415);
  pitch = pitch * (180 / 3.1415);
  yaw = yaw * (180 / 3.1415);

  // Print the Euler angles in degrees
  Serial.print("Roll: ");
  Serial.print(roll);
  Serial.print(" degrees\tPitch: ");
  Serial.print(pitch);
  Serial.print(" degrees\tYaw: ");
  Serial.print(yaw);
  Serial.println(" degrees");

  delay(100);
}

Images of text are useless. Please post text as text, using copy/paste and code tags.

Euler angles are very problematic, as there are no international standards, and twelve differently defined Euler angle systems to choose from. There is also the problem of gimbal lock in certain orientations.

Given the poor performance of the BNO055 (especially in the yaw angle), the orientation won't be very accurately determined, and calculating differences in orientation dramatically increases the experimental error.

Unless you understand the math, the Euler angle system definition and take into account the poor performance of this choice of sensor, the project is not likely to succeed.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.