.. _pid_controller:

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 :ref:`pid_code_api` for details.

Functional Description
----------------------

The following figure shows the PID controller's structure.

.. drawio-image:: pid.drawio

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 :c:var:`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 (:c:var:`pid_controller.output_sat_max` and :c:var:`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 :math:`k_{d\tau}`.

Time Continuous Transfer Function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The time continous transfer function of the PID controller is

.. math:: H_c(s) = \frac{Y_c(s)}{X_c(s)} = k_p + \frac{k_i}{s} + \frac{k_ds}{1+sk_{d\tau}} 


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:

.. math:: s = \frac{2}{T_s}\cdot \frac{z-1}{z+1}

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:

.. math:: H_d(z) = H_c(s)\bigg|_{s=\frac{2}{T_s}\cdot \frac{z-1}{z+1}} = k_p + \frac{k_i T_s (z+1)}{2(z-1)} + \frac{\frac{2}{T_s}k_d(z-1)}{\left(1+\frac{2k_{d\tau}}{T_s}\right)z+\left(1-\frac{2k_{d\tau}}{T_s}\right)}.

Converted to an implementable form:

.. math:: H_d(z) = k_p + \frac{k_iT_s(1+ z^{-1})}{2(1-z^{-1})} + \frac{\frac{2}{T_s}k_d(1-z^{-1})}{(1+2k_{d\tau}T_s^{-1})+(1-2k_{d\tau}T_s^{-1})z^{-1}}

This function can be splitted in the three individual parts of the PID controller:

.. math:: H_{d1}(z) = k_p
.. math:: H_{d2}(z) = \frac{k_iT_s(1+ z^{-1})}{2(1-z^{-1})}
.. math:: H_{d3}(z) = \frac{\frac{2}{T_s}k_d(1-z^{-1})}{(1+2k_{d\tau}T_s^{-1})+(1-2k_{d\tau}T_s^{-1})z^{-1}}

The individual time domain difference equations :math:`y_i[n] = \mathcal{Z}^{-1}\left\lbrace H_{di} * X(z)\right\rbrace` that are implemented in software are:

.. math:: y_1[n] = k_p x[n]
.. math:: y_2[n] = \underbrace{\frac{k_iT_s}{2}}_{k_{i_t}} \left( x[n] + x[n-1]\right) + y_2[n-1]
.. math:: y_3[n] = \underbrace{\frac{2k_{d}}{2k_{d\tau} + T_s}}_{k_{d_t}}\left( x[n] - x[n-1] \right) + \underbrace{\frac{2k_{d\tau} - T_s}{2k_{d\tau} + T_s}}_{\overline{k_{d_t}}} y_3[n-1]

The final output value is the sum of all three terms:

.. math:: y[n] = \sum_{i=1}^{3} y_i[n]

.. _pid_code_api:

PID Controller Code API
-----------------------

.. doxygengroup:: pid-controller
   :project: Reflow Controller Firmware