To be a bit more constructive, here is some code for pitch and roll calculation using 3D accelerometer data, following the guidelines of the Freescale Application Note I linked earlier.
It works very well.
The routine to read the accelerometer (read_accel_raw()) must return signed values for the acceleration along each axis. This is not a complete, working Arduino program, because nothing is assumed about the accelerometer to be used.
// pitch and roll calculated from raw 3D accelerometer readings
// See Freescale Semiconductor Document Number: AN3461
// Application Note Rev. 4, 02/2012
// Tilt Sensing Using Linear Accelerometers
#include <math.h>
#define R2D 180.0/3.14159265
// define a vector data type (3 floats)
typedef struct vector
{
float x, y, z;
} vector;
// vector operators
void vector_cross(vector *a, vector *b, vector *out)
{
out->x = a->y * b->z - a->z * b->y;
out->y = a->z * b->x - a->x * b->z;
out->z = a->x * b->y - a->y * b->x;
}
float vector_dot(vector *a, vector *b)
{
return a->x * b->x + a->y * b->y + a->z * b->z;
}
void vector_normalize(vector *a)
{
float mag = sqrt(vector_dot(a, a));
a->x /= mag;
a->y /= mag;
a->z /= mag;
}
//
// calculate and print pitch and roll from accelerometer data
//
void print_pitch_roll(void) {
vector b = {0,0,0};
vector a = {0,0,0};
int i;
// take 5 acceleration readings and average them
for(i = 0; i < 5; i++)
{
read_accel_raw(&a); //get the accelerometer data
b.x += a.x;
b.y += a.y;
b.z += a.z;
}
b.x /= 5;
b.y /= 5;
b.z /= 5;
vector_normalize(&b);
// here defining pitch as the rotation about X, roll as rotation about Y
// accelerometer X to right, Y backwards, pointing toward the user, Z down
float pitch = R2D*atan2(-b.y, -b.z);
float roll = R2D*atan2(-b.x, sqrt(b.y*b.y + b.z*b.z));
Serial.print("pitch ");
Serial.println(pitch);
Serial.print("roll ");
Serial.println(roll);
}
*** It is probably worth pointing out that the Freescale Application Note boils down to these two lines, with the caution that there are a few orientiations where they won't work as expected. One example is when the z acceleration (b.z) is zero.
float pitch = R2D*atan2(-b.y, -b.z);
float roll = R2D*atan2(-b.x, sqrt(b.y*b.y + b.z*b.z));