Emerging Interfaces

IMUs From Zero: Why Your Gyroscope Drifts and What to Do About It

Accelerometer, gyroscope, magnetometer — what each one can and cannot tell you, why integrating a gyro is a trap, and the fusion you should use instead of writing your own.

Motion sensing is the most common requirement in interactive hardware and the most commonly botched. Someone buys an MPU-6050, reads the gyroscope, integrates it to get an angle, and within thirty seconds the angle has wandered off by fifteen degrees with the board sitting still on the desk.

That is not a broken chip. It is the correct behaviour of a gyroscope, and the reason IMUs come with three sensors instead of one.

Core Electronics’ beginner’s guide, which is the clearest short explanation of the angle problem.

The three sensors and their complementary failures

Accelerometer — measures linear acceleration, including gravity. At rest it tells you which way is down, with excellent long-term stability. Its failure: it cannot distinguish gravity from motion. Shake it and “down” goes everywhere. It is accurate but noisy.

Gyroscope — measures angular rate, degrees per second. Beautifully smooth, immune to vibration, and responds instantly. Its failure: it measures rate, not angle. To get an angle you integrate, and integration accumulates the sensor’s small constant bias into an ever-growing error. It is smooth but drifts.

Magnetometer — measures the magnetic field, so it tells you which way is north. Needed because gravity cannot tell you your heading — rotate around the vertical axis and the accelerometer sees no change at all. Its failure: it measures all magnetic fields, including your speaker magnet, your DC motor, the steel desk frame and the building’s rebar.

The pattern: each sensor’s weakness is another’s strength. The accelerometer is stable long-term and bad short-term; the gyro is excellent short-term and bad long-term. Combining them is called sensor fusion, and it is the whole subject.

Degrees of freedom, decoded

  • 6-DoF — 3-axis accel + 3-axis gyro. Gives you pitch and roll reliably. Yaw will drift and nothing can stop it.
  • 9-DoF — adds a 3-axis magnetometer. Gives you full absolute orientation including heading.

If you need to know which way something is pointing in a room, you need 9-DoF. If you only need tilt — a hand-held controller, a tilt-to-steer object, the falling-sand demos we covered last week — 6-DoF is fine and simpler.

What to buy

BNO055 or BNO085 (Bosch). Buy one of these if you can. They are 9-DoF sensors with an onboard processor that does the fusion for you and outputs a ready-made quaternion or Euler angles over I2C. You read orientation; you do not implement anything. The BNO085 is the newer and better part.

The cost is a few dollars more and a slightly opaque black box. The benefit is that you skip every problem in this article. For almost all creative work this is the correct purchase, and people avoid it out of a misplaced sense that doing the fusion yourself is more legitimate.

ICM-20948 — 9-DoF, raw output, you do the fusion. Good modern part.

LSM6DSOX / LSM9DS1 (ST) — widely available, well supported in CircuitPython and Arduino.

MPU-6050 — the classic $3 6-DoF module. Officially obsolete, cloned endlessly, quality varies wildly, and the one most tutorials use. Fine for learning; do not put it in something that matters.

Fusion: use a library

If you have raw sensors, do not write your own filter. The two you will meet:

Complementary filter — the simple one, and genuinely good enough for a lot of work:

angle = alpha * (angle + gyro_rate * dt) + (1 - alpha) * accel_angle

With alpha around 0.98. Read it as: trust the gyro for fast changes, let the accelerometer slowly correct the drift. It is a high-pass on the gyro and a low-pass on the accelerometer, summing to one. Ten lines, no tuning beyond alpha, and it solves the drift problem for pitch and roll.

Madgwick / Mahony filters — the standard open implementations for 9-DoF orientation, available for Arduino, Python and CircuitPython. Use Madgwick unless you have a reason not to. It is computationally cheap, well-tested, and outputs quaternions.

Kalman filters are the textbook answer and are overkill here; the tuning effort is real and Madgwick gets you 95% of the result for none of it.

Calibration is not optional

Magnetometer calibration is mandatory and everyone skips it. An uncalibrated magnetometer will give you a heading that is wrong by tens of degrees and wrong differently depending on orientation.

The procedure: rotate the sensor slowly through every orientation — the “figure-eight” or “sphere” motion — while collecting readings. Ideally the readings form a sphere centred on the origin. In reality they form an off-centre ellipsoid:

  • Hard-iron offset — the sphere’s centre is displaced, caused by permanent magnets near the sensor. Fixed by subtracting the offset.
  • Soft-iron distortion — the sphere is squashed into an ellipsoid, caused by ferrous material distorting the field. Fixed with a 3×3 correction matrix.

The BNO055/085 do this continuously and report a calibration status you should check before trusting the output.

Gyro bias also needs measuring: hold the sensor completely still at startup, average a few hundred readings, and subtract that offset forever after. This single step removes most of the drift people blame on the sensor.

The quaternion thing, which will save you a weekend

You will be tempted to work in Euler angles — pitch, roll, yaw — because they are human-readable. Then you will hit gimbal lock: at ±90° pitch, roll and yaw become the same axis, the maths degenerates, and your object flips unpredictably.

Use quaternions for storing and combining rotations. Convert to Euler only for display. Every graphics and robotics library supports them, every fusion filter outputs them, and you do not have to understand the algebra to use them — treat a quaternion as an opaque four-number orientation that composes correctly.

This is the single most common source of “my object flips out when I point it straight up”, and it is entirely avoidable by never storing an orientation as three angles.

What an IMU cannot do

It cannot tell you where you are. Integrating acceleration twice to get position — dead reckoning — accumulates error quadratically and is useless within seconds. There is no filter that fixes this. Position needs an external reference: a camera, a UWB anchor, GPS, an optical tracker.

It cannot distinguish being tilted from being accelerated, momentarily. A sharp horizontal push looks like a tilt, which is why a tilt-controlled object feels odd when you move it across a room.

Which is also what makes it useful. We have covered research getting whole-body pose from a single earbud IMU and punch quality from an eight-IMU garment. In both cases the value came from the pattern of acceleration over time, not from an absolute position — and that is the right way to think about an IMU: a sensor of how something is moving, not where it is.