I am using Arduino Uno, with PID library and Jeff Rowberg library for MPU6050 i.e I2Cdev.h, MPU6050_6Axis_MotionApps20.h.

There is one PID for each axis i.e Pitch and Roll, I am getting output that wobbles and is unstable. I don't know whether my code is wrong or something else.

Errors which I feel are:

  • I am using Esc.write(), I know Microseconds should be used but it feels very light, even it doesn't wobble.
  • Kalman Filter not used, but I am getting the pitch, roll, yaw.
  • PID library (By Brett Beauregard) not suitable for Quadcopter.
  • else if (mpuIntStatus & 0x02) // wait for correc available data length, should be a VERY short wait
             while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); 
    This statement in loop making loop slow, it's written in its comment and maybe it making pid compute upset

Please look at code.

        // display Euler angles in degrees
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        yaw = ypr[0] * 180/M_PI;
        pitch = ypr[1] * 180/M_PI;
        roll = ypr[2] * 180/M_PI;

        Input = pitch;
        RInput = roll;

        //Sample Time is 10 for both PID.


        if(armed == 1) {
          int m1 = throttle.toInt() + Output;
          int m2 = throttle.toInt() + ROutput;
          int m3 = throttle.toInt() - Output;
          int m4 = throttle.toInt() - ROutput;

 int angle1 = map(m1, 0, 100, 0, 180);
 ESC1.write(angle1); //FRONT PITCH+
 int angle2 = map(m2, 0, 100, 0, 180);
 ESC2.write(angle2); //LEFT ROLL+
 int angle3 = map(m3, 0, 100, 0, 180); 
 ESC3.write(angle3); //BACK PITCH-
 int angle4 = map(m4, 0, 100, 0, 180); 
 ESC4.write(angle4); //RIGHT ROLL-

Kp = 0.25, Ki = 0.04, Kd = 0.05 | RKp = 0.25, RKi = 0.04, RKd = 0.05

From testing: if I shake my Quadcopter fast by hand it behaves like PID is activated and works as wanted, but suddenly after a couple of seconds again feel loose, may be PID compute become upset

1 Answer 1


Quadcopters usually use 2-PID loops per axis, a rate loop and an angle loop.

Your quadcopter needs to be very aggressive about its rate of rotation but relatively relaxed about how quickly it returns its angle to the center so it doesn't overshoot. With a single PID it will either be too slow to correct or overshoot and oscillate with no "usable" range of tunings in-between, because in order for its outputs to be strong enough to control the quad it will necessarily be too aggressive to smoothly align with the center position. There is a lot of math that explains why this cannot be achieved with a single loop more rigorously if you care to look into it.

So try setting it up with a PitchAngle PID whose output is the setpoint of a PitchRate PID loop whose output goes to the motors, and similarly with the Roll.

That is only one possible problem though, there is a huge number of things that could be wrong. Are your pitch and roll measurements angles to the horizon or euler angles? how fast is your loop running? Are oscillations induced by the motors causing your accelerometer reading/attitude filter combo to be unusable? Are the PID parameters correct? Is the accelerometer's bias calibrated? Is the gyro drift calibrated? Are all you ESC's calibrated the same way?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.