Reduce noise from rotors on Quadcopter IMU MPU9250


I am trying to reduce noise from my IMU (MPU9250). I have done some analyses of the data from my IMU an it creates noise on the Roll Axis. Right now my sketch uses a low pass filter to filter out noise. When the quadcopter is laying flat all the axis are 0, when I throttle about 30% the output is about 0+-3 degrees, but the problem is when I full throttle, even if I press dow the quadcopter to the floor where it is 0 without throttle the roll axis is +10 to +25 degrees, pitch holds +-5 witch is ok, but I dont know how to filter out such high error. It is not really noise it is more of an offset error, because it becomes very high continously so my low pass filter slowly goes up to the wrong value in the end. Here are some graphs of some flights. The drone is pressed agains the floor at increasing throttle:

The NewRoll/NewPitch is the low pass filtered values and the OldRoll/OldPitch are the raw values from the IMU. And as you see in the graph it doesnt look like a "noise" but the drone is actually laying flat. My program for the arduino is attached in the .zip folder. (4.6 KB)

Thanks beforehand!
Best regards Max

hey @lordmax2 nice to see you still grinding away on this project.

I got nothing, and had nothing to add to your PID tuning woes… just writing to offer sympathy and encouragement.

And to express hope that you are having fun.

And to ask: in the 6+ months it’s been have you managed to get outdoors and fly something, anything?

I logged quite a bit of air time, and had relatively little trouble with my fleet. Now winter is closing in and I may not be able to for some time. Fly.


Yes I have been grinding on my free time, after work and workouts I have jumped on my computer and done a lot of reading and testing :slight_smile:. Its been a fun project except waiting for parts. This feels like it is the hopefully last step before a real flight, it has only fliped over because it thinks that it is sloped. Thanks!!

I have tried about everything I can think of and now the only soulution in my head is to buy a new IMU, I think I will have to try this one

Check the quality of your power system, specifically what happens to the battery power when the motors are spun up to full speed. How does the logic power on the Arduino and IMU look?

Can you decouple the two: run the motors from the batteries and the Arduino from a bench/USB supply with the grounds connected?

Hi @lordmax2

Are you using the MPU9250's internal digital low pass filters for the gyroscope and accelerometer? For a quadcopter the 20Hz setting is good for both sensors.

Also, to estimate angle and reduce noise it's necessary fuse the gyroscope and accelerometer. The accelerometer is noisy over the short term, but stable over the long term. The gyroscope by contrast is stable over the short term, but drifts over time. Using a sensor fusion algorithm such as a complementary filter allows you simultaneously take advantage of the gyroscope's short term and accelerometer's long term stablility. The MPU9250 also contains a Digital Motion Processor (DMP) that can calculate the roll and pitch angles for you.

An easier route to getting your quadcopter airborne, is to use angular rate in degrees per second or radians per second rather than angles, since the x, y and z axes can be handled separately. (Changes to the roll, pitch and yaw angles by contrast affect each other). In any case, if you think about it, rate control is how most aircraft respond to pilot input, the further you pull the stick the faster the aircraft turns.

There's no one solution here, what I did was to take the pilot's throttle, roll, pitch and yaw commands. I then mapped the roll, pitch and yaw values to degrees per second, around ±250°/s for stick minimum and maximum, these became the set points to three rate PID controllers. The raw throttle value remained unchanged.

The gyrocope's raw output was also be converted to degrees per second for roll, pitch and yaw rates, these became the input for the previously mentioned rate PIDs.

The quadcopter can fly on just the control loops' proportional setting alone, (other terms can be added later). Each P controller simply subtracts the gyroscope from the pilot input and multiplies this by a gain factor:

P control loop = (pilot set point - gyrocope input) * gain

The pilot setpoint is specifying where we want to be in terms of the aircraft's angular rotation and the gyro input is where we currently are. In effect the closed loop is driving the motors to allow the gyroscope to shadow the pilots commands.

It's important to note that the output from the control loops don't have any units as such. These outputs were then mixed and used offset the raw throttle for each motor:

motor1 = rawThrottle + rollRateOut + pitchRateOut + yawRateOut;
motor2 = rawThrottle - rollRateOut + pitchRateOut - yawRateOut;
motor3 = rawThrottle - rollRateOut - pitchRateOut + yawRateOut;
motor4 = rawThrottle + rollRateOut - pitchRateOut - yawRateOut;

Following that the motor values were mapped and contrained using the Arduino map and constrain functions, before sending them out as PWM signals to the ESC using the Arduino analogWrite() function at 490Hz.

Auto-level where the airelon and elevator sticks represent a roll and pitch angle, can be appended as a later addition to this existing system.

Or not. After I switched from angle to rate ("acro") mode flying I turned off the accelerometer and never looked back…

Now if I use stability it is actually harder to fly.



This sounds interesting. Because my goal from the beginning was to make a drone that can be flewn by anyone, it should basically be easy to fly. But this sounds like it can be easier to do part of the things I am out for, complete stabilizaton (and maybe a intermediate mode). Can I from the MPU9250.h library get the degrees per second? And it sounds practical because it doesnt really need to be "calibrated", correct me if I am wrong :slight_smile:

Hi @lordmax2

The method I'm describing is know variously as either rate, gyro or acro mode. The term "acro" is sometimes used, because in this mode it's possible to perform acrobatic flips and rolls.

As alto777 suggests, this is the mode that most experienced drone pilots generally use, since it provides the most natural flying characteristics without additional support from the flight controller.

While this mode is the by far the easiest to implement from a programming perspective, it unfortunately isn't the easiest to fly for a beginner, since simultaneously controlling throttle, roll, pitch and yaw in a 3D world can be a bit overwhelming at first.

It is however possible to a least start with rate mode and tune up the PID loops to at least get airborne, even it's just a hover and then move on to implementing stabilised/auto-level mode.

By far the most difficult aspect of auto-level is the angle estimation algorithm. The issue is that unlike angular rate measurements, the roll, pitch and yaw angles are not independent. Also, the angles are a measurement of the aircraft's body with respect to a fixed world axis, which requires rotational mapping in 3D. There's also the additional complication of sensor fusion as well, (gyroscope, accelerometer and possibly magnetometer). From a mathematical perspective it opens up a can of worms. Fortunately there are some ready made software libraries available.

It's possible to get simpler schemes that use Euler angles with roll/pitch cross coupling working on an 8-bit AVR microcontroller, such as an Arduino Uno/Nano/Micro/Pro Mini:

More complex algorithms such as Madgwick or Mahony filters will most likely require more computing power (ARM or ESP32):

Sounds interesting! Will definatley try it out. I ordered a new IMU (the adafruit above) sins my MPU9250 gave a lot of noise, and I accidently broke it when I removed it. And the other one I mounted doesnt give a pitch value. But it should arrive very soon! I will update you if I succeed with the new one (or fail) :smiley: