# Problem with angle calculation

I'm using MPU6050(accelerometer+gyro) connected to ATmega328P microcontroller, but probably it isn't even important in my case.

In my project, I need an angle around the X axis. And it's calculated like this:

angle = -(atan2(acc.XAxis, sqrt(acc.YAxis*acc.YAxis + acc.ZAxis*acc.ZAxis))*180.0)/M_PI;


where acc is vector of accelerations in all directions.

The problem is, that it gives me credible value only when angle between Z axis and ground is right (so it's not rotated around Y axis). When I start to rotate it around Y axis it also changes value of X axis rotation.

I know, that it's due to YAxis acceleration in my algorithm, but I have no idea how to get rid of it.

How can I solve this problem?

• Does the acc vector include acceleration due to gravity? – Christo Jan 3 '17 at 0:41
• Where did you get the equation from? If you have gyroscopes, why are you using accelerometers to calculate angles? Why write your code from scratch when there is freely available code that does it for you? – Chuck Jan 3 '17 at 16:49
• Please more clearly explain the values that you get that you feel are not credible, and what the system attitude is that creates them. Give numerical examples if possible. – mikeTronix Jan 4 '17 at 21:13
• I realize that you may be talking about accelerations which are due to rotating your system about a point different than its IMU center point. That will cause a transverse acceleration due to the lever arm effect i.e. "omega cross r". You would need to explicitly compensate for this, using your gyros ("omega") and the known lever arm vector "r". Then you can apply the angle finding above. – mikeTronix Jan 4 '17 at 21:22
• To be more precise - I use kalman filter to calculate angle more accurately. It gets angle from the algorithm above and data from gyroscope about angular velocity around axis. But I checked it and kalman filter isn't a problem in this case, cause it happens also with raw angle calculated from accelerations @Chuck I got it from website which unfortunately isn't available in english. But here is the same (I have wrong naming so X and Y are swapped) – JanW Jan 4 '17 at 22:06

Your equation is formed so that the angle can be zero only when the projection of the gravity vector onto the X axis is zero. That gives zero when the system is oriented vertically, because the gravity vector is aligned with the -Y axis. But you also will get a zero angle result if the gravity vector lies exactly in the Y-Z plane, regardless of the system's angle to the vertical. That's because there is no projection of the gravity vector into the X direction in that scenario, no matter how you twist the system about the X axis.

If you just want the angle of tilt of your system from the vertical, use:

tilt = acos(-acc.Yaxis)

which will be zero when your system is vertical, and +/- 90 degrees when the system is as far away from vertical as possible.

Angles must always be defined very specifically to match the way you want to use them. I recommend drawing a diagram and using trigonometry to derive the equations that you use to compute them. Don't forget that in 3D, multiple angles must always be applied in a specific order, and their values interact within the final result.

• I don't think this is quite what OP was looking for. OP said they can already find the angle about the x-axis, but the problem they were having was the fact that rotation about their alternate axis caused the readings to be skewed. You touch briefly on the subject (it is because of how gravity is projected onto the plane), but then proceed to give OP the answer they already had. In your drawing, what is "tilt"? Z-axis rotation? What is happens to tilt if you rotate the x-axis? That's OP's problem - a tilt reading occurs regardless of input axis and/or the two axes interfere with the reading. – Chuck Jan 6 '17 at 13:40
• Okay, I see where you're going here. I was alluding to the equation being the wrong one, but I should have been more straightforward. The problem is that the equation OP provided doesn't give an angle of rotation about the X-axis, as he expected. It gives the deviation of the gravity vector from the YZ plane. The equation of rotation about the X axis would be: theta = atan2(acc.Zaxis, acc.Yaxis), assuming we want vertical to be the zero angle. – mikeTronix Jan 6 '17 at 15:27
• I agree; that's the comment I made to the question. OP states, "I'm using MPU6050(accelerometer+gyro)" but then goes on to ask about using the accelerometer to measure angles. That's what the gyro is for! It can still be done with accelerometers, but also as I mentioned that math has already been done and is freely available. – Chuck Jan 6 '17 at 19:32
• MEMS Gyros measure angular rates, not angles. Although angular rates can be integrated over time to get difference angles, a zero reference is required somewhere. Some applications just use use an initial starting position as zero reference, but depending on the quality of the gyros, drift due to gyro bias occurs either sooner or later. – mikeTronix Jan 15 '18 at 22:05