quadcopter project

Hi guys finally i was able to create an account after several days of searching through the net for the solutions i needed for my project.

Basically i have an H quadcopter with arduino microcontroller and an MPU6050, my goal is to let the quadcopter to hover.

I quiet understand how PID works but i can't seem to tune it. The biggest challenge is I will NOT have a radio controller to aid me, just the coding.

my code is... from a source

error = setPoint - angle
errSum += errordt
dErr = (error-lastErr)/dt
out = kp
err + kierrSum + kddErr;

m1.writeMicroseconds(1300 + out);
m2.writeMicroseconds(1300 - out);

lastErr = error;

so i'm just trying to test its roll capability, my problem is it always overshoots and starts to wobble so much like its gonna die,

and my kp is like 1, ki 0 kd 0. I tried alot of numbers still getting the same behaviour.

am I doing it right? im losing hope

First, see how I encapsulate CODE with the “</>” button.

error = setPoint - angle
errSum += error*dt
dErr = (error-lastErr)/dt
out = kp*err + ki*errSum + kd*dErr;

m1.writeMicroseconds(1300 + out);
m2.writeMicroseconds(1300 - out);

lastErr = error;

I assume you meant:

out = kp*error + ki*errSum + kd*dErr;

instead of:

out = kp*err + ki*errSum + kd*dErr;

With your quadcopter held flat, level and stable
do you have any method of determining what the value of ROLL “error” is?
Should the value of Roll “error” be essentially zero?
Is the value of ROLL “error” essentially zero?

Maybe a value of Kp =1 is too large?

How quickly can you recalculate a new PID error?
How quickly does you sensor react to changes in Roll Angle?

I can access all values on my quadcopter since i have it connected on a serial monitor.

My problem is somehow MPU6050 DMP is giving me around ~1.5 degree of roll on a flat surface, so I put 1.5 as my set point, i also tried 0 as set point seems it doesnt change the behavior.

MPU6050 DMP can have deltaT of 14 to 15 millisecond i guess its sufficient enough?

never thought kp of 1 is too large since i saw most people put 200, and on multiwii, a default of 3.3. I will try to give more information i can gather but any suggestion what to change?

You have ...

m1.writeMicroseconds(1300 + out);
m2.writeMicroseconds(1300 - out);

Your code assumes that when PID calculates a Roll Error of 0
then both motors should always go back to a value 1300?
Does a value of 1300 for both left motor & right motors guarantee a 0° Roll Angle?

Maybe it should be more like this ...

// Global: Left Motor & Right Motor 
// Initialize to OFF;
int leftMotorRPM = 0
int rightMotorRPM = 0;
.
.
.
// If "MOTOR ON" Command then start your engines!
leftMotorRPM = 1300;
rightMotorRPM = 1300;

.
.
.
// Process the ROLL PID 
error = setPoint - angle
errSum += error * dt
dErr = ( error - lastErr ) / dt;
out = ( kp * error ) + ( ki * errSum ) + ( kd * dErr );

// Keep adjusting the previous L/R Motor Speed until the Roll Error = 0
leftMotorRPM += out;
rightMotorRPM -= out;

m1.writeMicroseconds(LeftMotorRPM);
m2.writeMicroseconds(rightMotorRPM);

This way the PID will adjust the Left Motor and Right Motor
until the ROLL "error" goes to zero
then maintain those final RPM's for a stable 0° Roll Angle?

Maybe, this explains the unstable behavior?
And now you can boost Kp for quicker reaction without oscillation?

thank you for pointing that out maybe it is the solution to my problem :smiley:

i will post later the results and my quadcopter (just wanna share). I need to go to school in an hour for classes.

Thank you very much for the ideas :slight_smile: