• AVR Freaks

Hot!Practical PID example for dsPIC33EP256MC502

Author
TS9
Super Member
  • Total Posts : 908
  • Reward points : 0
  • Joined: 2010/05/07 10:52:22
  • Status: offline
2020/05/30 11:01:23 (permalink)
0

Practical PID example for dsPIC33EP256MC502

Hi, 

I have seen example of PID (CE019_PID) on microchip.com .

Some description of PID I have also read from this. https://microchipdevelope...ic-dscs-implementation

From the "DSP_Control_Functions_Help.htmA PID controller responds to an error signal in a closed control loop and attempts to adjust the controlled quantity in order to achieve the desired system response. The controlled parameter can be any measurable system quantity, such as speed, voltage or current. The output of the PID controller can control one or more system parameters that will affect the controlled system quantity. For example, a speed control loop in a Sensorless Brushless DC motor application can control the PWM duty cycle directly or it can set the current demand for an inner control loop that regulates the motor currents. The benefit of the PID controller is that it can be adjusted empirically by adjusting one or more gain values and observing the change in system response." Same way I have to Update duty cycle with in 100us to  regulates the  IGBTs current. 

#define NumberOfSamples 10 
void Timer0_100us_Interrupt_ISR()
{
    ADC_CT_Reading += ReadADCValue ;
AvgCount++ ;
  if(AvgCount == NumberOfSamples )
    {
     ADCAvg =
ADC_CT_Reading/NumberOfSamples

    }
    else
    {
      Error = ADCAvg - SetReadingCurrent ;
      // Error when error is Positive
      if(Error > 10 && Error < 20)
      {
       // Change PWM Duty Cycle accordingly
      }
      else if(Error > 20 && Error < 30)
      {
       // Change PWM Duty Cycle accordingly
      }
      else if(Error > 50 && Error < 100)
      {
       // Change PWM Duty Cycle accordingly
      }
      else
      {
        // Change PWM Duty Cycle accordingly
      }
      // Same way when error is negative.    if(Error > -10 && Error < -20)
      {
       // Change PWM Duty Cycle accordingly
      }
      else if(Error > -20 && Error < -30)
      {
       // Change PWM Duty Cycle accordingly
      }
      else if(Error > -50 && Error < -100)
      {
       // Change PWM Duty Cycle accordingly
      }
      else
      {
        // Change PWM Duty Cycle accordingly
      }
      AvgCount = 0;
    }
    Timer0_100us_Flag = 0 // Clear Flag for Next round .
}
   Is It good idea to replace above logic with PID Algorithm  as below ?
</p>
<p>//CE019_PID</p>
<p>#include <dsp.h></p>
<p>/*
Variable Declaration required for each PID controller in your application
*/
/* Declare a PID Data Structure named, fooPID */
tPID fooPID;
/* The fooPID data structure contains a pointer to derived coefficients in X-space and */
/* pointer to controler state (history) samples in Y-space. So declare variables for the */
/* derived coefficients and the controller history samples */
fractional abcCoefficient[3] __attribute__ ((section (".xbss, bss, xmemory")));
fractional controlHistory[3] __attribute__ ((section (".ybss, bss, ymemory")));
/* The abcCoefficients referenced by the fooPID data structure */
/* are derived from the gain coefficients, Kp, Ki and Kd */
/* So, declare Kp, Ki and Kd in an array */
fractional kCoeffs[] = {0,0,0};</p>
<p>/*
Main function demonstrating the use of PID(), PIDInit() and PIDCoeffCalc()
functions from DSP library in MPLAB C30 v3.00 and higher
*/
int main (void)
{
/*
Step 1: Initialize the PID data structure, fooPID
*/
fooPID.abcCoefficients = &abcCoefficient[0]; /*Set up pointer to derived coefficients */
fooPID.controlHistory = &controlHistory[0]; /*Set up pointer to controller history samples */
PIDInit(&fooPID); /*Clear the controler history and the controller output */
kCoeffs[0] = Q15(0.7);
kCoeffs[1] = Q15(0.2);
kCoeffs[2] = Q15(0.07);
PIDCoeffCalc(&kCoeffs[0], &fooPID); /*Derive the a,b, & c coefficients from the Kp, Ki & Kd */</p>
<p>/*
Step 2: Use the PID Controller
*/
fooPID.controlReference = Q15(0.74) ; /*Set the Reference Input for your controller */
fooPID.measuredOutput = Q15(0.453) ; /*Typically the measuredOutput variable is a plant response*/
/*measured from an A/D input or a sensor. */
/*In this example we manually set it to some value for */
/*demonstration but the user should note that this value will */
/*keep changing in a real application*/
while (1) /*We use a while(1) loop here for demonstration purposes.*/
{ /*Typically, the PID calculation may be triggered off a timer*/
/*or A/D interrupt */</p>
<p>PID(&fooPID); /*Call the PID controller using the new measured input */
/*The user may place a breakpoint on "PID(&fooPID)", halt the debugger,*/
/*tweak the measuredOutput variable within the watch window */
/*and then run the debugger again */
 


If yes , How PID (&fooPID) update PWM Duty Cycle in mine with  Reference Input and Reference Input in case?From where Q15 floats values comes from :kCoeffs[0] = Q15(0.7);
kCoeffs[1] = Q15(0.2);
kCoeffs[2] = Q15(0.07);fooPID.controlReference = Q15(0.74) ; /*Set the Reference Input for your controller */
fooPID.measuredOutput = Q15(0.453) ; /*Typically the measured Output variable is a plant response*/  


--TS9
post edited by TS9 - 2020/05/30 21:46:12
#1

1 Reply Related Threads

    T Yorky
    Super (Thick) Member
    • Total Posts : 563
    • Reward points : 0
    • Joined: 2012/08/28 02:07:35
    • Location: UK
    • Status: offline
    Re: Practical PID example for dsPIC33EP256MC502 2020/06/01 08:16:51 (permalink)
    0
    Sorry to be negative TS9, but this is a real 'how long is a piece of string' question.
    Often I have experienced 'the suck and see' PID tuning in industry.
    The results of this method is normally one of two 'achievements'.
    1. Minimise oscillation frequency.
    2. Minimise oscillation magnitude.
    What is often misunderstood is that the PID has to be related to the control. That is it needs to be scaled. Both in magnitude and time (look up time scaling).
    You will be implementing an integer PID controller. Unlike floating point. You have a finite range. You will have to have good knowledge of your dynamics to position this range where you can 'suck and see' the settings.
    As an example, many years ago working on a treatment plant and old PLC with integer calcs. Some control loops required the PID to be scanned every 5 seconds! This is so the scale was correct for integer calcs. Without doing tests and understanding the parameter scaling, you could try every value for the PID gains scanning at 1 second/500msec/100msec and still only affect the oscillation freq/magnitude.
    And also Q numbers are just yet another scaling and do not produce magic results. They are not floats.
    You will need to be specific about your requirements.
    T Yorky
     
    #2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5