PID Controller¶
The PID controller is the main element of the oven. It controls the output of the solid state relais in order to achieve the desired temperature.
The PID controller is implemented in the pid-controller.c
file. See the PID Controller Code API for details.
Functional Description¶
The following figure shows the PID controller’s structure.
The controller is composed of 3 paths. The proportional, the derivate, and the integrator path. Compared to a textbook PID controller, this version contains a few additional features.
The integrator has a configurable maximum limit of pid_controller.integral_max
. Once this value is reached (plus or minus), the integrator freezes.
The integrator is also frozen in case the output value is in saturation. This serves as an anti-windup protection.
The output value saturates at configurable high and low limits (pid_controller.output_sat_max
and pid_controller.output_sat_min
). The controller instance used for the
reflow oven’s solid state relais output is saturated by software to a limit of 0 to 100.
In addition to the above features, the derivate term contains an additional first order low pass filter in order to prevent coupling of high frequency noise amplified by the derivate term. The low pass filter is charcterized by its time constant \(k_{d\tau}\).
Time Continuous Transfer Function¶
The time continous transfer function of the PID controller is
Time Discrete Transfer Function¶
The time descrete transfer function which is implemented in the code is derived by converting the time continuous transfer function with the bilinear transformation:
The frequency warping of the bilinear transform can be considered negligible because the PID controller is targetted for low frequency temperature signal data with a maximum far below the nyquist freqency. In this area, the mapping of the continuous frequencies to the time descrete can be considered linear.
The time discrete transfer function after inserting the bilinear transform is:
Converted to an implementable form:
This function can be splitted in the three individual parts of the PID controller:
The individual time domain difference equations \(y_i[n] = \mathcal{Z}^{-1}\left\lbrace H_{di} * X(z)\right\rbrace\) that are implemented in software are:
The final output value is the sum of all three terms:
PID Controller Code API¶
-
group
pid-controller
Functions
-
void
pid_init
(struct pid_controller *pid, float k_deriv, float k_int, float k_p, float output_sat_min, float output_sat_max, float integral_max, float kd_tau, float sample_period)¶ Initialize a pid_controller struct.
- Parameters
pid
: Struct to initilaizek_deriv
: Derivate termk_int
: integral termk_p
: Proportional termoutput_sat_min
: Minimum output saturationoutput_sat_max
: Maximum output saturationintegral_max
: Maximum integral termkd_tau
: Time constant of derivate term low pass filtersample_period
: Sample time in seconds
-
void
pid_zero
(struct pid_controller *pid)¶ Reset a PID controller.
This sets all internal states to 0.
- Parameters
pid
: Controller
-
float
pid_sample
(struct pid_controller *pid, float deviation)¶ Execute a tiome step of the PID controller. This function must be periodically called in an pid_controller::sample_period interval.
- Note
This function does not check its calling interval. It must be ensured by the caller.
- Return
Current controller output after the calculated time step
- Parameters
pid
: Pid controller to executedeviation
: Input deviation
-
float
pid_get_control_output
(const struct pid_controller *pid)¶ Retrieve the controller’s current output.
- Return
Output
- Parameters
pid
: Pid controller
-
int
pid_copy
(struct pid_controller *dest, const struct pid_controller *src)¶ Duplicate a PID controller.
- Return
0 if successful
- Parameters
dest
: destination controllersrc
: Source controller
-
void
calculate_integral
(struct pid_controller *pid, float deviation)¶
-
struct
pid_controller
¶ - #include <pid-controller.h>
Representation of a PID controller.
Public Members
-
float
k_deriv
¶ Derivate term \(k_d\).
-
float
k_int
¶ Integral term \(k_i\).
-
float
k_p
¶ Proportional term \(k_p\).
-
float
k_int_t
¶ Internally precalculated auxiliary value. \(k_{i_t} = \frac{1}{2}k_{i} \cdot T_s\).
This value is caluclated during the pid_init function to reduce calculations during the continous PID sampling.
-
float
k_deriv_t
¶ Internally precalculated auxiliary value. \(k_{d_t} = 2\frac{k_{d}}{T_s + 2 k_{d\tau}}\).
This value is caluclated during the pid_init function to reduce calculations during the continous PID sampling.
-
float
k_inv_deriv_t
¶ Internally precalculated auxiliary value. \(\overline{k_{d_t}} = \frac{2 k_{d\tau} - T_s}{ 2k_{d\tau} + T_s}\).
This value is caluclated during the pid_init function to reduce calculations during the continous PID sampling.
-
float
output_sat_max
¶ Saturation of output value.
- Note
This value is set to 100 (corresponding to 100%) for the temperature controller
-
float
output_sat_min
¶ Minumum saturation of PID output value.
- Note
This value is set to 0 for the temperature controller as the oven driver is not able to cool
-
float
integral_max
¶ Maximum value \(i_{max}\) the inegrator in the PID controller can reach.
The output of the integral term of the PID controller is limited to \(\pm i_{max}\)
-
float
sample_period
¶ Sampling period \(T_s\) of the PID controller in seconds.
-
float
control_output
¶ Output value of the PID controller.
-
float
last_in
¶ Internal state variable holding the last input value.
-
float
integral
¶ integral term’s value
-
float
derivate
¶ derivate term’s value
-
float
-
void