# Experiment #008 — Can a Gyroscope Be Used as an Attitude Sensor?

> Integrating MPU6050 gyro rates into roll, pitch and yaw. It passes straight through the orientation where the accelerometer breaks down, it is the only source of relative yaw, and over five stationary minutes it wandered 1.1, 0.8 and 0.37 degrees. Then the temperature moved.

![A GY-521 MPU-6050 module tilted in space with a red roll arrow along its X axis, a green pitch arrow along Y and a blue yaw arrow along Z, each wrapped in a curved rotation arrow, beside three cards reading gyroscope output as angular velocity, integration over time, and relative change in roll, pitch and yaw](https://embed-studio.com/assets/hero.Da8ET9rp.jpg)

- Thread: MPU-6050 Journey (Experiment #008)
- Published: 2026-09-05
- Tags: Embedded, IMU, MPU6050, STM32, Gyroscope, Attitude, EmbedStudio
- Canonical page: https://embed-studio.com/experiments/mpu6050/experiment-008-mpu6050-gyroscope-inclination

In the previous experiment we looked at a fundamental limitation of using an
accelerometer to estimate inclination.

An accelerometer can use gravity as a reference, but that reference becomes
problematic at certain orientations. Around 90° of inclination a small
measurement error can produce a surprisingly large error in the calculated
angle.

So what happens if we use a gyroscope instead?

A gyroscope does not measure inclination directly. It measures angular
velocity. By integrating that angular velocity over time we can obtain a
relative change in orientation.

This sounds promising. But integration introduces another problem: **drift**.

This experiment investigates both sides of that trade. The acquisition
configuration is unchanged from the previous experiments — 1 kHz sampling,
internal low-pass filter at about 21 Hz, ±2 g and ±250 °/s ranges. EmbedStudio
read the firmware's own attitude variables over SWD at roughly 275 samples per
second.

## From Angular Velocity to Angle

The MPU6050 gyroscope measures angular velocity, expressed in degrees per
second.

If the sensor rotates at 20 °/s for one second, its orientation changes by
approximately 20°.

In general the angle is obtained by integrating angular velocity:

$$
\theta(t) = \theta_0 + \int_0^t \omega(\tau)\,d\tau
$$

For discrete measurements this becomes:

$$
\theta_{k+1} = \theta_k + \omega_k \Delta t
$$

where $\theta_k$ is the current angle, $\omega_k$ is the measured angular
velocity and $\Delta t$ is the time between samples.

![A diagram of the integration chain. Angular velocity in degrees per second enters a block computing theta at step k plus one as theta at step k plus omega times delta t, and an angle in degrees comes out. A second block feeding the accumulator carries the starting value, with roll and pitch taken from the accelerometer and yaw set to zero. Three cards underneath map gyro X to roll, gyro Y to pitch and gyro Z to yaw.](https://embed-studio.com/assets/mpu6050-008-01-integration-chain.jdOYiRpt.svg)
*Figure 1 — The whole estimator. One multiply and one add per axis per sample, plus a starting value the gyroscope itself cannot supply. The three axes are accumulated independently, which is a simplification discussed below.*

The firmware implementation is deliberately simple:

```c
// Resets the orientation angles in gyro_angles to the value provided by gyro_init
void ahrs_gyro_reset(vector_3f_t* const gyro_angles, const vector_3f_t* const gyro_init)
{
	memcpy(gyro_angles, gyro_init, sizeof(vector_3f_t));
}

// Updates the orientation angles by integrating the angular velocities for each axis
// This implementation is not correct and is build for demonstration of how the gyro works
void ahrs_gyro_loop(const vector_3f_t* const gyro, const float dt_s,
		vector_3f_t* const angles)
{
	for (uint8_t i = 0; i < VECTOR_3F_N_ELEMENTS; ++i) {
		angles->v[i] += gyro->v[i] * dt_s;
	}
}
```

`ahrs_gyro_reset()` initializes the accumulated angles. `ahrs_gyro_loop()`
integrates every new gyro sample. The `dt_s` it receives is the measured
interval from [experiment #004](https://embed-studio.com/experiments/mpu6050/experiment-004-mpu6050-timing-and-sampling.md),
not a nominal one.

The three gyro axes are integrated independently. The comment in the source
says what that is: a demonstration, not a correct attitude filter.

In a general 3D attitude estimator, body-frame angular velocity and Euler-angle
rates are not the same thing. The exact relationship depends on the current
orientation and couples the axes. That mathematics is useful when building a
complete estimator. It is not needed to answer the question this experiment
asks, and the simplification keeps the focus on how the gyroscope itself
behaves. The recording in the roll section shows exactly where it stops being
adequate.

## How Do We Initialize the Gyroscope?

There is one immediate problem.

The gyroscope measures rotation, but it does not know where the sensor started.

If the sensor is lying at 30° when the system starts, integrating the gyro
cannot tell us that the initial angle was 30°. It only tells us how much the
orientation has changed since then.

An initial orientation therefore has to be provided from somewhere else.

For roll and pitch we can use the accelerometer, because gravity provides a
reference for the vertical direction. Yaw is different. Gravity carries no
information about rotation around the vertical axis, so yaw cannot be
initialized to an absolute heading from the accelerometer.

The initial values are therefore:

$$\mathrm{roll}_0 = \mathrm{roll}_{acc}$$

$$\mathrm{pitch}_0 = \mathrm{pitch}_{acc}$$

$$\mathrm{yaw}_0 = 0$$

There is one more detail in the firmware. After power-up the gyro zero-offset
estimator needs time to determine the sensor bias, and it only banks samples
while the board is genuinely still. Until that estimate is ready the gyro
angles are reset on every iteration:

```c
if ((!gyro_inited && (mpu_data.sample_count > N_SAMPLES_BEFORE_GYRO_INIT))
|| !gyro_zero.ready
|| gyro_init_request) {
	gyro_inited = 1;
	gyro_init_request = 0;
	vector_3f_t init_angle = {
			.x = attitude_deg.roll,
			.y = attitude_deg.pitch,
			.z = 0,
	};
	ahrs_gyro_reset(&gyro_angles_deg, &init_angle);
}

ahrs_gyro_loop(&gyro_dps, (mpu_data.sample_time_us) / US_IN_S, &gyro_angles_deg);
```

Once the zero-offset estimate is ready the automatic resetting stops, and the
angles are updated by integration alone. The `gyro_init_request` flag can still
force a reset. That flag is an ordinary firmware variable, so during these
experiments the integration was restarted by writing to it from EmbedStudio,
without rebuilding anything.

That boundary is visible in the recording.

![An EmbedStudio plot of accelerometer roll and integrated gyro roll over ten seconds, with a vertical dashed line marking the instant the zero-offset estimate became ready. Before the line the two traces carry identical values and the smooth gyro trace is hidden under the noisy accelerometer one. After it the gyro trace is a smooth line drifting slowly upward while the accelerometer trace keeps its noise.](https://embed-studio.com/assets/mpu6050-008-02-gyro-initialization.BHP2g6mx.png)
*Figure 2 — The moment the integrator is let go. Left of the line the gyro angle is reset to the accelerometer angle every iteration, so it carries the accelerometer's noise exactly; the two traces never differ by more than 0.04°. Right of it, the same channel is smooth and moves 0.16° in twelve seconds, while the accelerometer keeps wandering over a 0.43° band.*

That one figure already contains the whole trade. The integrated angle is far
smoother than the accelerometer estimate, and it is slowly going somewhere.

The processing chain is therefore:

**gyro zero-offset estimation → initial attitude → gyro integration →
accumulated roll, pitch and yaw**

## Pitching Through 90 Degrees

The first experiment revisits the problem measured in
[experiment #007](https://embed-studio.com/experiments/mpu6050/experiment-007-mpu6050-roll-regularization.md).

The sensor was rotated in pitch, past 90° and back.

![Two stacked EmbedStudio plots over the same six seconds. The upper one shows accelerometer and gyro pitch falling together from zero; the accelerometer trace stops just short of the marked minus 90 degree line and turns back towards zero while the gyro trace continues to minus 100 and returns. The lower one shows accelerometer and gyro roll; the gyro roll is a flat line while the accelerometer roll drops to minus 176 degrees for about a second and comes back.](https://embed-studio.com/assets/mpu6050-008-03-pitch-through-90.DxIxYua3.png)
*Figure 3 — One sweep past vertical. Top: pitch. The accelerometer estimate (blue) reaches −88.9° and folds back towards zero; the integrated one (red) continues to −100.0° and returns. Bottom: roll, on the same time axis. The accelerometer roll swings to −176.4°; the integrated roll stays inside a 0.55° band the whole time.*

Two different things happen to the accelerometer estimate here, and they are
worth separating.

The first is the one measured in experiment #007. As pitch approaches −90° the
projection of gravity that the roll formula depends on shrinks into the noise,
and the calculated roll starts moving even though the board is not rolling.

The second is not an error at all. Past vertical, the same orientation is
described by moving roll to about 180° and bringing pitch back towards zero.
Both estimates are correct, and the accelerometer has no way to choose between
them. So its pitch turns around at the boundary and its roll jumps almost half
a revolution.

The gyroscope has neither problem. It measured the rotation as it happened and
accumulated it, so the pitch it reports is one continuous number that passes
through −90° without noticing it. Over the same two seconds, while the
accelerometer roll was moving over most of its range, the integrated roll moved
by 0.55°.

This is the important difference between the two sensors:

**the gyroscope does not need gravity to determine the change in orientation.**

It measures the rotation itself.

## Rolling Through 90 Degrees

The same experiment was repeated around the other inclination axis. The board
was rolled past 90° and returned.

The result is different, and it is worth stating plainly: **the accelerometer
is fine here.** Rolling through 90° is not a singular orientation for the roll
equation. Roll is `atan2(ay, az)`, and at 90° of roll the Y component is at a
full g, which is as well conditioned as this calculation ever gets. The
singularity in experiment #007 belongs to pitch approaching ±90°, not to
inclination in general.

![Two stacked EmbedStudio plots over six seconds. The upper one shows accelerometer and gyro roll dropping together through the marked minus 90 degree line to about minus 100 and returning, the two traces almost on top of one another. The lower one shows accelerometer pitch, gyro pitch and gyro yaw; during the rotation the gyro pitch departs to minus 21 degrees and the gyro yaw rises to plus 15 while the accelerometer pitch stays near minus 11, and both gyro traces come back afterwards.](https://embed-studio.com/assets/mpu6050-008-04-roll-through-90.CAxakBZn.png)
*Figure 4 — Rolling past vertical. Top: the two roll estimates agree through −100°, to a median of 1.0° and to 2.5° at the ninetieth percentile. Bottom: the price of integrating the three axes independently. Gyro pitch (red) leaves the accelerometer pitch (blue) by up to 10° during the rotation and returns to within 0.15° of where it started, and gyro yaw (purple) does the same.*

So the top panel says what this article is about: over a fast, large,
hand-held rotation the integrated angle tracked the accelerometer estimate to
about a degree. The differences that remain are mostly the accelerometer's, not
the gyro's. The board is being turned by hand, so the accelerometer is
measuring gravity plus the hand, and the magnitude of the measured vector
reaches 1.28 g during the sweep. That is the failure mode measured in
[experiment #006](https://embed-studio.com/experiments/mpu6050/experiment-006-mpu6050-accelerometer-inclination.md),
and it is exactly what a gyroscope is immune to.

The bottom panel is where the simplification shows. Gyro pitch started at
−11.9°, moved to −21.4° during the roll, and came back to −11.8°. Gyro yaw did
the same, out to +15.1° and back. The accelerometer pitch stayed between −16.1° and −6.4°
throughout, so the board's pitch did not really change by twelve degrees.

The excursion appears during the rotation and disappears when it stops. That is
the signature of axis coupling, not of drift. With the board rolled onto its
side, a rotation the operator makes about one axis is partly seen by the
gyroscope on another, and three independent accumulators have no way to sort
that out. A proper attitude estimator does. This one is not one, and the figure
is the measurement of how much that costs.

## A Capability the Accelerometer Does Not Have: Yaw

The accelerometer can determine the direction of gravity, which gives roll and
pitch. But rotating the sensor around the gravity vector does not change the
direction of gravity.

An accelerometer alone therefore cannot determine yaw. A gyroscope can.

![A diagram with a top view of the GY-521 module on the left, its pin header down one edge, the MPU-6050 in the middle, the X axis pointing across the board and the Y axis along the header, and the Z axis coming out of the board with a curved arrow around it marking yaw. On the right two cards state that the gyroscope measures rotation about Z directly and gives relative yaw, and that the accelerometer sees an unchanged gravity direction and has no yaw reference.](https://embed-studio.com/assets/mpu6050-008-05-yaw-about-gravity.DJ74hsGS.svg)
*Figure 5 — Yaw is rotation about the sensor Z axis. Held level, that axis points along gravity, so the accelerometer reads the same three numbers before and after the turn. The gyro Z channel reads the rotation rate directly.*

For the yaw experiment the board was turned about its vertical axis while
staying approximately level. It was moved by hand in four steps of roughly a
quarter turn each.

![An EmbedStudio plot over fifteen seconds. The integrated gyro yaw descends in four steps to about minus 346 degrees, with a flat plateau after each step. The accelerometer roll and pitch traces run along zero for the whole recording, indistinguishable from a straight line at this scale.](https://embed-studio.com/assets/mpu6050-008-06-yaw-full-turn.jskbjEaq.png)
*Figure 6 — A full turn about the vertical axis. The integrated yaw (red) follows every step and settles at −346°. The accelerometer's roll and pitch (blue and green) stay inside ±5° and ±8° for 98% of the rotation, apart from isolated single-sample excursions. There is nothing in them to read a heading from.*

The four plateaus sit at −82.5°, −179.7°, −251.3° and −346.3°. Those are where
the operator's hand stopped, not calibration points: the board was turned
without a jig and there is no external heading reference in this recording to
check the total against. What the figure shows is that the rotation was
followed at all, by a sensor pair in which one half is completely blind to it.

Of course this does **not** mean that the gyro knows the absolute heading. If
we initialize yaw to zero, the gyro can tell us that the sensor subsequently
rotated by, for example, +40° or −90° relative to that initial orientation.

It cannot tell us that the sensor is pointing north.

So the distinction is:

**gyro → relative yaw**

**magnetometer or another external reference → absolute heading**

## How Stable Is a Gyro When Nothing Is Moving?

The main weakness of gyro integration is drift.

Even when the sensor is completely stationary, the measured angular velocity is
not exactly zero. Suppose the real angular velocity is zero but the gyro
reports a constant error of 0.1 °/s. After one second the accumulated error is
0.1°. After one minute it is 6°.

This is the fundamental problem with integration: **a small bias becomes an
angle error that grows with time.**

How large is that effect in practice for the MPU6050?

The sensor was initialized and then left alone for five minutes. The die
temperature moved by 0.14 °C over the whole recording, so conditions were about
as steady as a desk gets.

![An EmbedStudio plot of three deviation traces over five minutes, with the Analysis panel underneath. Roll climbs steadily to just over one degree, pitch falls to minus 0.8 and yaw falls to minus 0.37. The panel reports the count, mean, standard deviation, minimum, maximum and peak-to-peak of each trace over the 305 second window.](https://embed-studio.com/assets/mpu6050-008-07-stationary-drift.C7vFO4u9.png)
*Figure 7 — Five stationary minutes, measured by the Analysis panel. Top: the die temperature, on the same scale as figure 8, where it is a flat line. Middle: each integrated angle minus the attitude the integrator was started at, so zero is the initial attitude. Over 305 s and 76 860 samples the extremes are +1.11° in roll, −0.80° in pitch and −0.37° in yaw. Note the angle scale — figure 8 uses one seventeen times wider.*

| Axis | Maximum deviation | Implied residual bias |
| --- | --: | --: |
| Roll | 1.11° | 0.0036 °/s |
| Pitch | 0.80° | 0.0026 °/s |
| Yaw | 0.37° | 0.0011 °/s |

*Table 1 — Deviation from the initial attitude over 305 stationary seconds, and the constant rate that would produce it. The die temperature stayed within 0.14 °C.*

These results are surprisingly good for a low-cost MEMS gyroscope. Over five
minutes the integrated orientation stayed within about a degree on roll and
pitch, and the yaw deviation was smaller still.

Two things put that in context.

The drift is not random walk here, it is a slope. Each trace moves in one
direction at a nearly constant rate, which is what a small residual bias looks
like. Dividing the deviation by the window gives biases of a few thousandths of
a degree per second, thirty to ninety times smaller than the 0.1 °/s used as
an illustration above.

And the accelerometer estimate, over the same five minutes on the same
stationary board, wandered over 0.49° in roll and 0.51° in pitch without going
anywhere. For the first minute or two of this recording, the noisier of the two
estimates is the one that cannot drift.

None of this eliminates gyro drift. It shows that **for short-term
applications, gyro integration can be considerably more useful than the word
"drift" might suggest.**

## What Happens When the Temperature Changes?

The previous result was obtained under steady temperature. That matters,
because the gyro bias is not necessarily constant.

A stationary sensor can therefore show a changing integrated angle even though
its physical orientation has not moved. One practical source of that behaviour
is temperature.

A second stationary recording was made while the sensor temperature was allowed
to change. The board had been handled, so it started warm at 38.5 °C, and it
was left to cool.

![Two stacked EmbedStudio plots over three minutes. The upper one shows the die temperature falling from 38.5 to 29.9 degrees Celsius along a cooling curve. The lower one shows the three integrated angles leaving zero together, roll rising to plus 32 degrees, pitch to plus 21 and yaw falling to minus 9.](https://embed-studio.com/assets/mpu6050-008-08-temperature-drift.CYHaYGaW.png)
*Figure 8 — The same measurement, with the temperature moving. Top: the die cools from 38.5 °C to 29.9 °C, on the same scale as figure 7. Bottom: the integrated attitude of a board that never moved, running away by 31.8°, 20.9° and −9.1° — the angle scale spans 46° here against 2.7° in figure 7. Temperature dependence is demonstrated qualitatively; a controlled thermal characterization is a separate experiment.*

The board was as stationary as in the previous recording — its accelerometer
roll and pitch stayed inside 0.8° and 0.5° bands throughout. The integrated
attitude nevertheless left by more than thirty degrees.

Averaged over that window the roll drift rate was 0.18 °/s, against 0.0036 °/s
with the temperature steady. A milder version of the same recording, over a
0.6 °C fall rather than an 8.6 °C one, gave 4.6° of roll in three minutes. Both
are in the dataset.

**Two measured rates on the same board are not a temperature coefficient**, and
nothing here should be read as one. The recording is not controlled: the
cooling rate, the starting temperature and the gradient across the package were
all whatever they happened to be. Characterizing the coefficient needs a
controlled temperature range and is planned as its own experiment.

What the recording does establish is the practical fact:

**gyro bias changes with operating conditions, so a zero-offset estimate taken
at startup does not stay valid indefinitely.**

## What Have We Learned?

The experiments show that a gyroscope is a capable short-term attitude sensor.

### What the gyroscope does well

**It measures rotation directly.** The gyro does not infer rotation from
gravity, so it tracked the board smoothly through the orientation where the
accelerometer estimate breaks down, and past it.

**It provides relative yaw.** Unlike the accelerometer, the gyro can detect
rotation around the gravity vector. It followed a full revolution that the
accelerometer could not see at all.

**It is immune to linear acceleration.** During the hand-held sweeps the
measured acceleration reached 1.28 g and the accelerometer attitude moved with
it. The gyro did not.

**Its short-term estimate is smooth and steady.** In the five-minute stationary
recording the deviations from the initial attitude were 1.11° in roll, 0.80° in
pitch and 0.37° in yaw.

### What the gyroscope cannot do

**It cannot determine the initial orientation by itself.** An initial attitude
has to come from another sensor or another system.

**It cannot provide absolute heading.** A gyro measures changes in yaw. Without
an external heading reference it does not know the absolute direction.

**It drifts.** Even a small measurement bias accumulates through integration,
and the error grows for as long as the integration runs.

**Its bias changes.** Cooling by 8.6 °C turned a 0.0036 °/s residual bias into
an average of 0.18 °/s, and thirty-two degrees of roll error in three minutes.

**Three independent accumulators are not an attitude estimator.** Rolling the
board onto its side moved the integrated pitch by twelve degrees and put it back
afterwards. That is coupling between the axes, and it is a property of the
simplified model rather than of the sensor.

## Conclusion

The gyroscope provides a fundamentally different way of estimating attitude.

Instead of using gravity as an absolute reference, it measures angular velocity
and integrates it over time. That makes it good at tracking short-term
rotational motion, and it avoids the geometric limitation measured around 90°
in the previous experiment. It also provides something the accelerometer
cannot: relative yaw.

But the price is drift.

The gyro does not know where it started, and every small bias in its
measurement accumulates into the estimated angle. Under steady conditions the
MPU6050 held a surprisingly good short-term attitude estimate. Let the
temperature move by a few degrees and the same board wandered by thirty.

So we now have two sensors with complementary strengths.

The accelerometer provides an absolute reference from gravity, but its estimate
is disturbed by motion and becomes unusable at certain orientations. The
gyroscope handles rotational motion well, but its estimate inevitably drifts
because it has no long-term reference.

Perhaps the best solution is not to choose one sensor over the other, but to
use both.

That is what we will investigate next.

## Experiment data

The raw datasets used in this experiment are publicly available in the
[EmbedStudio Experiments repository](https://github.com/Embed-Studio/embedstudio-experiments/tree/main/008-gyro-as-an-inclination-sensor).

The dataset contains:

- the gyro initialization capture, in which the integrator is released the
  moment the zero-offset estimate becomes ready;
- the pitch sweep past vertical and the roll sweep past vertical;
- the yaw rotation through a full turn;
- the five-minute stationary recording used for the drift measurement, and a
  three-minute one at the same steady temperature;
- two stationary recordings with the temperature moving, one over 8.6 °C and
  one over 0.6 °C.

Every capture carries the three calibrated accelerometer channels, the three
calibrated gyro rates, the accelerometer attitude, the three integrated gyro
angles, the zero-offset estimator state and the die temperature.

The EmbedStudio workspace the captures were recorded with is in the repository
as well. It carries an extra *Article figures* dashboard whose views are the
ones the screenshots above were taken from, so opening a capture with it puts
the same plots on the screen.

All datasets are provided as HDF5 files and can be downloaded and opened with
EmbedStudio or another compatible HDF5 tool.

## Frequently Asked Questions

### How do you calculate an angle from a gyroscope?

By integration. Each sample of angular velocity is multiplied by the time since the previous sample and added to a running total, so theta at step k plus one equals theta at step k plus omega at step k times delta t. On the MPU6050 that is one multiply and one add per axis per sample. The gyroscope measures how fast the sensor is turning, not where it is pointing, so the running total is a change in orientation rather than an orientation.

### Can a gyroscope alone measure inclination?

Only relative to wherever it was started. Integration gives the change in orientation since the accumulator was initialized, so an initial attitude has to come from somewhere else. In this experiment roll and pitch start from the accelerometer, which can see the direction of gravity, and yaw starts at zero because gravity carries no heading information.

### Does the gyroscope have the same 90 degree problem as the accelerometer?

No. In the recording here the board was tipped past vertical. The accelerometer pitch stopped at minus 88.9 degrees and folded back towards zero while its roll jumped to minus 176 degrees, which is a correct but discontinuous description of the same orientation. The integrated gyro pitch went straight through to minus 100 degrees as one continuous number, and the integrated roll stayed inside a 0.55 degree band while the accelerometer roll swung across most of its range.

### Why can a gyroscope measure yaw when an accelerometer cannot?

Because it measures rotation itself rather than the direction of gravity. Turning the sensor about the vertical axis leaves the gravity vector unchanged, so the accelerometer reads the same three numbers throughout. The gyro Z axis reads the rotation rate directly. In the recording here the board was turned by hand through a full revolution and the integrated yaw accumulated minus 346 degrees while the accelerometer roll and pitch stayed inside a few degrees of level.

### Does a gyroscope give absolute heading?

No. It gives a change of heading relative to whatever the accumulator was started at. If yaw is initialized to zero, the gyro can say the sensor has since turned by plus 40 or minus 90 degrees, but it cannot say the sensor is pointing north. Absolute heading needs an external reference such as a magnetometer.

### How much does an MPU6050 gyroscope drift when it is not moving?

On this module, left stationary for five minutes with the die temperature steady within 0.14 degrees Celsius, the integrated attitude moved 1.11 degrees in roll, 0.80 degrees in pitch and 0.37 degrees in yaw away from the attitude it started at. Those correspond to residual biases of about 0.0036, 0.0026 and 0.0011 degrees per second. That is a lot better than the word drift usually suggests, and it is still an error that grows for as long as the integration runs.

### Does gyro bias change with temperature?

Yes, and enough to dominate everything else. A second stationary recording started with the sensor at 38.5 degrees Celsius and let it cool to 29.9 over about three minutes. The integrated roll ran away by 31.8 degrees, an average rate of 0.18 degrees per second against 0.0036 with the temperature steady. A zero-offset estimate is only valid for the conditions it was measured in, and this recording is a qualitative demonstration rather than a characterization of the temperature coefficient.

### Why does integrating the three gyro axes independently not give correct Euler angles?

Because body-frame angular rates and Euler-angle rates are only the same thing near level. The exact relationship depends on the current orientation and couples the axes. In the roll recording here the board was rolled past 90 degrees and the integrated pitch moved from minus 11.9 to minus 21.4 degrees and back to minus 11.8 while the accelerometer pitch stayed between minus 16 and minus 6. The excursion appeared during the rotation and disappeared afterwards, which is what coupling looks like rather than drift.

## Source Code

The firmware and supporting files for this experiment: https://github.com/Embed-Studio/MPU-6050/releases/tag/experiment_008

- Previous: [When Accelerometer Roll Estimation Fails: The Pitch Singularity](https://embed-studio.com/experiments/mpu6050/experiment-007-mpu6050-roll-regularization.md)
- Next: [Experiment #009 — What Does a Complementary Filter Actually Fix?](https://embed-studio.com/experiments/mpu6050/experiment-009-mpu6050-complementary-filter.md)
