I'm trying to follow this tutorial which uses asin() but whatever I do it always returns 0.

asin(27)

asin(27.0)

asin((float)27.0)

All return 0. What am I doing wrong?!

I'm trying to follow this tutorial which uses asin() but whatever I do it always returns 0.

asin(27)

asin(27.0)

asin((float)27.0)

All return 0. What am I doing wrong?!

What am I doing wrong?!

You are not showing your real code. That snippet looks fine, so the culprit is what you are doing with the output from the asin function.

http://www.nongnu.org/avr-libc/user-manual/group__avr__math.html#ga98384ad60834911ec93ac5ae1af4cf0a

The asin() function computes the principal value of the arc sine of __x. The returned value is in the range [-pi/2, pi/2] radians. A domain error occurs for arguments not in the range [-1, +1].

AVR Libc does not produce run-time exceptions. The developers chose to return zero instead.

Yup, that's it, looks like I'm going to need to liberally apply the scale() function...

That tutorial sensibly uses atan2 for compass orientation, but for some obscure reason resorts to asin for tilt. The atan2 approach is superior, since you don't need to calibrate the accelerometer/compass nor to scale its output and it will work with the sensor upside down.

```
float pitchRadians = atan2 (accX, accZ) ;
float rollRadians = atan2 (accY, accZ) ;
```

MarkT:

That tutorial sensibly uses atan2 for compass orientation, but for some obscure reason resorts to asin for tilt. The atan2 approach is superior, since you don’t need to calibrate the accelerometer/compass nor to scale its output and it will work with the sensor upside down.`float pitchRadians = atan2 (accX, accZ) ;`

float rollRadians = atan2 (accY, accZ) ;

When you say that it won’t require calibration/scaling does this assume that both the accelerometer & compass are physically level with each other, with their axis all parallel? If I just replace asin in the tutorial with atan2 as you’ve provided the tilt compensation is completely wrong (applying 150 degrees of compensation to the heading when the compass & accelerometer are flat on the desk).

I'm confused - I'm just showing how to calculate pitch and roll correctly from 3-axis accelerometer data - nothing to do with compass, that's already handled isn't it? The asin method is assuming that the accel data is correctly scaled, and doesn't handle the case where there is acceleration in addition to that due to gravity, nor does it have any meaningful accuracy when the tilt angle approaches 90 to the vertical.

Of course the roll/pitch you get when there is more than just gravity is perhaps less physically meaningful, but atan2 measures the actual angle from the acceleration vector to the z-axis

If you only had 2-axis accelerometer data you'd be forced to resort to asin and assume there was only tilt and no acceleration w.r.t. the earth's surface.