Hello,
I have been developing a library of function blocks. One of the developed function blocks is the PID controller. I have created a Simulink block based on the S-function written in C language to be able to analyze behavior of my implementation of the PID controller.
Here is my C code which I have inserted into the text field in the Outputs tab in the S-function Builder
Here is the C code which I have inserted into the text field in the Discrete Update tab in the S-function Builder
I have prepared following control loop in Simulink (please see the attached figure). The controller controls FOPDT system with transfer function F(s) = 1/(10*s + 1) and transport delay Tdelay = 4 seconds. Parameters of the
PID controller are set in following manner: Kp = 3, Ti = 8, Td = 2. It is worthwile to say that the control value of the PID controlleris saturated in range <0, 1.5>. I have chosen sampling period T = 1 second in respect to the system time constant tau = 10 seconds (the sampling period is used by the PID algorithm and also by the ZOH blocks). For simulation output (without switching between controller output and manually set control value) please see the attached figure.
The controlled variable oscillates and I don't understand why. The same setting of the controller behaves correctly in analog case with PID controller block from Simulink library. I have tried smaler sampling period values but results are same. Can anybody give me an advicewhat I am doing wrong?
I have been developing a library of function blocks. One of the developed function blocks is the PID controller. I have created a Simulink block based on the S-function written in C language to be able to analyze behavior of my implementation of the PID controller.
Here is my C code which I have inserted into the text field in the Outputs tab in the S-function Builder
Code:
double tmp; // temporary control value
double satU;
double dup; // increment of proportional part
double dui; // increment of integral part
double dud; // increment of derivative part
double du; // increment of control value
dup = Kp[0]*(xD[0] - xD[1]); // dup(k) = Kp*[e(k) - e(k-1)]
dui = (Kp[0]*T[0])/(2*Ti[0])*(xD[0] + xD[1]); // dui(k)=(Kp*T)/(2*Ti)*[e(k) + e(k-1)]
dud = (Kp[0]*Td[0])/T[0]*(xD[0] - 2*xD[1] + xD[2]); // dud(k) = (Kp*Td)/T*[e(k) - 2*e(k-1) + e(k-2)]
du = dup + dui + dud; // du(k)
tmp = xD[3] + du; // u(k) = u(k-1) + du(k)
// antiwind-up
if(tmp > Umax[0]){
satU = Umax[0];
}else if(tmp < Umin[0]){
satU = Umin[0];
}else{
satU = tmp;
}
y0[0] = satU;
Code:
xD[0] = u0[0] - u1[0]; // e(k) = sp - cv
xD[2] = xD[1]; // e(k-2) = e(k-1)
xD[1] = xD[0]; // e(k-1) = e(k)
xD[3] = u2[0]; // bumpless transition: u(k-1) = tr
PID controller are set in following manner: Kp = 3, Ti = 8, Td = 2. It is worthwile to say that the control value of the PID controlleris saturated in range <0, 1.5>. I have chosen sampling period T = 1 second in respect to the system time constant tau = 10 seconds (the sampling period is used by the PID algorithm and also by the ZOH blocks). For simulation output (without switching between controller output and manually set control value) please see the attached figure.
The controlled variable oscillates and I don't understand why. The same setting of the controller behaves correctly in analog case with PID controller block from Simulink library. I have tried smaler sampling period values but results are same. Can anybody give me an advicewhat I am doing wrong?
Last edited: