A MEMS accelerometer is measuring accelerations of all kinds across its three axes, and through this noise the gravitational vector must be deduced. When the system is at total rest, then acceleration noise is at a minimum and simple math works fine. But when in motion, or more specifically in an environment of vibration energy going in all different directions, it gets to be very difficult.
My suggestion is to filter your accelerometer x, y and z values before your pitch calculation, then filter the output of your pitch calculation.
If you have a way of dumping data out of your system in real time, you could graph what the output of your accelerometer is doing. Then you can simulate and tune filters to best suit your application.
Example filters include IIR, FIR, median, averaging, Kalman, and so on. Each carries their strengths and weaknesses. You can also compound them a bit, depending on what your application needs.
What you'll probably find is that it is actually very difficult to have a stable reading on the gravitational vector in a vibration-heavy environment. As a result, the IMU chip includes the gyro. The gyro will provide you with angular rate data that is very helpful, but is subject to very significant amounts of drift (like several degrees per second). These two very imperfect sensors have to be meshed together to figure out your orientation compared to gravity. Common approaches are:
- High pass filter the gyro and low pass filter the accelerometer.
- Rely on gyro for short-term orientation and attempt to error-correct with long-term accelerometer data.