STM32-Based IMU Attitude Estimation: Difference between revisions

From PC5271 wiki
Jump to navigationJump to search
Liding (talk | contribs)
Liding (talk | contribs)
 
(41 intermediate revisions by the same user not shown)
Line 1: Line 1:
__FORCETOC__
__FORCETOC__
This project involves using an STM32 microcontroller and an MPU6050 sensor module to measure angular velocity and acceleration. The collected sensor data will be processed to determine the attitude angles (roll, pitch, and yaw) of the system. The project will include sensor calibration, data filtering (e.g., complementary or Kalman filter), and real-time angle computation for accurate motion tracking applications.
This project involves using an STM32 microcontroller and an MPU6050 sensor module to measure angular velocity and acceleration. The collected sensor data will be processed to determine the attitude angles (roll, pitch, and yaw) of the system. The project will include sensor calibration, data filtering (e.g., complementary or Kalman filter), and real-time angle computation for accurate motion tracking applications.


== Introduction ==
== Introduction ==
This project aims to build a simple but functional system that can estimate the orientation (attitude) of an object in real time. We used an STM32F103C8T6 microcontroller together with an MPU6050 sensor, which includes a 3-axis gyroscope and a 3-axis accelerometer.
By collecting data from the sensor and processing it through our own code, we can estimate how the object is tilted—specifically its roll, pitch, and yaw angles. To make the results more stable and accurate, we applied filtering techniques (e.g., complementary filter) to combine acceleration and gyroscope data.
The project mainly involves:


Reading raw sensor data through I2C communication
In this project, we built a simple attitude estimation system using the STM32F103C8T6 microcontroller and the MPU6050 inertial measurement unit (IMU). The MPU6050 contains a 3-axis accelerometer and a 3-axis gyroscope, which together allow us to sense both linear acceleration and angular velocity in space.


Calibrating the sensor to reduce offset and noise
Our goal was to estimate the orientation of the sensor in real time—specifically the roll, pitch, and yaw angles—by processing the raw physical signals output by the sensor. The core idea is based on how physical forces like gravity and rotational motion affect the internal elements of MEMS sensors, and how these effects can be digitized and interpreted.


Using a filtering algorithm to compute stable angle values
To make the system work, we wrote low-level I²C communication routines to read data directly from the MPU6050 registers. The raw measurements were then converted into meaningful physical quantities, and passed into a complementary filter, which combines accelerometer and gyroscope data to produce smoother and more stable angle estimates.


Updating the angles in real time
The main steps of the project include:
* Reading raw acceleration and gyroscope data via I²C
* Calibrating the sensor to reduce offset and random noise
* Computing roll and pitch using a complementary filter
* Updating and displaying the estimated angles in real time on an OLED screen


This kind of system is commonly used in applications like drones, mobile phones, and robot balance systems. Our goal is to understand how such a system works from both a hardware and software perspective by building one from scratch.
Although this system is relatively simple, it closely reflects the principles used in real-world applications like drone stabilization, smartphone orientation sensing, and robot balancing. More importantly, it helps us explore how sensor physics—particularly the detection of inertial forces—can be harnessed in embedded systems to measure motion and orientation.


== Team Members ==
== Team Members ==
Line 24: Line 24:
FAN XUTING
FAN XUTING


== Project Overview ==  
== Project Overview ==
 
The core idea of this project is to estimate the orientation (attitude) of an object in space using inertial sensor data. We used the MPU6050 module, which integrates a 3-axis accelerometer and a 3-axis gyroscope, to measure two different physical quantities: linear acceleration and angular velocity. These are fundamental mechanical observables when analyzing motion.


The idea of this project is to estimate the orientation (attitude) of an object using sensor data. We used the MPU6050 module, which combines a gyroscope and an accelerometer, to measure how the object is moving and rotating in space. The sensor data is collected using the STM32F103C8T6 microcontroller through I2C communication.
The data from the sensor is acquired through I²C communication using the STM32F103C8T6 microcontroller. However, the raw measurements—especially from the gyroscope—tend to drift over time, and the accelerometer is sensitive to external vibrations. Therefore, we applied a complementary filter to combine the short-term precision of the gyroscope with the long-term stability of the accelerometer. This approach helps us reduce noise and improve the reliability of the estimated angles.


Since the raw data from the sensor is not very stable or accurate by itself, we applied a filtering method (in our case, a complementary filter) to combine the gyroscope and accelerometer readings. This allows us to reduce noise and drift, and get smoother and more reliable angle values over time.
Our objective is to continuously compute the roll, pitch, and yaw angles of the sensor in real time. In practice, only roll and pitch can be estimated reliably without a magnetometer, since yaw depends on integrating rotational velocity around the vertical axis and is subject to drift.


The final goal is to calculate the roll, pitch, and yaw angles of the system in real time. This kind of setup is commonly used in things like self-balancing robots, drones, camera stabilizers, or even mobile phones for detecting screen orientation. Our project is a small-scale version of such systems, built from scratch to better understand how attitude estimation actually works.
Systems like this are commonly found in drones, balancing robots, camera gimbals, and even smartphones for orientation detection. In our project, we replicated the basic functionality of such systems on a smaller scale in order to understand how physical quantities—like gravity and rotation—can be sensed, processed, and interpreted through embedded electronics.


== Setup ==
== Setup ==
=== Equipment ===
=== Equipment ===
Here are the main components used in this project:
STM32F103C8T6 ("Blue Pill") – A versatile microcontroller for controlling the system.
MPU6050 – A 6-axis IMU sensor that includes both a 3-axis accelerometer and a 3-axis gyroscope.


USB to TTL Serial Converter – Used for programming the STM32 and communicating with the serial terminal.
The following components were used to build our attitude estimation system:


Jumper wires and breadboard – For making connections between the STM32 and MPU6050.
* **STM32F103C8T6 ("Blue Pill")** – A low-cost 32-bit microcontroller used here to handle I²C communication, filtering, and OLED output.
* **MPU6050** – A 6-axis IMU that combines a 3-axis accelerometer (for sensing gravity and linear motion) and a 3-axis gyroscope (for measuring angular velocity).
* **USB to TTL Serial Converter** – Used mainly during development to upload programs to the STM32 and read data from the serial port.
* **Breadboard and jumper wires** – For making temporary connections during prototyping.
* **3.3V Power Supply** – The MPU6050 operates at 3.3V, which is provided by the STM32 board itself.


Power supply (3.3V) – Provided by the STM32 or through an external 3.3V regulator.
The MPU6050 is connected to the STM32 using the I²C protocol. I²C is widely used in sensor interfacing due to its simplicity and ability to handle multiple devices over just two lines (SDA and SCL).


The MPU6050 module is powered with 3.3V, and it communicates with the STM32 over the I2C bus.
[[File:Stm32c8t6.jpg|center|thumb|300px|STM32F103C8T6 "Blue Pill" development board]]


=== Wiring / Circuit Overview ===
=== Wiring / Circuit Overview ===
Here's how the components are connected:
The sensor communicates with the STM32 via I²C, and the wiring is shown below:


{| class="wikitable"
{| class="wikitable"
! MPU6050 Pin !! STM32 Pin !! Notes
! MPU6050 Pin !! STM32 Pin !! Notes
|-
|-
| VCC || 3.3V || Powered by STM32
| VCC || 3.3V || Sensor powered by STM32
|-
|-
| GND || GND || Common ground
| GND || GND || Common ground reference
|-
|-
| SDA || PB7 || I2C data line
| SDA || PB7 || I²C data line
|-
|-
| SCL || PB6 || I2C clock line
| SCL || PB6 || I²C clock line
|}
|}


The sensor is connected to the STM32 using the I2C interface, which allows the STM32 to read the sensor's data. I2C is a simple and efficient communication protocol for embedded systems.


Optional: A USB to TTL converter is used for programming the STM32 and debugging through the serial port. This allows us to print the sensor data or estimated angles to the terminal.
Below are two views of the hardware setup: a breadboard diagram and an abstract schematic:


<div style="display: flex; gap: 20px; align-items: flex-start;">
<div style="display: flex; gap: 10px; align-items: center;">
[[File:Imu circuit diagram.png|thumb|600px|imu_wiring_diagram]]
[[File:Imu circuit diagram.png|center|thumb|500px|Breadboard wiring diagram]]
[[File:Schematic diagram of electrical connections.jpeg|thumb|600px|imu_wiring_diagram]]
[[File:Schematic diagram of electrical connections.jpeg|center|thumb|500px|Schematic representation of connections]]
</div>
</div>
=== Software & Code ===
The firmware was written in C using STM32's standard peripheral libraries. The program runs in a loop, repeatedly collecting data from the MPU6050 and computing the corresponding attitude angles in real time.
The main software tasks are as follows:
* '''Initialize I²C interface''' – Configure STM32 to communicate with the MPU6050 using the I²C protocol.
* '''Set up MPU6050''' – Select the measurement range for both the accelerometer and gyroscope, and enable continuous data output.
* '''Read raw sensor values''' – Acquire unprocessed data from the accelerometer and gyroscope registers.
* '''Convert to physical units''' – Translate raw values into real-world quantities:
  * Acceleration in ''g'' (gravitational units)
  * Angular velocity in ''°/s''
* '''Estimate angles''' – Apply a complementary filter to combine the short-term precision of the gyroscope and the long-term stability of the accelerometer. The filter uses the formula:
<math>
\theta = \alpha \cdot (\theta_{\text{prev}} + \omega \cdot \Delta t) + (1 - \alpha) \cdot \theta_{\text{acc}}
</math>
* '''Output the result''' – Display the roll and pitch angles on the OLED screen. Optionally, angles can also be printed to the serial terminal for monitoring.
The system updates approximately every 10 milliseconds (100 Hz), which is fast enough to track slow and moderate human motion smoothly.
== Theory & Angle Estimation ==
To estimate the orientation (attitude) of an object using the MPU6050, we need to understand the physical meaning of the quantities it measures. The accelerometer responds to linear acceleration (including gravity), while the gyroscope senses angular velocity. By interpreting and combining these outputs, we can reconstruct the rotation of the sensor in space.
=== Sensor Principles ===
The MPU6050 is a MEMS-based 6-axis Inertial Measurement Unit (IMU). Internally, it contains:
* '''3-axis accelerometer''' – measures linear acceleration along the X, Y, and Z axes, in units of ''g''.
* '''3-axis gyroscope''' – measures angular velocity around the X, Y, and Z axes, in ''°/s''.
These two types of data correspond to physical forces acting on the sensor:
* The accelerometer reflects the direction and magnitude of gravity (when stationary) or combined forces (when moving).
* The gyroscope provides information about how fast the object is rotating around each axis.
By combining both types of data, we can estimate the orientation of the sensor relative to a fixed reference frame.
[[File:MPU6050.png|center|thumb|300px|MPU6050 breakout board showing the chip and I²C interface]]
=== Attitude Angles: Roll, Pitch, Yaw ===
Attitude in 3D space is commonly expressed using three angles:
{| class="wikitable"
! Angle !! Axis !! Description
|-
| Roll  || X-axis || Tilting left and right
|-
| Pitch || Y-axis || Tilting forward and backward
|-
| Yaw  || Z-axis || Rotating around the vertical axis
|}
In our project, we focus on roll and pitch. Yaw is difficult to measure accurately without a magnetometer, because the accelerometer does not respond to rotation around the vertical axis, and gyroscope-based yaw accumulates drift over time.
[[File:roll_pitch_yaw_axes.png|center|thumb|240px|Roll (X), Pitch (Y), and Yaw (Z) in 3D space]]
=== Using the Accelerometer ===
When the sensor is at rest or moving slowly, the accelerometer mainly senses the Earth's gravity. We can use the direction of this gravity vector to estimate the tilt angles with respect to the horizontal plane. Using basic trigonometry:
<math>
\text{pitch} = \arctan\left( \frac{a_x}{\sqrt{a_y^2 + a_z^2}} \right)
</math>
<math>
\text{roll} = \arctan\left( \frac{a_y}{\sqrt{a_x^2 + a_z^2}} \right)
</math>
These estimates are relatively stable when the sensor is static but become noisy during motion, since linear acceleration disturbs the gravity vector.
=== Using the Gyroscope ===
The gyroscope gives angular velocity ω (in ''°/s''), which can be integrated over time to estimate changes in orientation:
<math>
\theta = \theta_{\text{prev}} + \omega \cdot \Delta t
</math>
However, this method suffers from drift because small measurement errors accumulate over time.
=== Complementary Filter ===
To reduce drift while keeping responsiveness, we apply a complementary filter, which fuses gyroscope and accelerometer data. The gyroscope provides short-term accuracy, while the accelerometer corrects long-term drift.
<math>
\theta = \alpha \cdot (\theta_{\text{prev}} + \omega \cdot \Delta t) + (1 - \alpha) \cdot \theta_{\text{acc}}
</math>
Where:
* <math>\omega</math> is the angular velocity from the gyroscope
* <math>\theta_{\text{acc}}</math> is the angle derived from the accelerometer
* <math>\alpha</math> is a constant between 0.95 and 0.98
This gives us smooth and relatively accurate estimates for roll and pitch in real time.
== Results ==
After completing the sensor initialization, calibration, and complementary filter implementation, we tested our system by manually changing the orientation of the MPU6050 module and observing the real-time calculated attitude angles: pitch, roll, and yaw. These values were displayed on the OLED screen in real time.
=== Initial State ===
In the initial state, the sensor was placed flat and stationary on the table. The calculated angles were close to zero, fluctuating slightly within ±1° due to sensor noise and environmental vibration.
[[File:pitchrollyaw_initial.png|center|thumb|500px|Initial state: pitch ≈ 0°, roll ≈ 0°, yaw ≈ 0° (flat and stable).]]
=== Pitch Variation===
We manually tilted the sensor forward and backward around the Y-axis to generate positive and negative pitch angles.
<div style="display: flex; gap: 30px; justify-content: center;">
<div style="text-align: center;">
[[File:pitch_positive.jpeg|thumb|340px|Pitch ≈ +45°]]
</div>
<div style="text-align: center;">
[[File:pitch_negative.jpeg|thumb|340px|Pitch ≈ -45°]]
</div>
</div>
The pitch angle responded clearly and symmetrically to changes in tilt. The results remained stable when holding the angle.
=== Roll Variation ===
Next, we tilted the sensor side-to-side around the X-axis to test roll estimation.
<div style="display: flex; gap: 30px; justify-content: center;">
<div style="text-align: center;">
[[File:roll_positive.jpeg|thumb|340px|Roll ≈ +45°]]
</div>
<div style="text-align: center;">
[[File:roll_negative.jpeg|thumb|340px|Roll ≈ -45°]]
</div>
</div>
The roll angle also showed accurate and consistent results. There was some fluctuation due to hand-held movement, but the trend was clear and repeatable.
=== Yaw Rotation ===
Since our yaw angle is calculated by integrating the Z-axis angular velocity, it is expected to drift over time. However, for short-term motion, it could still reflect relative rotation. We rotated the device on a flat surface and observed the change.
<div style="display: flex; gap: 30px; justify-content: center;">
<div style="text-align: center;">
[[File:yaw_0deg.jpeg|thumb|340px|Yaw ≈ 0°]]
</div>
<div style="text-align: center;">
[[File:yaw_90deg.jpeg|thumb|340px|Yaw ≈ 90°]]
</div>
</div>
The yaw angle changed appropriately during rotation. However, due to the lack of a magnetometer, long-term drift is still present and was not corrected in our system.
=== Summary ===
The table below summarizes the approximate angles observed during different manual movements. The "Reference" column represents rough estimates of the sensor orientation based on intuition and relative movement, not exact measured angles.
{| class="wikitable"
! Test Condition          !! Estimated Tilt !! Measured Angle (OLED) !! Observation
|-
| Flat (Initial)          || ≈ 0°          || 0° ± 1°                || Stable near zero
|-
| Pitch Forward            || ~ +45°        || +46°                  || Correct trend
|-
| Pitch Backward          || ~ -45°        || -46°                  || Correct trend
|-
| Roll Right              || ~ +45°        || +46°                  || Correct trend
|-
| Roll Left                || ~ -45°        || -48°                  || Correct trend
|-
| Yaw No Rotation          || ~ 0°          || 0°                    || As expected
|-
| Yaw Rotated Clockwise    || ~ +90°        || +91°                  || Matches rotation
|}
Note: The reference angles were estimated by eye during manual movement. No precise angle measurement tools were used.
Pitch and roll estimation was stable and consistent throughout the tests. The angle values responded smoothly to manual tilting and aligned well with expected trends within an approximate ±45° range.
Yaw angle changes were visible and directionally accurate during short-term rotation, but drifted over time due to the lack of a magnetometer for correction.
All three angles were displayed clearly on the OLED screen and updated in real time at approximately 100 Hz.
Overall, the complementary filter worked effectively for basic attitude estimation using only the MPU6050 sensor, especially for roll and pitch. The system demonstrates reliable performance for short-term orientation tracking without external reference.
== Discussion ==
=== Accuracy and Stability of Roll and Pitch ===
The complementary filter worked well in estimating roll and pitch angles. These two values stayed stable when the sensor was stationary, and responded predictably when the module was manually tilted. The accelerometer provides a consistent long-term reference by measuring gravity, while the gyroscope enhances short-term responsiveness due to its ability to capture quick changes in angular velocity. Minor fluctuations (within ±1°) were observed, likely caused by hand tremors or ambient vibrations, but overall the performance was satisfactory for basic real-time tracking.
=== Yaw Angle Limitations ===
Yaw angle is significantly more difficult to estimate. Unlike pitch and roll, which rely on the gravity vector, yaw involves rotation around the vertical (Z) axis, and cannot be observed by the accelerometer. In this project, yaw was estimated by integrating the gyroscope’s Z-axis angular velocity. While this method works for short-term orientation changes, it introduces drift over time because small sensor biases accumulate with each integration step. Without a magnetometer (e.g., to detect Earth's magnetic field), yaw estimation lacks an absolute reference, making it unreliable in the long term.
=== Display and Refresh Rate ===
The OLED screen displays the estimated angles in real time at roughly 100 Hz. This update rate was sufficient to observe smooth changes during hand-held motion. However, due to the limited resolution and refresh speed of the OLED, rapid or subtle angle changes may not be visually apparent. For more precise analysis, data could be logged via serial communication and plotted on a PC.
=== Potential Improvements ===
Several enhancements could improve the accuracy and expand the capabilities of this system:
* Adding a '''magnetometer''' (e.g., HMC5883L) to correct yaw drift and provide an absolute heading.
* Implementing a more advanced fusion algorithm such as a '''Kalman filter''' or '''Madgwick filter''' for better dynamic performance.
* Including a '''calibration routine''' at startup to correct sensor biases and scaling errors.
* Sending angle data to a PC or mobile device over serial or Bluetooth for richer visualization and analysis.
These changes would bring the system closer to what is used in real-world IMU applications, especially in drones and robotics.
=== Applications and Extensions ===
Although this is a small-scale project, the techniques used here reflect real principles behind many motion-sensing systems. Possible applications include:
* Orientation feedback in drones or quadcopters
* Balancing control in two-wheeled robots
* Gesture recognition in wearable or handheld devices
* Head tracking in VR or AR environments
By building this system from scratch—including raw register access, filtering, and angle estimation—we’ve gained a practical understanding of how physical motion is sensed and processed in embedded systems. This hands-on experience ties directly into the themes of the Physics of Sensors course.
== References ==
* [1] '''MPU6050 Register Map and Datasheet''', InvenSense. 
https://invensense.tdk.com/products/motion-tracking/6-axis/mpu-6050/
* [2] '''STM32F103C8T6 Datasheet''', STMicroelectronics. 
https://www.st.com/en/microcontrollers-microprocessors/stm32f103c8.html
* [3] '''How to Interface the MPU6050 (GY-521) with STM32''', Controllerstech. 
https://controllerstech.com/how-to-interface-mpu6050-gy-521-with-stm32/
* [4] '''STM32 I2C for MPU6050 (e.g., GY-521) Get Angle''', GitHub Repository by creative-apple. 
https://github.com/creative-apple/STM32_MPU6050_ComplementartFilter

Latest revision as of 20:06, 6 April 2025

This project involves using an STM32 microcontroller and an MPU6050 sensor module to measure angular velocity and acceleration. The collected sensor data will be processed to determine the attitude angles (roll, pitch, and yaw) of the system. The project will include sensor calibration, data filtering (e.g., complementary or Kalman filter), and real-time angle computation for accurate motion tracking applications.


Introduction

In this project, we built a simple attitude estimation system using the STM32F103C8T6 microcontroller and the MPU6050 inertial measurement unit (IMU). The MPU6050 contains a 3-axis accelerometer and a 3-axis gyroscope, which together allow us to sense both linear acceleration and angular velocity in space.

Our goal was to estimate the orientation of the sensor in real time—specifically the roll, pitch, and yaw angles—by processing the raw physical signals output by the sensor. The core idea is based on how physical forces like gravity and rotational motion affect the internal elements of MEMS sensors, and how these effects can be digitized and interpreted.

To make the system work, we wrote low-level I²C communication routines to read data directly from the MPU6050 registers. The raw measurements were then converted into meaningful physical quantities, and passed into a complementary filter, which combines accelerometer and gyroscope data to produce smoother and more stable angle estimates.

The main steps of the project include:

  • Reading raw acceleration and gyroscope data via I²C
  • Calibrating the sensor to reduce offset and random noise
  • Computing roll and pitch using a complementary filter
  • Updating and displaying the estimated angles in real time on an OLED screen

Although this system is relatively simple, it closely reflects the principles used in real-world applications like drone stabilization, smartphone orientation sensing, and robot balancing. More importantly, it helps us explore how sensor physics—particularly the detection of inertial forces—can be harnessed in embedded systems to measure motion and orientation.

Team Members

LI DING

FAN XUTING

Project Overview

The core idea of this project is to estimate the orientation (attitude) of an object in space using inertial sensor data. We used the MPU6050 module, which integrates a 3-axis accelerometer and a 3-axis gyroscope, to measure two different physical quantities: linear acceleration and angular velocity. These are fundamental mechanical observables when analyzing motion.

The data from the sensor is acquired through I²C communication using the STM32F103C8T6 microcontroller. However, the raw measurements—especially from the gyroscope—tend to drift over time, and the accelerometer is sensitive to external vibrations. Therefore, we applied a complementary filter to combine the short-term precision of the gyroscope with the long-term stability of the accelerometer. This approach helps us reduce noise and improve the reliability of the estimated angles.

Our objective is to continuously compute the roll, pitch, and yaw angles of the sensor in real time. In practice, only roll and pitch can be estimated reliably without a magnetometer, since yaw depends on integrating rotational velocity around the vertical axis and is subject to drift.

Systems like this are commonly found in drones, balancing robots, camera gimbals, and even smartphones for orientation detection. In our project, we replicated the basic functionality of such systems on a smaller scale in order to understand how physical quantities—like gravity and rotation—can be sensed, processed, and interpreted through embedded electronics.

Setup

Equipment

The following components were used to build our attitude estimation system:

  • **STM32F103C8T6 ("Blue Pill")** – A low-cost 32-bit microcontroller used here to handle I²C communication, filtering, and OLED output.
  • **MPU6050** – A 6-axis IMU that combines a 3-axis accelerometer (for sensing gravity and linear motion) and a 3-axis gyroscope (for measuring angular velocity).
  • **USB to TTL Serial Converter** – Used mainly during development to upload programs to the STM32 and read data from the serial port.
  • **Breadboard and jumper wires** – For making temporary connections during prototyping.
  • **3.3V Power Supply** – The MPU6050 operates at 3.3V, which is provided by the STM32 board itself.

The MPU6050 is connected to the STM32 using the I²C protocol. I²C is widely used in sensor interfacing due to its simplicity and ability to handle multiple devices over just two lines (SDA and SCL).

STM32F103C8T6 "Blue Pill" development board

Wiring / Circuit Overview

The sensor communicates with the STM32 via I²C, and the wiring is shown below:

MPU6050 Pin STM32 Pin Notes
VCC 3.3V Sensor powered by STM32
GND GND Common ground reference
SDA PB7 I²C data line
SCL PB6 I²C clock line


Below are two views of the hardware setup: a breadboard diagram and an abstract schematic:

Breadboard wiring diagram
Schematic representation of connections

Software & Code

The firmware was written in C using STM32's standard peripheral libraries. The program runs in a loop, repeatedly collecting data from the MPU6050 and computing the corresponding attitude angles in real time.

The main software tasks are as follows:

  • Initialize I²C interface – Configure STM32 to communicate with the MPU6050 using the I²C protocol.
  • Set up MPU6050 – Select the measurement range for both the accelerometer and gyroscope, and enable continuous data output.
  • Read raw sensor values – Acquire unprocessed data from the accelerometer and gyroscope registers.
  • Convert to physical units – Translate raw values into real-world quantities:
 * Acceleration in g (gravitational units)
 * Angular velocity in °/s
  • Estimate angles – Apply a complementary filter to combine the short-term precision of the gyroscope and the long-term stability of the accelerometer. The filter uses the formula:

θ=α(θprev+ωΔt)+(1α)θacc

  • Output the result – Display the roll and pitch angles on the OLED screen. Optionally, angles can also be printed to the serial terminal for monitoring.

The system updates approximately every 10 milliseconds (100 Hz), which is fast enough to track slow and moderate human motion smoothly.

Theory & Angle Estimation

To estimate the orientation (attitude) of an object using the MPU6050, we need to understand the physical meaning of the quantities it measures. The accelerometer responds to linear acceleration (including gravity), while the gyroscope senses angular velocity. By interpreting and combining these outputs, we can reconstruct the rotation of the sensor in space.

Sensor Principles

The MPU6050 is a MEMS-based 6-axis Inertial Measurement Unit (IMU). Internally, it contains:

  • 3-axis accelerometer – measures linear acceleration along the X, Y, and Z axes, in units of g.
  • 3-axis gyroscope – measures angular velocity around the X, Y, and Z axes, in °/s.

These two types of data correspond to physical forces acting on the sensor:

  • The accelerometer reflects the direction and magnitude of gravity (when stationary) or combined forces (when moving).
  • The gyroscope provides information about how fast the object is rotating around each axis.

By combining both types of data, we can estimate the orientation of the sensor relative to a fixed reference frame.

MPU6050 breakout board showing the chip and I²C interface

Attitude Angles: Roll, Pitch, Yaw

Attitude in 3D space is commonly expressed using three angles:

Angle Axis Description
Roll X-axis Tilting left and right
Pitch Y-axis Tilting forward and backward
Yaw Z-axis Rotating around the vertical axis

In our project, we focus on roll and pitch. Yaw is difficult to measure accurately without a magnetometer, because the accelerometer does not respond to rotation around the vertical axis, and gyroscope-based yaw accumulates drift over time.

Roll (X), Pitch (Y), and Yaw (Z) in 3D space

Using the Accelerometer

When the sensor is at rest or moving slowly, the accelerometer mainly senses the Earth's gravity. We can use the direction of this gravity vector to estimate the tilt angles with respect to the horizontal plane. Using basic trigonometry:

pitch=arctan(axay2+az2)

roll=arctan(ayax2+az2)

These estimates are relatively stable when the sensor is static but become noisy during motion, since linear acceleration disturbs the gravity vector.

Using the Gyroscope

The gyroscope gives angular velocity ω (in °/s), which can be integrated over time to estimate changes in orientation:

θ=θprev+ωΔt

However, this method suffers from drift because small measurement errors accumulate over time.

Complementary Filter

To reduce drift while keeping responsiveness, we apply a complementary filter, which fuses gyroscope and accelerometer data. The gyroscope provides short-term accuracy, while the accelerometer corrects long-term drift.

θ=α(θprev+ωΔt)+(1α)θacc

Where:

  • ω is the angular velocity from the gyroscope
  • θacc is the angle derived from the accelerometer
  • α is a constant between 0.95 and 0.98

This gives us smooth and relatively accurate estimates for roll and pitch in real time.

Results

After completing the sensor initialization, calibration, and complementary filter implementation, we tested our system by manually changing the orientation of the MPU6050 module and observing the real-time calculated attitude angles: pitch, roll, and yaw. These values were displayed on the OLED screen in real time.

Initial State

In the initial state, the sensor was placed flat and stationary on the table. The calculated angles were close to zero, fluctuating slightly within ±1° due to sensor noise and environmental vibration.

Initial state: pitch ≈ 0°, roll ≈ 0°, yaw ≈ 0° (flat and stable).

Pitch Variation

We manually tilted the sensor forward and backward around the Y-axis to generate positive and negative pitch angles.

Pitch ≈ +45°
Pitch ≈ -45°

The pitch angle responded clearly and symmetrically to changes in tilt. The results remained stable when holding the angle.

Roll Variation

Next, we tilted the sensor side-to-side around the X-axis to test roll estimation.

Roll ≈ +45°
Roll ≈ -45°

The roll angle also showed accurate and consistent results. There was some fluctuation due to hand-held movement, but the trend was clear and repeatable.

Yaw Rotation

Since our yaw angle is calculated by integrating the Z-axis angular velocity, it is expected to drift over time. However, for short-term motion, it could still reflect relative rotation. We rotated the device on a flat surface and observed the change.

Yaw ≈ 0°
Yaw ≈ 90°

The yaw angle changed appropriately during rotation. However, due to the lack of a magnetometer, long-term drift is still present and was not corrected in our system.

Summary

The table below summarizes the approximate angles observed during different manual movements. The "Reference" column represents rough estimates of the sensor orientation based on intuition and relative movement, not exact measured angles.

Test Condition Estimated Tilt Measured Angle (OLED) Observation
Flat (Initial) ≈ 0° 0° ± 1° Stable near zero
Pitch Forward ~ +45° +46° Correct trend
Pitch Backward ~ -45° -46° Correct trend
Roll Right ~ +45° +46° Correct trend
Roll Left ~ -45° -48° Correct trend
Yaw No Rotation ~ 0° As expected
Yaw Rotated Clockwise ~ +90° +91° Matches rotation


Note: The reference angles were estimated by eye during manual movement. No precise angle measurement tools were used.

Pitch and roll estimation was stable and consistent throughout the tests. The angle values responded smoothly to manual tilting and aligned well with expected trends within an approximate ±45° range.

Yaw angle changes were visible and directionally accurate during short-term rotation, but drifted over time due to the lack of a magnetometer for correction.

All three angles were displayed clearly on the OLED screen and updated in real time at approximately 100 Hz.

Overall, the complementary filter worked effectively for basic attitude estimation using only the MPU6050 sensor, especially for roll and pitch. The system demonstrates reliable performance for short-term orientation tracking without external reference.

Discussion

Accuracy and Stability of Roll and Pitch

The complementary filter worked well in estimating roll and pitch angles. These two values stayed stable when the sensor was stationary, and responded predictably when the module was manually tilted. The accelerometer provides a consistent long-term reference by measuring gravity, while the gyroscope enhances short-term responsiveness due to its ability to capture quick changes in angular velocity. Minor fluctuations (within ±1°) were observed, likely caused by hand tremors or ambient vibrations, but overall the performance was satisfactory for basic real-time tracking.

Yaw Angle Limitations

Yaw angle is significantly more difficult to estimate. Unlike pitch and roll, which rely on the gravity vector, yaw involves rotation around the vertical (Z) axis, and cannot be observed by the accelerometer. In this project, yaw was estimated by integrating the gyroscope’s Z-axis angular velocity. While this method works for short-term orientation changes, it introduces drift over time because small sensor biases accumulate with each integration step. Without a magnetometer (e.g., to detect Earth's magnetic field), yaw estimation lacks an absolute reference, making it unreliable in the long term.

Display and Refresh Rate

The OLED screen displays the estimated angles in real time at roughly 100 Hz. This update rate was sufficient to observe smooth changes during hand-held motion. However, due to the limited resolution and refresh speed of the OLED, rapid or subtle angle changes may not be visually apparent. For more precise analysis, data could be logged via serial communication and plotted on a PC.

Potential Improvements

Several enhancements could improve the accuracy and expand the capabilities of this system:

  • Adding a magnetometer (e.g., HMC5883L) to correct yaw drift and provide an absolute heading.
  • Implementing a more advanced fusion algorithm such as a Kalman filter or Madgwick filter for better dynamic performance.
  • Including a calibration routine at startup to correct sensor biases and scaling errors.
  • Sending angle data to a PC or mobile device over serial or Bluetooth for richer visualization and analysis.

These changes would bring the system closer to what is used in real-world IMU applications, especially in drones and robotics.

Applications and Extensions

Although this is a small-scale project, the techniques used here reflect real principles behind many motion-sensing systems. Possible applications include:

  • Orientation feedback in drones or quadcopters
  • Balancing control in two-wheeled robots
  • Gesture recognition in wearable or handheld devices
  • Head tracking in VR or AR environments

By building this system from scratch—including raw register access, filtering, and angle estimation—we’ve gained a practical understanding of how physical motion is sensed and processed in embedded systems. This hands-on experience ties directly into the themes of the Physics of Sensors course.

References

  • [1] MPU6050 Register Map and Datasheet, InvenSense.

https://invensense.tdk.com/products/motion-tracking/6-axis/mpu-6050/

  • [2] STM32F103C8T6 Datasheet, STMicroelectronics.

https://www.st.com/en/microcontrollers-microprocessors/stm32f103c8.html

  • [3] How to Interface the MPU6050 (GY-521) with STM32, Controllerstech.

https://controllerstech.com/how-to-interface-mpu6050-gy-521-with-stm32/

  • [4] STM32 I2C for MPU6050 (e.g., GY-521) Get Angle, GitHub Repository by creative-apple.

https://github.com/creative-apple/STM32_MPU6050_ComplementartFilter