Looking for very specific support developing a simple Python script to take the time series X,y,z tuple readings from a triple axis accelerometer and output a meaningful measure of vibration for rotating machinery anomaly detection.

I am using an LiS3dh but not sure how to take the three axis time series data and calculate mm/s + acceleration, velocity etc

I’m swimming in references to RMS, FFT and PSD

Can someone help me understand how to take the accelerometer readings and actually output something meaningful for vibration that could be displayed on a graph?

How do you account for the three axes? Is there a method to combine this data into a single reading? Where doesn’t PSd/FFT come in? Help please!

Will ultimately need to write this in Python so code based examples would help, but any mathematical explanation would be helpful.


1 Answer 1


If you are not aware of vector math then perhaps now is the time.

You can use vectors to represent the direction of all three component accelerations as a single magnitude along with a direction with which you can then perform operations on.

If the accerlerometer spits out:

$a_x = 1/m/s^2$

$a_y = -3/m/s^2$

$a_x = 5/m/s^2$

Then those are component accelerations along each axis. They are components of an acceleration in a single direction. That acceleration is described by the acceleration vector:

$$\vec{a} =[a_x,a_y,a_z] = [1, -3, 5] = 1\hat{i} - 3\hat{j} +5\hat{k}$$

$\hat{i},\hat{j},\hat{k}$ are unit vectors. Not only are they unit vectors they are basis vectors. A unit vector is a vector that only specifies a direction and not a magnitude. A basis vector is a unit vector that points along an axis which provides the basis of our coordinate system.

Unit vectors (and basis vectors by extension) have a magnitude of 1 which means if you multiply them by a scalar, the magnitude does not change. All that happens is that a direction is imparted to the scalar and a magnitude is imparted to the direction. Since $\hat{i},\hat{j},\hat{k}$ here are each basis vectors which point straight along the x, y, and z axis respectively:

$\hat{i} = [1,0,0]=1\hat{i} + 0\hat{j} + 0\hat{k}$

$\hat{j} = [0,1,0]=0\hat{i} + 1\hat{j} + 0\hat{k}$

$\hat{k}= [0,0,1]=0\hat{i} + 0\hat{j} + 1\hat{k}$

Note how they each have a magnitude of 1, as unit vectors and basis vectors should.

They are used similar to identify what axis a number is on similar to how $i$ or $j$ is used in complex numbers to identify if a number is on the real axis or imaginary axis.

But $\hat{i},\hat{j},\hat{k}$ do not represent $\sqrt(-1)$ so don't treat it that way. You can add them together with each other or multiply them with scalars as if they were normaly variables. However, you cannot multiply or divide them with each other. It has no meaning They have an equivalents called dot and cross product which behave differently than multiplication and division which I won't go into here.

If you vector sum the magnitude scalars associated with these basis vectors, this gives you the magnitude and direction of the acceleration. This is similar to Pythagoras but Pythagoras is on a 2D plane and this is 3D.

So the magnitude would be: $$|\vec{a}|=\sqrt{a_x^2+a_y^2+a_z^2} = \sqrt{1^2+(-3)^2+5^2}=5.91$$

And the direction is represented by a unit vector: $$\hat{a}=\frac{\vec{a}}{|\vec{a}|} = \frac{1\hat{i} - 3\hat{j} +5\hat{k}}{5.91}= 0.169\hat{i}-.508\hat{j}+ 0.846\hat{k}$$

Notice how we divided the original vector by its magnitude? That means the result has a magnitude of 1 as a unit vector should. It is one because we divided it by itself. You can verify that this is true by calculating the magnitude of the unit vector via $|\vec{u}|=\sqrt{u_x^2+u_y^2+u_z^2}$.

This means we can also write our original acceleration so that the magnitude and direction are split up as: $$\vec{a} = |\vec{a}|\hat{a}= 5.91(0.169\vec{i}-.508\vec{j}+ 0.846\vec{k})$$

Note again that the unit vector in the acceleration vector has a magnitude of one and therefore only describes the direction. Therefore, multiplying the unit vector by the magnitude leaves the magnitude unchanged and also leaves the direction of the unit vector unchanged. This lets us describe both the direction and magnitude as independent components.

In your case, you could just plot that magnitude with respect to time. That will give you a 2D graph of the acceleration at any given moment but you will lose the direction (which you don't seem to care about).

To calculate velocity from acceleration, you will need to numerically integrate sequences of the x, y, and z samples independently. After that you'll have a velocity vector similar to the acceleration vector discussed here and you can perform all the same operations on it.

Beware of integration error which will cause drift with unbounded error. You will need to introduce some mechanism to bound the error in the velocity. For example, run the velocity through a high-pass FIR before using it in the next integration since you know it's vibration and thus should average to zero over time. Unless it doesn't. Then your stationary machine really has problems. Such an FIR filter will require remembering a sequence of velocity results. Or, much simpler to implement due to your usage case is simply to periodically reset the velocity to zero and start integrating from that zero anew.

  • $\begingroup$ Thank you. Super helpful. This looks similar to RMS calculation. What about reading our high frequency 6khz but displaying in 1 second readings? Isn’t that what FfT is for? $\endgroup$ Feb 26, 2022 at 0:30
  • $\begingroup$ Ideally I’d like to output a data model that consolidates 600 samples/sec into a one second value for rmsAccel, rmsVelocity, minVelocity, maxVelocity, etc $\endgroup$ Feb 26, 2022 at 0:31
  • $\begingroup$ Doesn't look like RMS to me since there is no integration/summation. In any case, it's not RMS. If you want to weed out the frequencies in the vibration I guess you could record a sequence of magnitudes mentioned and then FFT them. I am not sure if that is valid though since you wouldn't be working off any direction information and you know the direction isn't going to be consistent in the sequence. I have the same trepidation about calculating RMS from just the magnitudes. $\endgroup$
    – DKNguyen
    Feb 26, 2022 at 0:43
  • $\begingroup$ Another approach might be to run the FFT on x, y, z sequences separately then add the three xyz frequency plots together to produce an overall plot. Depending on the FFT you use it would be a magnitude for the sinusoid or a spectral power. This will affect how you add them together (straight add vs RMS add). But the FFT gives a plot of the frequencies present and the strengths of each frequency. Not a single number. You'd have to give the power and frequency value of the strongest frequency but that leaves out a lot if you have many strong frequencies present with similar strength. $\endgroup$
    – DKNguyen
    Feb 26, 2022 at 0:50
  • $\begingroup$ Max and Min is easy enough since you can just act directly on the magnitudes regardless of what direction the readings happen to be in. $\endgroup$
    – DKNguyen
    Feb 26, 2022 at 0:51

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.