0

I've been trying to simulate a PID using Brett Beauregard's PID library in order to understand it better. Here is my code.

#include <PID_v1.h>
const unsigned int numReadings = 500;
double analogVals[numReadings];
unsigned int i = 0;
int angle = 0;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
void setup()
{
 //turn the PID on
 myPID.SetMode(AUTOMATIC);
 Serial.begin(115200);
 Setpoint = 300;
 myPID.SetOutputLimits(-2,2);
 myPID.SetSampleTime(100);
 Input = random(292, 302) ;
}
void loop()
{
 if (i % 2 == 0) {
 Input += random(-2,3);
 }
 angle += 1 % 360;
 Input += sin(angle*355/(113*180));
 myPID.Compute();
 Input += Output;
 analogVals[i] = Input;
 i++;
 if (i>= numReadings)
 {
 for (int j = 0; j < i; j++) {
 Serial.println(analogVals[j]);
 } 
 i = 0; //reset to beginning of array, so you don't try to save readings outside of the bounds of the array
 }
}

Even if I restrict the output of the PID to a very small value, I get huge nonsense results of this code. It oscillates like -1000 to 1000. I've read this https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops and tried to adjust my parameters, but they're just shots in the dark really, I can't even damp these massive oscillations. How would I tune a PID to cancel out a sin error ?

Thanks in advance

Edgar Bonet
45.1k4 gold badges42 silver badges81 bronze badges
asked Mar 31, 2019 at 23:33
1
  • please post the link to the PID library? Commented Apr 1, 2019 at 3:31

1 Answer 1

1

I do not have your PID_v1.h, but I made a simple experiment trying to control your example with a simple P-Controller instead of the PID lib. I made the following changes to your code:

...
double K_P = 1;
... 
//myPID.Compute();
 Output = K_P*(Setpoint - Input);
 Input += Output;

This is working for very small amounts of K_P, but as soon as K_P gets higher than 2.0 it gets instable very fast. I guess this is what you are observing. The reason for me is, that you have implemented a ideal control path. In real control tasks you will always have some transfer behavior

Therefore I added a simple PT1 element (first-order lag element) to your code, now your system is much more stable and you can experiment with the K, I and D factors. Here it works with K_P even higher than 400:

// #include <PID_v1.h>
const unsigned int numReadings = 500;
double analogVals[numReadings];
unsigned int i = 0;
int angle = 0;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
double Input_PT1;
double K_P = 20;
//Specify the links and initial tuning parameters
//PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
void setup()
{
 //turn the PID on
 // myPID.SetMode(AUTOMATIC);
 Serial.begin(115200);
 Setpoint = 300;
 // myPID.SetOutputLimits(-2,2);
 //myPID.SetSampleTime(100);
 Input = random(292, 302) ;
}
void loop()
{
 if (i % 2 == 0) {
 Input += random(-2, 3);
 }
 angle += 1 % 360;
 Input += sin(angle * 355 / (113 * 180));
 //myPID.Compute();
 Output = K_P * (Setpoint - Input_PT1);
 Input += Output;
 // start PT1
 Input_PT1 -= Input_PT1 / 25;
 Input_PT1 += Input / 25;
 // end PT1
 analogVals[i] = Input_PT1;
 i++;
 if (i >= numReadings)
 {
 for (int j = 0; j < i; j++) {
 Serial.println(analogVals[j]);
 }
 i = 0; //reset to beginning of array, so you don't try to save readings outside of the bounds of the array
 }
}

Some hint:

  • The sketch above does not initialize Input_PT1, so it takes some secondes until you reach a steady value of 300, if you do not want to wait, just initialize Input_PT1 with 300. But this is exactly where you can start increasing first I, then D factors to try to increase speed for reaching a steady value of 300 and experiencing what influence I and D part will have.
  • Input_PT1 is not a good naming, since this is the output of the PT1 element, but since you are using it as the PID Input, I did not change.

Here a drawing of what I implemented in contrast to your sketch (at least I hope so ;-))

enter image description here

answered Apr 1, 2019 at 19:02

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.