Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. /*This file has been prepared for Doxygen automatic documentation generation.*/
  2. /*! \file *********************************************************************
  3.  *
  4.  * \brief General PID implementation for AVR.
  5.  *
  6.  * Discrete PID controller implementation. Set up by giving P/I/D terms
  7.  * to Init_PID(), and uses a struct PID_DATA to store internal values.
  8.  *
  9.  * - File:               pid.c
  10.  * - Compiler:           IAR EWAAVR 4.11A
  11.  * - Supported devices:  All AVR devices can be used.
  12.  * - AppNote:            AVR221 - Discrete PID controller
  13.  *
  14.  * \author               Atmel Corporation: http://www.atmel.com \n
  15.  *                       Support email: avr@atmel.com
  16.  *
  17.  * $Name$
  18.  * $Revision: 456 $
  19.  * $RCSfile$
  20.  * $Date: 2006-02-16 12:46:13 +0100 (to, 16 feb 2006) $
  21.  *****************************************************************************/
  22.  
  23. #include "pid.h"
  24. #include <inttypes.h>
  25.  
  26. /*! \brief Initialisation of PID controller parameters.
  27.  *
  28.  *  Initialise the variables used by the PID algorithm.
  29.  *
  30.  *  \param p_factor  Proportional term.
  31.  *  \param i_factor  Integral term.
  32.  *  \param d_factor  Derivate term.
  33.  *  \param pid  Struct with PID status.
  34.  */
  35. void pid_Init(float p_factor, float i_factor, float d_factor, struct PID_DATA *pid)
  36. // Set up PID controller parameters
  37. {
  38.   // Start values for PID controller
  39.   pid->sumError = 0;
  40.   pid->lastProcessValue = 0;
  41.   // Tuning constants for PID loop
  42.   pid->P_Factor = p_factor;
  43.   pid->I_Factor = i_factor;
  44.   pid->D_Factor = d_factor;
  45.   // Limits to avoid overflow
  46.   pid->maxError = MAX_INT / (pid->P_Factor + 1);
  47.   pid->maxSumError = MAX_I_TERM;
  48. }
  49.  
  50.  
  51. /*! \brief PID control algorithm.
  52.  *
  53.  *  Calculates output from setpoint, process value and PID status.
  54.  *
  55.  *  \param setPoint  Desired value.
  56.  *  \param processValue  Measured value.
  57.  *  \param pid_st  PID status struct.
  58.  */
  59. float pid_Controller(float setPoint, float processValue, struct PID_DATA *pid_st, struct PID_DEBUG_DATA *pidDebugData )
  60. {
  61.   float error, p_term, d_term;
  62.   float i_term, ret, temp;
  63.  
  64.   error = setPoint - processValue;
  65.  
  66.   // Calculate Pterm and limit error overflow
  67.   if (error > pid_st->maxError){
  68.     p_term = MAX_INT;
  69.   }
  70.   else if (error < -pid_st->maxError){
  71.     p_term = -MAX_INT;
  72.   }
  73.   else{
  74.     p_term = pid_st->P_Factor * error;
  75.   }
  76.  
  77.   // Calculate Iterm and limit integral runaway
  78.  
  79.   temp = pid_st->sumError + error;
  80.  
  81.   if(temp > pid_st->maxSumError){
  82.     i_term = pid_st->maxSumError*pid_st->I_Factor;
  83.     pid_st->sumError = pid_st->maxSumError;
  84.   }
  85.   else if(temp < -pid_st->maxSumError){
  86.     i_term = -pid_st->maxSumError*pid_st->I_Factor;
  87.     pid_st->sumError = -pid_st->maxSumError;
  88.   }
  89.   else{
  90.     pid_st->sumError = temp;
  91.     i_term = pid_st->I_Factor * pid_st->sumError;
  92.   }
  93.  
  94.   // Calculate Dterm
  95.   d_term = pid_st->D_Factor * (pid_st->lastProcessValue - processValue);
  96.  
  97.   pid_st->lastProcessValue = processValue;
  98.  
  99. pidDebugData->I_term = i_term;
  100. pidDebugData->D_term = d_term;
  101. pidDebugData->P_term = p_term;
  102.  
  103.  
  104.  
  105.   ret = (p_term + i_term + d_term) / SCALING_FACTOR;
  106.  
  107. pidDebugData->Sum = ret;
  108.  
  109.   if(ret > MAX_INT){
  110.     ret = MAX_INT;
  111.   }
  112.   else if(ret < -MAX_INT){
  113.     ret = -MAX_INT;
  114.   }
  115.  
  116.   return(ret);
  117. }
  118.  
  119. /*! \brief Resets the integrator.
  120.  *
  121.  *  Calling this function will reset the integrator in the PID regulator.
  122.  */
  123. void pid_Reset_Integrator(pidData_t *pid_st)
  124. {
  125.   pid_st->sumError = 0;
  126. }
  127.