I've got a 6DOF IMU and have, using some trig and and a few references such as ADI's app note: https://www.analog.com/en/app-notes/an-1057.html successfully implemented some Arduino/C code to calculate pitch, roll, and "tilt" angle for any given attitude.

Now, I would like to be able to detect about which axis the IMU is being rotated (in its own reference frame). So, picture grabbing one corner of the board on which the IMU is mounted and just lifting it up. This will rotate the IMU, and if I lift straight up, it should rotate in a plane, about that plane's perpendicular.

I would like to find the projection of that perpendicular into the XY plane of the IMU.

I should probably be able to figure this out, but am a bit stuck on it. Then also, all of the search terms I'm using don't readily distinguish the typical pitch and yaw examples of which there are many!


  • $\begingroup$ Wouldn't the axis of rotation not be given directly by the gyroscope (the angular velocity vector)? $\endgroup$
    – fibonatic
    Oct 1, 2022 at 23:41
  • $\begingroup$ I think you are right in the sense that atan(gyroX/gyroY) does give me the angle I'm looking for, but it's very noisy by itself - I think I'll have to take the derivative of the pitch and roll (which of course have gyro components) to get a smoother reading. Appreciate the lead! $\endgroup$
    – braddo
    Oct 2, 2022 at 1:52
  • $\begingroup$ If you have noisy data it might be worth looking into a low pass or Butterworth filter. $\endgroup$
    – Josef
    Oct 4, 2022 at 13:24
  • $\begingroup$ Thanks - the IMU I'm using does have some advanced filters onboard that I can turn on. Now that I have something that sort of works, I can improve it. At the moment though my next big challenge is gyro drift, trying to make a "zero velocity filter" that will reset the gyro integration to 0 when the accel "isn't moving" - where that latter concept is a bit hard to define at the moment. $\endgroup$
    – braddo
    Oct 5, 2022 at 2:56

1 Answer 1


If you look at a Bode plot you can design a simple low pass filter by using something like this: $v_n = c_1 \:v_{n-1} + c_2 \: v_{n,raw}$. This is called a ``difference equation'' and fairly simple to implement in Arduino code. $v_{n,raw}$ is your currently measured velocity, $v_n$ is the velocity resulting from the low pass filter and $v_{n-1}$ is the previous time step's velocity which resulted from the low pass filter. $c_1$ and $c_2$ are coefficients which you have to choose, and this will change your Bode plot. The coefficients need to sum up to 1. You can simply use MATLAB and look up the transfer function of a low pass filter in continuous time, it should look something like $G(s)=\frac{\omega_{cutoff}}{s + \omega_{cutoff}}$. Knowing your sample time of your IMU recording allows you to apply the c2d-command in MATLAB on $G(s)$ and voila you have your discrete transfer function and you have your coefficients $c_1$ and $c_2$. So it all depends on your cutoff frequency.

From my experience: If you use an MPU6050 the velocity should drift too much. There is a nice documentation for an Arduino library by Romain JL Fetick. The library is called MPU6050_light if I remember correctly.


Your Answer

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

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