PID control with different parameters of setpoint

Hi Geeks,
I have made a code, I don’t connect any sensor, just use a function generator and oscilloscope sumlated the PID control,but I find when I set different setpoint ,there is no change in output. for example setpoint =1,10,1000, in additional,when no sensor connect the arduino,what setpoint=5 means?

//#include <PID_v1.h>
const int inPD0 = A0;
const int inPD1 = A2;
const int inMonitor = A4;
const int inPotSP  = A6; // setpoint
const int inPotOFS = A8; // offset
const int inSPDT0 = 42;
const int inSPDT1 = 44;
const int LockInMode = 0;
const int MaxVisMode = 1;
const int outPID    = DAC1;
const int outOFFSET = DAC0;
const double Min = -2047;
const double Max = 2048;
const double DACmin = 0;
const double DACmax = 4095;


unsigned long lastTime;
double Input, Output, Setpoint;
//(derivative kick)double errSum, lastErr;
/*because the setpoint is change, so there is a derivative kick here,for dError/dt=dSetpoint/dt-dInput/dt Setpoint is constant */
/*dError/dt= -dInput/dt*/
double ITerm, lastInput;
//(turnings changes)double errSum, lastInput;
double kp, ki, kd;
int SampleTime = 10; //1 sec
double outMin, outMax;
bool inAuto = false;

#define MANUAL 0
#define AUTOMATIC 1

#define DIRECT 0
#define REVERSE 1
int controllerDirection = DIRECT;




void Compute()
{
  if(!inAuto) return;//?
  unsigned long now = millis();
  int timeChange = (now - lastTime);
  if(timeChange>= SampleTime)
  {
    /*Compute all the working errorvariables*/
    //double tmp1 = analogRead(inPD0);
    //double tmp2 = analogRead(inPD1);
    Input = analogRead(inPD0);
    double error = Setpoint - Input; 
    ITerm += (ki * error);
    if(ITerm > outMax) ITerm= outMax;/*reset windup*/
    else if(ITerm< outMax) ITerm= outMin;
    //(turning changes)errSum += error;
    //(derivative kick)double dErr = (error -lastErr);
    double dInput = (Input - lastInput);
    /*compute the output*/
    Output = kp * error + ITerm - kd * dInput;
    if(Output > outMax) Output = outMax;
    else if(Output < outMin) Output = outMin;
    //(turning changes)Output = kp * error + ki * errSum - kd * dInput;
    //(derivative kick)Output = kp * error + ki * errSum + kd * dErr;
    /*remember some variables for next time*/
    //(derivative kick)lastErr = error;/*that is no need at all*/
    lastInput = Input;
    lastTime = now;
   
    
  }
}
void SeTurnings(double Kp, double Ki, double Kd)
{
  if(kp<0 || ki<0 || kd<0) return;//direction
  double SampleTimeSec = ((double)SampleTime)/1000;
  kp = Kp;
  ki = Ki * SampleTimeSec;
  kd = Kd / SampleTimeSec;
  if(controllerDirection ==REVERSE)
  {
    kp = (0 - kp);
    ki = (0 - ki);
    kd = (0 - kd);}
}
void SetSampleTime(int NewSampleTime)
{
  if (NewSampleTime > 0)
  {
    double ratio = (double)NewSampleTime / (double)SampleTime;
    ki *= ratio;
    kd /= ratio;
    SampleTime = (unsigned long) NewSampleTime;
  }
}
void SetOutputLimits(double Min, double Max)
{
  if (Min > Max) return;
  outMin = Min;
  outMax = Max;
  if(Output > outMax) Output = outMax;
  else if(Output <outMin) Output = outMin;
  if(ITerm > outMax) ITerm = outMax;
  else if(ITerm < outMin) ITerm = outMin;
}
void SetMode(int Mode)
{
  bool newAuto = (Mode == AUTOMATIC);
  if(newAuto && !inAuto)
  {/*we just went from manual to auto*/
    Initialize();//initialization
    }
  //inAuto = (Mode == AUTOMATIC);
  inAuto = newAuto;
}
void Initialize()
{
  lastInput = Input;
  ITerm = Output;
  if(ITerm> outMax) ITerm= outMax;
  else if(ITerm< outMin) ITerm = outMin;
}
void SetControllerDirection(int Direction)
{
  controllerDirection = Direction;
 }


void setup()
{ 
  Setpoint   = 3;
  kp = 10;
  ki = 10;
  kd = 1;
  

  pinMode(inPD0, INPUT);
  pinMode(inPD1, INPUT);
  pinMode(inMonitor, INPUT);
  pinMode(inPotOFS, INPUT);
  pinMode(inPotSP,  INPUT);
  pinMode(inSPDT0, INPUT_PULLUP);
  pinMode(inSPDT1, INPUT_PULLUP);

  SeTurnings(kp, ki, kd);
  SetOutputLimits(outMin, outMax);
  SetMode(AUTOMATIC);
  Serial.begin(9600);
  
}

int SPDTread(int pin0, int pin1){
  int tmp = 0;
  if( digitalRead(pin0) == 0 ){ tmp += 1; }
  if( digitalRead(pin1) == 0 ){ tmp += 2; }
  return tmp;
}
void writeUSB(double x, const int n)
{
  char str[n];
  sprintf(str, "%f", x);
  SerialUSB.write(str, n);
  SerialUSB.write("\n", 1);

}

void loop() {

  SerialUSB.write("+++++++++", 9);
  SerialUSB.write("Setpoint:", 9);
  writeUSB(Setpoint, 5);
  SerialUSB.write("Input:", 9);
  writeUSB(Input, 5);
  //Serial.println(123);

 int digRead = SPDTread(inSPDT0, inSPDT1);
  if(digRead==1) controllerDirection==DIRECT;
  else if (digRead==2) controllerDirection==REVERSE;
  SeTurnings(kp, ki, kd);
  Serial.println(Output);
  Serial.println(Setpoint);
  Serial.println(Input);
  
  Compute();
  analogWrite(outPID,Output);
  delay(0.01);
  
}

but I find when I set different setpoint ,there is no change in output.

I'm not trying to be an ass, but if you change the PID tuning and the output does not change, your code (or assumption) is wrong.

Have you tried to simulate your basic PID model? Is this 100% original code or do you have a reference for the source before you modified?

Generally, we just tell Ops to go back to their code and intersperse Serial.print(...) statements to watch their variable usage.

Ray

Hi Ray,
Thanks for your help, I have used Serial.print(),but nothing in the Serial monitor. This code comes from Improving the Beginner’s PID – Introduction « Project Blog

I have used Serial.print(),but nothing in the Serial monitor.

Forgive me for assuming, but did you put your watch variable inside the parenthesis?

For example

Serial.print(Setpoint);
Serial.println(" ... Setpoint);

And remember, yoh need to Serial.begin(9600); in setup()

Ray

in additional,when no sensor connect the arduino,what setpoint=5 means?

Setpoint = 5 means that you want the PID to generate an Output that will make Input (the measured value) equal to 5. The PID generates Output. You apply Output to your device and you measure Input to see the current state of the device. For example: Input comes from a temperature sensor that reads in degrees centigrade. Output is a 0 to 255 value that drives an electric heater. Setpoint would be set to the desired temperature. If Input is much less than Setpoint, the PID will generate a high Output. If Input is much greater than Setpoint, the PID will generate a low Output. When Input is near Setpoint the Output will be adjusted constantly to get Input to match Setpoint.

What model of Arduino are you using?

Arduino: 1.6.10 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

sketch_sep21a:12: error: 'DAC1' was not declared in this scope
 const int outPID    = DAC1;
                       ^
sketch_sep21a:13: error: 'DAC0' was not declared in this scope
 const int outOFFSET = DAC0;
                       ^
/Users/john/Documents/Arduino/sketch_sep21a/sketch_sep21a.ino: In function 'void writeUSB(double, int)':
sketch_sep21a:168: error: 'SerialUSB' was not declared in this scope
   SerialUSB.write(str, n);
   ^
/Users/john/Documents/Arduino/sketch_sep21a/sketch_sep21a.ino: In function 'void loop()':
sketch_sep21a:175: error: 'SerialUSB' was not declared in this scope
   SerialUSB.write("+++++++++", 9);
   ^
/Users/john/Documents/Arduino/sketch_sep21a/sketch_sep21a.ino:183:41: warning: statement has no effect [-Wunused-value]
   if (digRead == 1) controllerDirection == DIRECT;
                                         ^
/Users/john/Documents/Arduino/sketch_sep21a/sketch_sep21a.ino:184:46: warning: statement has no effect [-Wunused-value]
   else if (digRead == 2) controllerDirection == REVERSE;
                                              ^
exit status 1
'DAC1' was not declared in this scope

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Hi John,
Thanks for your kind help.
I use Arduino Due. Could you please let me konw when my setpoint=5,how much voltage I set about my setpoint

wdclot1:
Could you please let me konw when my setpoint=5,how much voltage I set about my setpoint

I do not understand the question. I don’t have a DUE on which to try your code. I don’t know what hardware you have connected to your DUE.