Orientation problem from inertial module LSM9DS1

Hi everyone.

I am working on a project where i have to determine position and rotation of an IoT object with accelerometer, gyroscope and magnetometer. The goal is to show this object in a Unity3D virtual world.

To do this, i have an Arduino Nano 33 BLE that include a LSM9DS1 as inertial module.
So, i started to determine the rotation of my object. This link was very usefull : accéléromètre et gyroscope MPU6050 - /dev/tbo

That's the line for get the Y axis :
angle=0.98*(angle+float(gy)0.01/131) + 0.02atan2((double)ax,(double)az)*180/PI;

With this one, i can get X, Y and Z angles. When i try one by one axis orientation, all axis rotation are fine. The problem is when i use 2 axis or more at same time. For example, i use only X and Y axis. When i turn only X axis of 90°, Y axis turn of 90° too. This video will explain more accurately than words : Problem Orientation Arduino Nano 33 BLE to Unity - YouTube

I searched lot of things to fix it but now, i have no more idea. Can anyone guide me?

Read about how to post on the forum, then post code, schematics etc. Use code tags.

Thanks, and sorry. I havn't read this post before ask my question ...

This is my complete code :

#include <Arduino_LSM9DS1.h>
#include "math.h"

float ax, ay, az;
float gx, gy, gz;
float anglex=0, angley=0, anglez=0;
unsigned long timer = 0;
void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Started");

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);
  }
}


void loop() {
  timer = millis();
  if (IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
    IMU.readAcceleration(ax, ay, az);
    IMU.readGyroscope(gx, gy, gz);
    
    //Read accelerometer and gyroscope as degree
    
    float atanx = atan2((double)ay,(double)az)*180/PI;
    float gyrox = fmod(double(anglex+float(gx)*0.03/0.762), 360.0);

    float atany = atan2((double)ax,(double)az)*180/PI;
    float gyroy = fmod(double(angley+float(gy)*0.03/0.762), 360.0);

    float atanz = atan2((double)ay,(double)ax)*180/PI;
    float gyroz = fmod(double(angley+float(gy)*0.03/0.762), 360.0);


    //Change value to get a value from 0 to 360°
    
    if (atanx < 0) {
      atanx = atanx + 360;
    }
    if (gyrox < 0) {
      gyrox = gyrox + 360;
    }
    
    if (atany < 0) {
      atany = atany + 360;
    }
    if (gyroy < 0) {
      gyroy = gyroy + 360;
    }

    if (atanz < 0) {
      atanz = atanz + 360;
    }
    if (gyroz < 0) {
      gyroz = gyroz + 360;
    }

    /*
     * Get angle smmoth from gyro and accel. 
     * Tried different way to change coef before gyro and accel.
     * All time coef gyro + coef accel = 1
    */
    anglex=0.6*gyrox + 0.4*atanx;
    angley=0.6*gyroy + 0.4*atany;
    anglez=0.6*gyroz + 0.4*atanz;

    //print values
    Serial.print(anglex);
    Serial.print("/");
    Serial.print(angley);
    Serial.print("/");
    Serial.println(anglez);
    
  }
  delay((0.03*1000) - (millis() - timer));
}

In Unity3D, i just get this values and asign them to an object.

Your video looks like “gimbal lock”, I wonder if your equations and processes have a fundamental difficulty with certain orientations? Perhaps there is some kind of discontinuity that makes passing through that straight up position mathematically fraught.

Only thinging out loud, so to speak.

a7