For my inclinometer application, I use an integrated 3-D accelerometer chip that outputs analog voltage.

Before I deploy my device, I submit it collect a bunch of samples with different temperature and angles for temperature compensation.

The problem I am experiencing is that voltage outputs for each individual axis are not completely independent. For the same temperature, if one axis is kept constant and the other changes, the former will output some change as well.

For example, let's say I'm measuring "g" on the pitch axis and the output is zero when the roll axis is zero. If I roll the accelerometer to one side, I get the corresponding roll "g", but pitch will have a slight change (+/- 2 degrees), even though pitch is still zero.

Any ideas on how to achieve better precision out of this?

  • 1
    \$\begingroup\$ How are you rolling your device - do you know you're not giving it a pitch change of 2 degrees? The mounting error due to soldering might be that small. If you're fairly certain the mounting is good, then a more precise fixture might be the ticket. Also, what accelerometer are you using? Many have a function by which they can be trimmed, or have a +/- 2 degree (or worse) error bound. \$\endgroup\$ Jul 20, 2010 at 3:11
  • 1
    \$\begingroup\$ I'm using a high precision 6DOF manipulator. It gives me 0.01 degrees accuracy in all axes. Mounting is done by pick and place. The sensor is a freescaleMMA7361LC. \$\endgroup\$ Jul 20, 2010 at 16:07

2 Answers 2


Let's put together a simple mathematical model of an accelerometer - from this, we can work out some calibration options.

Ignoring non-linearity and other nasty effects, the output measurement of an accelerometer is given by:

$$\hat{\mathbf{f}} = \mathbf{M} \mathbf{f} + \mathbf{b}_a + \mathbf{n}_a$$

where \$\hat{\mathbf{f}}\$ is the actual measurement, \$\mathbf{b}_a\$ is the accelerometer bias, \$\mathbf{n}_a\$ is a random noise vector, \$\mathbf{f}\$ is the true specific force (i.e. acceleration) and \$\mathbf{M}\$ is the Scale Factor/Misalignment Matrix.

The individual elements of the SFA matrix are: $$ \mathbf{M} = \begin{bmatrix} S_x && \gamma_{xy} && \gamma_{xz} \\ \gamma_{yx} && S_{yy} && \gamma_{yz} \\ S_x && \gamma_{zy} && S_{zz} \\ \end{bmatrix} $$

So, each scale factor is represented by an \$S\$ and each cross-axis sensitivity is represented by a \$\gamma\$.

Ideally, if the scale factor is 1 and there is no cross-axis sensitivity, then then the resulting matrix is \$\mathbf{M} = \mathbf{I}\$.

Representing it like this allows us to develop a compensation model. If we happen to know \$\mathbf{M}\$ and \$\mathbf{b}_a\$ and assume \$\mathbf{n}_a\$ to be small (i.e. close to zero), we can make a good estimate of the "true" acceleration from the measurements: $$ \mathbf{f} = \mathbf{M}^{-1}\left(\hat{\mathbf{f}} - \mathbf{b}_a\right) $$

The trick is, of course, working out \$\mathbf{M}\$ and \$\mathbf{b}_a\$.

I'll describe a procedure called the six position test, which is an easy and cheap way to calibrate an accelerometer. Step 1 is to mount the accelerometer in a rectangular box with perfectly \$90^\circ\$ sides (or as close as you can get). Place this on a perfectly level surface (or, again, as close as you can get) - you'd be surprised how good you can do this.

At this point, we know what the value should be: gravity on the z-accelerometer: $$ \mathbf{f}_1 = \begin{bmatrix} 0 \\ 0 \\ g\end{bmatrix} $$

So, this becomes: $$ \hat{\mathbf{f}}_1 = \mathbf{M} \mathbf{f}_1 + \mathbf{b}_a + \mathbf{n}_a $$ Noting that \$\hat{\mathbf{f}}_1\$ will close, but not the same as \$\mathbf{f}_1\$

If we put the box on it's head, the force acting is \$-g\$: $$ \mathbf{f}_2 = \begin{bmatrix} 0 \\ 0 \\ -g\end{bmatrix} $$

And when placed on one side: $$ \mathbf{f}_3 = \begin{bmatrix} 0 \\ -g \\ 0\end{bmatrix} $$

And so on for the remaining three sides.

Now, let's write out one of the equations longhand: $$ \hat{\mathbf{f}}_1 = \mathbf{M} \mathbf{f}_1 + \mathbf{b}_a + \mathbf{n}_a = \begin{bmatrix} S_{xx} f_x + \gamma_{xy} f_y + \gamma_{xz} f_z + b_x \\ \gamma_{yx} f_x + S_{yy} f_y + \gamma_{yz} f_z + b_y \\ \gamma_{xz} f_x + \gamma_{yz} f_y + S_{zz} f_z + b_z \end{bmatrix} $$

And even longer hand (for the first one): $$ \hat{\mathbf{f}}_1 = \begin{bmatrix} f_x S_{xx} + f_y \gamma_{xy} + f_z \gamma_{xz} + 0 \gamma_{yx} + 0 S_{yy} + 0 \gamma_{yz} + 0 \gamma_{xz} + 0 \gamma_{yz} + 0 S_{zz} + 1 b_x + 0 b_y + 0 b_z \\ 0 S_{xx} + 0 \gamma_{xy} + 0 \gamma_{xz} + f_x \gamma_{yx} + f_y S_{yy} + f_z \gamma_{yz} + 0 \gamma_{xz} + 0 \gamma_{yz} + 0 S_{zz} + 0 b_x + 1 b_y + 0 b_z \\ 0 S_{xx} + 0 \gamma_{xy} + 0 \gamma_{xz} + 0 \gamma_{yx} + 0 S_{yy} + 0 \gamma_{yz} + f_x \gamma_{xz} + f_y \gamma_{yz} + f_z S_{zz} + 0 b_x + 0 b_y + 1 b_z \end{bmatrix} $$

So we can create a stacked vector of the unknowns $$ \mathbf{z} = \mathbf{A} \mathbf{\beta} $$ Where $$ \mathbf{z} = \begin{bmatrix} \hat{\mathbf{f}}_1 \\ \hat{\mathbf{f}}_2 \\ \vdots \\ \hat{\mathbf{f}}_6 \end{bmatrix} $$

And $$ \mathbf{\beta} = \begin{bmatrix} S_{xx} \\ \gamma_{xy} \\ \gamma_{xz} \\ \gamma_{yx} \\ S_{yy} \\ \gamma_{yz} \\ \gamma_{xz} \\ \gamma_{yz} \\ S_{zz} \\ b_x \\ b_y \\ b_z \\ \end{bmatrix} $$

The design matrix is (for one set of measurements): $$ \hat{A}_1 = \begin{bmatrix} f_x && f_y && f_z && 0 && 0 && 0 && 0 && 0 && 0 && 1 && 0 && 0 \\ 0 && 0 && 0 && f_x && f_y && f_z && 0 && 0 && 0 && 0 && 1 && 0 \\ 0 && 0 && 0 && 0 && 0 && 0 && f_x && f_y && f_z && 0 && 0 && 1 \end{bmatrix} $$

Now, once this is setup, one may solve for \$\mathbf{\beta}\$ (and hence sensitivity and bias) via least squares.

A similar procedure may be performed with a robotic arm if you can precisely control the angles - it simply replies knowing the precise gravity at that angle which, if you know the angle, is easy to calculate.


If you look at the datasheet for the chip you'll find there is a spec for the cross axis sensitivity. So what you're seeing is just part of the limitations of the device.

You might be able to calibrate it out if you restrict the movement to one axis only. If you are allowing it to move in any axis then I don't think it is possible with only an accelerometer if the second axis is changing because of cross axis sensitivity or because of a change in angle/acceleration on that axis.

If you added in some other sensors - gyroscopes or magnetic field - you might be able to combine all the sensor data to work it out.

  • 2
    \$\begingroup\$ Nice first post, and welcome to the site. Yes, even the highly accurate Bosch BMA180 has a cross axis sensitivity of 1.75%. So, a 90 degree change in one axis might cause a 1.57 degree readout on the others, and this may change every time you move it. An additional factor is the alignment error - Again, the BMA180 is only specified to be within +/- 1 degree relative to the case, but this is a constant for every physical chip and can therefore be calibrated out in software by your tester. \$\endgroup\$ Jul 20, 2010 at 14:07
  • 1
    \$\begingroup\$ I've collected a bunch of points at several pitches and rolls. I've plotted several lines characterizing the x-axis sensitivity and I was going to try to compensate the readouts using these compensation equations... \$\endgroup\$ Jul 20, 2010 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.