/* Reflow Oven Controller * * Copyright (C) 2020 Mario Hüttel * * This file is part of the Reflow Oven Controller Project. * * The reflow oven controller is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * The Reflow Oven Control Firmware is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the reflow oven controller project. * If not, see . */ /** @addtogroup pid-controller * @{ */ #ifndef __PID_CONTROLLER_H__ #define __PID_CONTROLLER_H__ /** * @brief Representation of a PID controller */ struct pid_controller { /** * @brief Derivate term @f$k_d@f$ */ float k_deriv; /** * @brief Integral term @f$k_i@f$ */ float k_int; /** * @brief Proportional term @f$k_p@f$ */ float k_p; /** * @brief Internally precalculated auxiliary value. @f$k_{i_t} = \frac{1}{2}k_{i} \cdot T_s@f$ * * This value is caluclated during the @ref pid_init function to reduce calculations during the continous * PID sampling. */ float k_int_t; /** * @brief Internally precalculated auxiliary value. @f$k_{d_t} = 2\frac{k_{d}}{T_s + 2 k_{d\tau}}@f$ * * This value is caluclated during the @ref pid_init function to reduce calculations during the continous * PID sampling. */ float k_deriv_t; /** * @brief Internally precalculated auxiliary value. @f$\overline{k_{d_t}} = \frac{2 k_{d\tau} - T_s}{ 2k_{d\tau} + T_s}@f$ * * This value is caluclated during the @ref pid_init function to reduce calculations during the continous * PID sampling. */ float k_inv_deriv_t; /** * @brief Saturation of output value * @note This value is set to 100 (corresponding to 100%) for the temperature controller */ float output_sat_max; /** * @brief 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 output_sat_min; /** * @brief Maximum value @f$i_{max}@f$ the inegrator in the PID controller can reach. * * The output of the integral term of the PID controller is limited to @f$\pm i_{max}@f$ * */ float integral_max; /** * @brief Sampling period @f$T_s@f$ of the PID controller in seconds */ float sample_period; /** * @brief Output value of the PID controller */ volatile float control_output; /** * @brief Internal state variable holding the last input value. */ volatile float last_in; /** * @brief integral term's value */ volatile float integral; /** * @brief derivate term's value */ volatile float derivate; }; /** * @brief Initialize a @ref pid_controller struct * @param pid Struct to initilaize * @param k_deriv Derivate term * @param k_int integral term * @param k_p Proportional term * @param output_sat_min Minimum output saturation * @param output_sat_max Maximum output saturation * @param integral_max Maximum integral term * @param kd_tau Time constant of derivate term low pass filter * @param sample_period Sample time in seconds */ 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); /** * @brief Reset a PID controller. * * This sets all internal states to 0. * * @param pid Controller */ void pid_zero(struct pid_controller *pid); /** * @brief 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. * @param pid Pid controller to execute * @param deviation Input deviation * @return Current controller output after the calculated time step */ float pid_sample(struct pid_controller *pid, float deviation); /** * @brief Retrieve the controller's current output * @param pid Pid controller * @return Output */ float pid_get_control_output(const struct pid_controller *pid); /** * @brief Duplicate a PID controller * @param dest destination controller * @param src Source controller * @return 0 if successful */ int pid_copy(struct pid_controller *dest, const struct pid_controller *src); #endif /* __PID_CONTROLLER_H__ */ /** @} */