// MPU-6050 Short Example Sketch // By Arduino User JohnChi // August 17, 2014 // Public Domain #include<Wire.h> #include <Servo.h> Servo firstESC, secondESC,thirdESC,fourthESC; //Create as much as Servoobject you want. You const int MPU=0x68; // I2C address of the MPU-6050 int speed1=2000,speed2=0,speed3=0,speed4; int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; float integ=0,der=0,pidx=0,kp = .5,ki=0.00005 ,kd=.01,prerror,dt=100; void setup(){ firstESC.attach(3); // attached to pin 9 I just do this with 1 Servo secondESC.attach(5); // attached to pin 9 I just do this with 1 Servo thirdESC.attach(6); // attached to pin 9 I just do this with 1 Servo fourthESC.attach(9); // attached to pin 9 I just do this with 1 Servo Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); // PWR_MGMT_1 register Wire.write(0); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); Wire.beginTransmission(MPU); Wire.write(0x1c); // PWR_MGMT_1 register Wire.write(0<<3); // set to zero (wakes up the MPU-6050) Wire.endTransmission(true); Serial.begin(9600); firstESC.writeMicroseconds(0); secondESC.writeMicroseconds(0); thirdESC.writeMicroseconds(0); fourthESC.writeMicroseconds(0); firstESC.writeMicroseconds(2000); secondESC.writeMicroseconds(2000); thirdESC.writeMicroseconds(2000); fourthESC.writeMicroseconds(2000); delay(2000); firstESC.writeMicroseconds(700); secondESC.writeMicroseconds(700); thirdESC.writeMicroseconds(700); fourthESC.writeMicroseconds(700); delay(2000); } void loop(){ Wire.beginTransmission(MPU); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU,4,true); // request a total of 14 registers AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L) AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L) firstESC.writeMicroseconds(0); secondESC.writeMicroseconds(700-(pidx/10)); thirdESC.writeMicroseconds(700+(pidx/10)); fourthESC.writeMicroseconds(0); PID(); //if(Serial.available()) //speed1 = Serial.parseInt(); //Serial.print("AcX = "); Serial.print(AcX); //Serial.print(" | AcY = "); Serial.print(AcY); //Serial.println(); //delay(333); } void PIdD() { float error; error = (atan2(AcY,AcZ)*180/3.14); now = millis(); dt = now-ptime; if(error>0)error=180-error; else error = -(180+error); error=0-error; integ = integ+(error*dt) ; der = (error - prerror)/dt ; prerror=error; pidx = (kp*error); pidx+=(ki*integ); pidx+=(kd*der); if(pidx>1000)pidx=1000; if(pidx<-1000)pidx=-1000; ptime = now; } The above is my program for my quadcopter, but now I have to tune the PID values, that is kp, ki, and kd. My accelome is at 2g. Please point to me what is wrong with the program? Is the error signal not appropriate? Please also give me or help me choose correct PID tuning. My limitation is I always have to connect my Arduino to pc and change kp ki or kd values, that is I have no remote control available currently.
AcX=Wire.read()<<8|Wire.read();is not well-defined. (2) Reatan(az/ay)mentioned in a comment, instead useatan2(az, ay)$\endgroup$