arduinno PID library error

Hi I am trying to PID control the Arduino-Quadcopter. I have installed PID library from github as well as library given by arduino. I have also changed my user account on windows. (in case former account has copies of libraries). but the error remain the same.

->main is my sketch name
-> I have also tried C:\Program Files\Arduino\libraries this location but error remain the same. can anyone help?

main:51: error: no matching function for call to 'PID::PID(float*, float*, float*, float&, float&, float&, int)'
main.ino:51:54: note: candidates are:
In file included from main.ino:37:0:
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:18:5: note: PID::PID(double*, double*, double*, double, double, double, int)
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
^
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:18:5: note: no known conversion for argument 1 from 'float*' to 'double*'
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:5:7: note: PID::PID(const PID&)
class PID
^
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:5:7: note: candidate expects 1 argument, 7 provided
main:52: error: no matching function for call to 'PID::PID(float*, float*, float*, float&, float&, float&, int)'
main.ino:52:53: note: candidates are:
In file included from main.ino:37:0:
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:18:5: note: PID::PID(double*, double*, double*, double, double, double, int)
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and
^
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:18:5: note: no known conversion for argument 1 from 'float*' to 'double*'
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:5:7: note: PID::PID(const PID&)
class PID
^
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:5:7: note: candidate expects 1 argument, 7 provided
no matching function for call to 'PID::PID(float*, float*, float*, float&, float&, float&, int)'

main is my sketch name

Not a good idea in the Arduino environment unless you know exactly what you are doing because it uses a hidden main() function.

Please post your whole program using code tags.

oh You are right. My bad. I have changed the name of my sketch to mainn :wink: thanks but the problem is still there. :frowning:

UKHeliBob:
Please post your whole program using code tags.

float pitch,roll,dpitch,droll;
volatile double throttle;
float pkp =0.92, pki= 0, pkd= 0;

float rkp =0.92,rki =0,rkd= 0;


void pid()
{
  r0utput.SetMode(AUTOMATIC);//set pid on may be
 r0utput.SetOutputLimits(-PID_ROLL_INFLUENCE, PID_ROLL_INFLUENCE);
 
  r0utput.Compute();
  
  p0utput.SetMode(AUTOMATIC);
 p0utput.SetOutputLimits(-PID_ROLL_INFLUENCE, PID_ROLL_INFLUENCE);
 
  p0utput.Compute();
}

/////////////////////////////////////////////////////////////
PID p0utput(&AA,&pitch, &dpitch,pkp, pki, pkd, DIRECT); 
PID r0utput(&BB,&roll, &droll, rkp, rki, rkd, DIRECT);

#define PID_ROLL_INFLUENCE 7

P.S
I am calling pid(); in void loop ()

When I said "please post your whole program" what I actually meant was please post your whole program. The snippet that you have posted is no good to man nor beast in diagnosing the problem.

I am actually coding for a Quad. its a bit long and forum does't allow me to post because its exceeding the maximum allowed length. I am uploading it in 2 parts.

here is my code:

// ================================================================
// ===               Sensor Int.                                ===
// ================================================================
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

MPU6050 mpu;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
float AA,BB;
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '

, 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
   mpuInterrupt = true;
}

//------------------------------------------------------------------------------------------\
////////////////// OTHER Init. //////////////////////////
#include <Wire.h>
#include <PID_v1.h>

int esc1= 5; int esc2= 6; int esc3= 7; int esc4= 8 ;
double a,b,c,d;

float dpitch,droll;
float pitch,roll;
volatile double throttle;
float pkp =0.92, pki= 0, pkd= 0;

float rkp =0.92,rki =0,rkd= 0;

/////////////////////////////////////////////////////////////
PID p0utput(&AA,&pitch, &dpitch,pkp, pki, pkd, DIRECT);
PID r0utput(&BB,&roll, &droll, rkp, rki, rkd, DIRECT);
///////////////////////////////////////////////
/////////////////////////////////////////////////

#define PID_ROLL_INFLUENCE 7
////////////////////////PID DATA END//////////////
//--------------------------------------------------------------\

////////////////////////RC_RX Init.///////////////////////////

#define CH1_int_th 0     // Channel 1 interrupt throttle
#define CH1_pin_th 2     // Respective channel Hardware interrupt pin number

#define CH2_int_pt 1     // Channel 2 interrupt pitch
#define CH2_pin_pt 3     // Respective channel Hardware interrupt pin number

#define CH3_int_r1 4     // Channel 3 interrupt roll
#define CH3_pin_r1 19     // Respective channel Hardware interrupt pin number

#define valid_pulse_limit 3000 // [uS] Valid output high pulse time limit for RC controller
#define max_high_time 1895 // [uS] Maximum expected high time
#define min_high_time 1090 // [uS] Minimum expected high time

unsigned long t=0;
int counter;
void init_rc_rx();

volatile unsigned long CH1_t_th=0, CH1_delta_th=0, CH2_t_pt=0, CH2_delta_pt=0, CH3_t_rl=0, CH3_delta_rl=0 ;

// Interrupt ISRs

void CH1_int_ISR()
{
 
 if ((micros()-CH1_t_th) < valid_pulse_limit){
   CH1_delta_th = micros()-CH1_t_th;
 }
 CH1_t_th = micros();
}

void CH2_int_ISR()
{
 
 if ((micros()-CH2_t_pt) < valid_pulse_limit){
   CH2_delta_pt = micros()-CH2_t_pt;
 }
 CH2_t_pt = micros();
}

void CH3_int_ISR()
{
 
 if ((micros()-CH3_t_rl) < valid_pulse_limit){
   CH3_delta_rl = micros()-CH3_t_rl;
 }
 CH3_t_rl = micros();
}

// Initialization\

void init_rc_rx(){

//MAKING PINS INPUT//
 pinMode(CH1_pin_th, INPUT);
 pinMode(CH2_pin_pt, INPUT);
 pinMode(CH3_pin_r1, INPUT);

//ENABLING INTERRUPTS//
 attachInterrupt(CH1_int_th, CH1_int_ISR, CHANGE);
 attachInterrupt(CH2_int_pt, CH2_int_ISR, CHANGE);
 attachInterrupt(CH3_int_r1, CH3_int_ISR, CHANGE);

}

void pid()
{
 r0utput.SetMode(AUTOMATIC);//set pid on may be
r0utput.SetOutputLimits(-PID_ROLL_INFLUENCE, PID_ROLL_INFLUENCE);

r0utput.Compute();
 
 p0utput.SetMode(AUTOMATIC);
p0utput.SetOutputLimits(-PID_ROLL_INFLUENCE, PID_ROLL_INFLUENCE);

p0utput.Compute();
}

// ================================================================
// ===                    Sensor                                                                                            ===
// ================================================================

void sensor_temp() {
   // if programming failed, don't try to do anything
   if (!dmpReady) return;

// wait for MPU interrupt or extra packet(s) available
   while (!mpuInterrupt && fifoCount < packetSize) {
     
   }

// reset interrupt flag and get INT_STATUS byte
   mpuInterrupt = false;
   mpuIntStatus = mpu.getIntStatus();

// get current FIFO count
   fifoCount = mpu.getFIFOCount();

// check for overflow (this should never happen unless our code is too inefficient)
   if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
       // reset so we can continue cleanly
       mpu.resetFIFO();
       Serial.println(F("FIFO overflow!"));

// otherwise, check for DMP data ready interrupt (this should happen frequently)
   } else if (mpuIntStatus & 0x02) {
       // wait for correct available data length, should be a VERY short wait
       while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

// read a packet from FIFO
       mpu.getFIFOBytes(fifoBuffer, packetSize);
       
       // track FIFO count here in case there is > 1 packet available
       // (this lets us immediately read more without waiting for an interrupt)
       fifoCount -= packetSize;
       
            mpu.dmpGetQuaternion(&q, fifoBuffer);
           mpu.dmpGetGravity(&gravity, &q);
           mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
           AA=ypr[1] * 180/M_PI;
           BB=ypr[2] * 180/M_PI;

}
}

2nd part:

//---------------------------------------------------------------------\\

void setup() {
  
  pinMode(esc1,OUTPUT); 
  pinMode(esc2,OUTPUT);
  pinMode(esc3,OUTPUT); 
  pinMode(esc4,OUTPUT);

  init_rc_rx();

// ================================================================
// ===                     SENSOR   SETUP                       ===
// ================================================================
// join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
  
    Serial.begin(115200);
    while (!Serial); // wait for Leonardo enumeration, others continue immediately


    // initialize device

    mpu.initialize();

    
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {
      
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
      //  Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
      //  Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
      
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

}

void loop() {
 
sensor_temp();
pid();


  ///////////////////////////looping/////////////////
      
        
 throttle=map(CH1_delta_th,1004,1968,0,200);
throttle=constrain(throttle,0,200);
      if(1480<CH3_delta_rl<1492)
 { droll=0;
}
    droll=map(CH3_delta_rl,1008,1968,-12,10);

droll=constrain(droll,-16,7);
droll=droll;
          if(1470<CH2_delta_pt<1480)
 { dpitch=0;
}

 dpitch=map(CH2_delta_pt,996,1976,-10,10);

 dpitch=constrain(dpitch,-10,4);
dpitch=dpitch+3;


            if(roll<1 && roll>-1)
 { roll=0;
}     

            if(pitch<1&&pitch>-1)
 { pitch=0;
}
Serial.print("rl ");
Serial.println(pitch);
b=map(throttle+roll+pitch,0,170,0,200); // fl
a=map(throttle-roll+pitch,0,170,0,200);//fr
c=map(throttle-roll-pitch,0,170,0,200);//br
d=map(throttle+roll-pitch,0,170,0,200);
b=constrain(b,0,200); // fl
a=constrain(a,0,200);//fr
c=constrain(c,0,200);//br
d=constrain(d,0,200);
 

     analogWrite (esc3,b);//fl esc3
analogWrite (esc4,d);//bl esc4
analogWrite (esc1,a); //fr esc1
    analogWrite (esc2,c);//br 
   
}

Compiles fine if you change AA, BB, pitch, roll, dpitch, and droll to 'double' instead of 'float'. On the Arduino UNO both types are the same.

Note: I have my warning levels turned up and get a BUNCH of warnings indicating common programming errors. You may want to turn up warnings (in the Preferences dialog) and fix those:

In file included from sketch_aug16a.ino:7:0:
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h: In member function 'uint8_t MPU6050::dmpInitialize()':
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:497:21: warning: variable 'mpuIntStatus' set but not used [-Wunused-but-set-variable]
             uint8_t mpuIntStatus = getIntStatus();
                     ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:347:13: warning: unused variable 'hwRevision' [-Wunused-variable]
     uint8_t hwRevision = readMemoryByte();
             ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:355:13: warning: unused variable 'otpValid' [-Wunused-variable]
     uint8_t otpValid = getOTPBankValid();
             ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h: In member function 'uint8_t MPU6050::dmpGetAccel(int32_t*, const uint8_t*)':
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:580:31: warning: left shift count >= width of type [enabled by default]
     data[0] = ((packet[28] << 24) + (packet[29] << 16) + (packet[30] << 8) + packet[31]);
                               ^
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:580:52: warning: left shift count >= width of type [enabled by default]
     data[0] = ((packet[28] << 24) + (packet[29] << 16) + (packet[30] << 8) + packet[31]);
                                                    ^
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h: In member function 'uint8_t MPU6050::dmpGetGyro(int32_t*, const uint8_t*)':
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:637:31: warning: left shift count >= width of type [enabled by default]
     data[0] = ((packet[16] << 24) + (packet[17] << 16) + (packet[18] << 8) + packet[19]);
                               ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:637:52: warning: left shift count >= width of type [enabled by default]
     data[0] = ((packet[16] << 24) + (packet[17] << 16) + (packet[18] << 8) + packet[19]);
                                                    ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:638:31: warning: left shift count >= width of type [enabled by default]
     data[1] = ((packet[20] << 24) + (packet[21] << 16) + (packet[22] << 8) + packet[23]);
                               ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:638:52: warning: left shift count >= width of type [enabled by default]
     data[1] = ((packet[20] << 24) + (packet[21] << 16) + (packet[22] << 8) + packet[23]);
                                                    ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:639:31: warning: left shift count >= width of type [enabled by default]
     data[2] = ((packet[24] << 24) + (packet[25] << 16) + (packet[26] << 8) + packet[27]);
                               ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:639:52: warning: left shift count >= width of type [enabled by default]
     data[2] = ((packet[24] << 24) + (packet[25] << 16) + (packet[26] << 8) + packet[27]);
                                                    ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h: At global scope:
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:710:9: warning: unused parameter 'dmpData' [-Wunused-parameter]
 uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) {
         ^

/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h: In member function 'uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t, uint8_t*)':
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050_6Axis_MotionApps20.h:731:41: warning: value computed is not used [-Wunused-value]
         if (processed != 0) *processed++;
                                         ^


sketch_aug16a.ino: In function 'void loop()':
sketch_aug16a.ino:281:12: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
sketch_aug16a.ino:288:12: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]


/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050.cpp: In member function 'bool MPU6050::writeMemoryBlock(const uint8_t*, uint16_t, uint8_t, uint8_t, bool, bool)':
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050.cpp:2979:14: warning: 'progBuffer' may be used uninitialized in this function [-Wmaybe-uninitialized]
     uint8_t *progBuffer;
              ^
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050.cpp: In member function 'bool MPU6050::writeDMPConfigurationSet(const uint8_t*, uint16_t, bool)':
/Users/john/Documents/Arduino/libraries/MPU6050/MPU6050.cpp:3084:101: warning: 'progBuffer' may be used uninitialized in this function [-Wmaybe-uninitialized]
                 if (sizeof(progBuffer) < length) progBuffer = (uint8_t *)realloc(progBuffer, length);

One problem appears to be that you are using floats for the parameters when defining the PIDs whereas the library is expecting doubles for those values.

Hence the error messages like

main:51: error: no matching function for call to 'PID::PID(float*, float*, float*, float&, float&, float&, int)'
main.ino:51:54: note: candidates are:
In file included from main.ino:37:0:
C:\Users\4hsan\Documents\Arduino\libraries\PID_v1/PID_v1.h:18:5: note: PID::PID(double*, double*, double*, double, double, double, int)
PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and

HI all :slight_smile:

I have written my own code . Everything works fine but now I am having trouble in PID control of my quad.

PID r0utput(&compAngleX,&roll, &droll, rkp, rki, rkd, DIRECT);

written that as according to:

PID(&Input, &Output, &Setpoint, Kp, Ki, Kd, Direction)

but the problem is, instead of adjusting output with reference of setpoint, PID function is calculating its output with the reference of "setpoint" and "Input" both.
"Input" is sensor's output and "setpoint" is desired roll I want to achieve.

In my understandings, PID should have only calculate or change its "output" when setpoint value is changed. not when the "input" is changed. Am I right?
here is the complete new code:

//================================================================
// ===               Sensor Int.                                ===
// ================================================================
#include<Wire.h>
const int MPU=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;//stores 
double compAngleX,compAngleY,timer;
  double accXangle ,accYangle ,gyroXrate ,gyroYrate;
  double gyroXAngle, gyroYAngle;
 
  int ap=0.955;

//------------------------------------------------------------------------------------------\\
////////////////// OTHER Init. //////////////////////////
#include <Wire.h> 
#include <PID_v1.h>

int esc1= 5;//front right
int esc2= 6;//back right 
int esc3= 7;//front left 
int esc4= 8;//back left
double front_left,front_right,back_left,back_right;

double dpitch,droll;
double pitch,roll;
volatile double throttle;
float pkp =0.41, pki= 0, pkd= 0;

float rkp =0.41,rki =0,rkd= 0;


/////////////////////////////////////////////////////////////
PID p0utput(&compAngleY,&pitch, &dpitch,pkp, pki, pkd, DIRECT);
PID r0utput(&compAngleX,&roll, &droll, rkp, rki, rkd, DIRECT);
///////////////////////////////////////////////
/////////////////////////////////////////////////

#define PID_ROLL_INFLUENCE 10
////////////////////////PID DATA END//////////////
//--------------------------------------------------------------\\

////////////////////////RC_RX Init.///////////////////////////


#define CH1_int_th 0    // Channel 1 interrupt throttle 
#define CH1_pin_th 2     // Respective channel Hardware interrupt pin number

#define CH2_int_pt 1     // Channel 2 interrupt pitch 
#define CH2_pin_pt 3     // Respective channel Hardware interrupt pin number

#define CH3_int_r1 4     // Channel 3 interrupt roll 
#define CH3_pin_r1 19     // Respective channel Hardware interrupt pin number

#define valid_pulse_limit 2000 // [uS] Valid output high pulse time limit for RC controller
#define max_high_time 1895 // [uS] Maximum expected high time
#define min_high_time 1090 // [uS] Minimum expected high time
 

unsigned long t=0;
int counter;
void init_rc_rx();
//void read_rc_rx();  

volatile unsigned long CH1_t_th=0, CH1_delta_th=0, CH2_t_pt=0, CH2_delta_pt=0, CH3_t_rl=0, CH3_delta_rl=0 ;

// Interrupt ISRs

void CH1_int_ISR()
{
  
  if ((micros()-CH1_t_th) < valid_pulse_limit){
    CH1_delta_th = micros()-CH1_t_th;
  }
  CH1_t_th = micros();
}

void CH2_int_ISR()
{
  
  if ((micros()-CH2_t_pt) < valid_pulse_limit){
    CH2_delta_pt = micros()-CH2_t_pt;
  }
  CH2_t_pt = micros();
}

void CH3_int_ISR()
{
  
  if ((micros()-CH3_t_rl) < valid_pulse_limit){
    CH3_delta_rl = micros()-CH3_t_rl;
  }
  CH3_t_rl = micros();
}



// Initialization\\

void init_rc_rx(){
  

  //MAKING PINS INPUT//
  pinMode(CH1_pin_th, INPUT);
  pinMode(CH2_pin_pt, INPUT);
  pinMode(CH3_pin_r1, INPUT);

  //ENABLING INTERRUPTS//
  attachInterrupt(CH1_int_th, CH1_int_ISR, CHANGE);
  attachInterrupt(CH2_int_pt, CH2_int_ISR, CHANGE);
  attachInterrupt(CH3_int_r1, CH3_int_ISR, CHANGE);

}

//---------------------------------------------------------------------\\




void pid()
{
  r0utput.SetMode(AUTOMATIC);//set pid on may be
 r0utput.SetOutputLimits(-PID_ROLL_INFLUENCE, PID_ROLL_INFLUENCE);
 
  r0utput.Compute();
  
  p0utput.SetMode(AUTOMATIC);
 p0utput.SetOutputLimits(-PID_ROLL_INFLUENCE, PID_ROLL_INFLUENCE);
 
  p0utput.Compute();
}



// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void sensor_temp() {
    Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14);  // request a total of 14 registers//wire.requestFrom to request bytes from a slave device.
  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)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
 

  
 accXangle = (atan2(AcY, AcZ) * RAD_TO_DEG);
 accYangle = (atan2(AcX, AcZ) * RAD_TO_DEG);

 gyroXrate = GyX / 16.5;
 gyroYrate = GyY / 16.5;
 
 timer = millis();
 //angular position
 gyroXAngle += gyroXrate * (millis()-timer)/1000;
 gyroYAngle += gyroYrate * (millis()-timer)/1000;
 
 
 //---------------------------\\
 //COMPLIMENTRY FILTER STARTED\\
 //---------------------------\\

 compAngleX = ap * (compAngleX + gyroXAngle) + (1-ap) * accXangle;
 compAngleY = ap * (compAngleY + gyroYAngle) + (1-ap) * accYangle;
 
 //---------------------------\\
 //COMPLIMENTRY FILTER ENDED  \\
 //---------------------------\\

}

void setup() {
  
  pinMode(esc1,OUTPUT); 
  pinMode(esc2,OUTPUT);
  pinMode(esc3,OUTPUT);	
  pinMode(esc4,OUTPUT);

  init_rc_rx();

// ================================================================
// ===                     SENSOR   SETUP                       ===
// ================================================================
 Serial.begin(115200);
/////////////////////// SENSOR READING//////////
 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);
  ///////////////////////////////////////

}

void loop() {

sensor_temp();
pid();


  ///////////////////////////looping/////////////////
      


throttle=map(CH1_delta_th,988,1968,0,200);
throttle=constrain(throttle,0,200);
Serial.println("");
Serial.println("");
Serial.println("");
Serial.print("throttle Rcv");
Serial.println(CH1_delta_th);
Serial.print("Roll Rcv");
Serial.println(CH3_delta_rl);
Serial.print("Pitch Rcv");
Serial.println(CH2_delta_pt);
Serial.println("");
Serial.println("");
Serial.println("");



droll=map(CH3_delta_rl,1008,1968,-45,45);
      if(CH3_delta_rl>1470 && CH3_delta_rl<1490)
 { droll=0;
}      
droll=constrain(droll,-45,45);


 dpitch=map(CH2_delta_pt,970,1976,-45,45);
          if(CH2_delta_pt>1460&&CH2_delta_pt<1490)
 { dpitch=0;
}

 dpitch=constrain(dpitch,-45,45);




            if(roll<1.86 && roll>-1.86)
 { roll=0;
}     

            if(pitch<1.86&&pitch>-1.86)
 { pitch=0;
}


Serial.print("pitch ");
Serial.println(pitch);
Serial.print("roll ");
Serial.println(roll);
Serial.print("throttle ");
Serial.println(throttle);

front_left=map(throttle+roll+pitch,0,170,0,200); // front left
front_right=map(throttle-roll+pitch,0,170,0,200);//front right
back_right=map(throttle-roll-pitch,0,170,0,200);//back right
back_left=map(throttle+roll-pitch,0,170,0,200);//back left

front_left=constrain(front_left,0,240); // front left
front_right=constrain(front_right,0,240);//front right
back_right=constrain(back_right,0,240);//back right
back_left=constrain(back_left,0,240);//back left
 
Serial.print("front_left ");
Serial.println(front_left);
Serial.print("front_right ");
Serial.println(front_right);
Serial.print("back_right ");
Serial.println(back_right);
Serial.print("back_left ");
Serial.println(back_left);

//======Writing Values====\\
analogWrite (esc3,front_left);//fl esc3
analogWrite (esc4,back_left);//bl esc4
analogWrite (esc1,front_right); //fr esc1
analogWrite (esc2,back_right);//br 
delay(1000);
    /////////////////////////////////////////////
}