Keeping the angle measurement the same for holding position

The IMU MPU6050, that I am using, is not providing the same value for the holding position of the actuated object. I started by keeping the object stationary, then pressurized it, and kept it pressurized for 4 sec. and collected the angle position value of sensor. I saw that the sensor was providing gradually decreasing values when it was hold for 4 sec. in pressurized position. So, I wrote the following code to keep its angle measurement the same for holding position.

void MPU6050::update(){
  // retrieve raw data
  this->fetchData();
  
  // estimate tilt angles: this is an approximation for small angles!
  float sgZ = (accZ>=0)-(accZ<0); // allow one angle to go from -180 to +180 degrees
  angleAccX =   atan2(sgZ*accY, sqrt(accZ*accZ + accX*accX)) * RAD_2_DEG; // [-180,+180] deg
  angleAccY =  atan2(accX,     sqrt(accZ*accZ + accY*accY)) * RAD_2_DEG; // [- 90,+ 90] deg

  unsigned long Tnew = millis();
  float dt = (Tnew - preInterval) * 1e-3;
  preInterval = Tnew;

  // Correctly wrap X and Y angles (special thanks to Edgar Bonet!)
  // https://github.com/gabriel-milan/TinyMPU6050/issues/6
   angleX = wrap(filterGyroCoef*(angleAccX + wrap(angleX +     gyroX*dt - angleAccX,180)) + (1.0-filterGyroCoef)*angleAccX,180);
  angleY = wrap(filterGyroCoef*(angleAccY + wrap(angleY + sgZ*gyroY*dt - angleAccY, 90)) + (1.0-filterGyroCoef)*angleAccY, 90);
  angleZ += gyroZ*dt; // not wrapped (to do???)
  float previousangleX = 0;
  float currentangleX = wrap(filterGyroCoef*(angleAccX + wrap(angleX +     gyroX*dt angleAccX,180)) + (1.0-filterGyroCoef)*angleAccX,180);
  if (gyroX < 0.25) {currentangleX = previousangleX;}	  
  previousangleX = currentangleX;

}

Now, I am reading currentangleX from the sensor instead of the angleX. But the code is not working. I am getting all 0 angle for all position. What change should I make?
This is the source code that I am editing: GitHub - rfetick/MPU6050_light: Lightweight, fast and simple library to communicate with the MPU6050
The following figure will be helpful to understand my problem. This diagram is obtained before updating the source code.

A zero result of a multiplication means that one of your inputs is a zero, which usually sneaks in by an undefined value. Make sure you can see each individual value to verify it is not zero. I think it is the 1e-3 which might be "too small" and rounds to zero.

Your topic was moved to its current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

It will help you get the best out of the forum in the future.

Thank you

I feel like the problem is defining the float previousangleX = 0; in the loop. How can I set previousangleX's initial value as 0 and keep it outside of the loop?

Please note that everything works fine with the source code and I only added last 4 lines in the code (from float previousangleX = 0; to previousangleX = currentangleX;)

Have you tried defining it globally? (or does that badly effect other calculations)

Unfortunately, it is still the same when I moved the float previousangleX = 0 outside of the loop and defined it in the private variable section of the MPU6050_light.h file of the source code.

For stationary tilt angle measurements, use only the accelerometer. The gyro contributes nothing but noise and drift errors, which can be quite large if you don't calibrate the gyro properly.

Tutorial here: How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing-DFRobot

1 Like

I tried and it didn't work, too! You can see, this is graph I got for the angle measured by the accelerometer. In the holding part, it returns to zero and does not keep its position at -40 degrees (and sometimes provides more angle that the actual angle). Accelerometer uses this equation to measure the angle:

angleAccX =   atan2(sgZ*accY, sqrt(accZ*accZ + accX*accX)) * RAD_2_DEG; // [-180,+180] deg

question to arduino forum

This is clearly wrong. What is sgZ?

angleAccX =   atan2(sgZ*accY, sqrt(accZ*accZ + accX*accX)) * RAD_2_DEG;

There may be other errors, so post all the code, using code tags.

Here are the correct formulas, from the tutorial linked above.

  roll = atan2(y_Buff , z_Buff) * 57.3;
  pitch = atan2((- x_Buff) , sqrt(y_Buff * y_Buff + z_Buff * z_Buff)) * 57.3;

That's not wrong, the method in the tutorial is not the only way of measuring roll, pitch and yaw.
For sgZ, please check the source code which is available at GitHub - rfetick/MPU6050_light: Lightweight, fast and simple library to communicate with the MPU6050

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