How to convert accelerometer values from -1 / 1 to a full 360°?

A bit more complex than the title makes it sound, lemme explain :

My accelerometer gives me 3 values, X, Y, and Z, that ranges from -1 to 1.

X and Y are linear, while Z is a sine wave.

X is pitch, Y is roll, and Z is... how upward the sensor is ? It's positive while the sensor's up, and as soon as it goes beyond 90° in any angle, it goes negative, so basically Z >0 == upward, Z < 0 == downard.

I got a formula that makes X and Y into degrees, but it only range from -90 to 90°, so for example if I tilt it 120° on the left, it will pass 90°, start decreasing, then end up at about 60°, meaning the only difference a 60 tilt has from a 120° tilt is that Z is < 0, because X will still return 60°.

Here's the formulas, I don't think they're the issue, but who knows :

roll = atan(Y_out / sqrt(pow(X_out, 2) + pow(Z_out, 2))) * 180 / PI;

pitch = atan(-1 * X_out / sqrt(pow(Y_out, 2) + pow(Z_out, 2))) * 180 / PI;

So, what I did was this :

if (roll < 0 and Z_out >= 0) {

Xdeg = abs(roll);

}

if (roll < 0 and Z_out < 0) {

Xdeg = 180 - abs(roll);

}

if (roll > 0 and Z_out < 0) {

Xdeg = 180 + abs(roll);

}

if (roll > 0 and Z_out >= 0) {

Xdeg = 360 - abs(roll);

}

if (pitch < 0 and Z_out >= 0) {

Ydeg = abs(pitch);

}

if (pitch < 0 and Z_out < 0) {

Ydeg = 180 - abs(pitch);

}

if (pitch > 0 and Z_out < 0) {

Ydeg = 180 + abs(pitch);

}

if (pitch > 0 and Z_out >= 0) {

Ydeg = 360 - abs(pitch);

}

And it works ! I get a full 360° reading for both axis, exacly that way I need it for the rest of my program.

Only... it only works for single axis tilt.

So, the issue that I encounter is that, for example, when I tilt it left (so, Roll) more than 90°, then the Pitch get affected when it shouldn't be, as soon as Z_out becomes negative.

So, if I have X=271°, Y=10° and Z > 0, it's all good, and when it becomes X=270 and Z < 0, I get a Y = 170°

Do you have any idea how to get a constant reading where one axis won't mess up the other ? I've been at this for days, it's kinda driving me crazy. I've managed to get a formula to get Z from either X or Y, but I don't see how to make use of it, and it only work on either X or Y anyway, not both at the same time.

Acceleration in Z is gravity, and they're all sines and cosines. If you want a 4-quadrant results for roll and pitch use the 2-term form of arctangent (atan2) instead of atan.

https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing

The formulas you are using are not correct for the usual definition of pitch and roll using Euler angles. The link given in post #2 gives the correct ones (based on one of the more common of the 12 existing definitions).

Even with the correct definition, you won't be able to get "a full 360 degrees" on both pitch and roll axes, due to gimbal lock.

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