Adaptive complementary filter for MPU6050 on Arduino Nano. Roll, pitch, yaw with dynamic gyro/accel sensor fusion.
| Component | Details |
|---|---|
| MCU | Arduino Nano |
| IMU | MPU6050 (I2C, address 0x68) |
| Display | SSD1306 OLED 128x64 |
Wiring
| MPU6050 | Arduino Nano |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
| SSD1306 | Arduino Nano |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
Install via Arduino Library Manager:
The filter blends gyroscope and accelerometer data using a blending factor k:
roll = k * GYR_X + (1 - k) * ACC_X
- Gyroscope : accurate short-term, drifts long-term
- Accelerometer : stable long-term reference, noisy short-term
- k : controls the blend. Adapts continuously based on angular velocity
Instead of a fixed k, this implementation maps RAW_GYR_X to k in real time:
float k_constrained = constrain(abs(RAW_GYR_X), 0, 5);
k = mapFloat(k_constrained, 0, 5, 0.02, 0.98);- Still - k near 0.02 → trust accelerometer
- Moving - k near 0.98 → trust gyroscope
| Output | Method |
|---|---|
| Roll | Complementary filter (gyro + accel) |
| Pitch | Complementary filter (gyro + accel) |
| Yaw | Gyro integration only — drifts, no absolute reference |
- Yaw drifts indefinitely - no magnetometer correction
- After extended motion, roll/pitch snaps back on stopping - unavoidable with this filter type
- Calibration offsets are hardcoded - measure yours and update the error variables
When motion stops, k drops from 0.98 to near 0.13 in a single sample.
This instant drop means the filter suddenly trusts the accelerometer almost fully causing a visible snap in the roll/pitch output after movement.
Exponential smoothing fixes this by letting k slide gradually:
k = alpha * new_k + (1 - alpha) * k;- High alpha -> k changes fast
- Low alpha -> k changes slowly, smoother output
This is the same blending principle as the complementary filter itself applied to k instead of angle. Not implemented in this version, next step is Mahony.
- Complementary Filter Theory — Phil's Lab
- MPU6050 Register Map
- Mahony Filter — next step beyond this implementation
- Madgwick Filter Paper
