/********************************************************
 * PID Adaptive Tuning Example
 * One of the benefits of the PID library is that you can
 * change the tuning parameters at any time.  this can be
 * helpful if we want the controller to be agressive at some
 * times, and conservative at others.   in the example below
 * we set the controller to use Conservative Tuning Parameters
 * when we're near setpoint and more agressive Tuning
 * Parameters when we're farther away.
 ********************************************************/

#include <PID_v2.h>

#define PIN_INPUT 0
#define PIN_OUTPUT 3

// Define the aggressive and conservative Tuning Parameters
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;

// Specify the links and initial tuning parameters
PID_v2 myPID(consKp, consKi, consKd, PID::Direct);

void setup() {
  myPID.Start(analogRead(PIN_INPUT),  // input
              0,                      // current output
              100);                   // setpoint
}

void loop() {
  const double input = analogRead(PIN_INPUT);

  double gap = abs(myPID.GetSetpoint() - input);  // distance away from setpoint
  if (gap < 10) {
    // we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  } else {
    // we're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }

  const double output = myPID.Run(input);
  analogWrite(PIN_OUTPUT, output);
}
