Author Topic: C code - implementation of PID in microcontroller  (Read 23837 times)

0 Members and 1 Guest are viewing this topic.

Online IanB

  • Super Contributor
  • ***
  • Posts: 11891
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #25 on: March 29, 2017, 05:34:51 pm »
In case my previous answer seems unhelpful, an internet search on PID control algorithms will turn up a huge number of documents, descriptive articles and tutorials on the subject.

I could write yet another tutorial explanation in this thread, but I would be repeating what others have already done. I would encourage you to read around the topic more widely by yourself.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #26 on: March 29, 2017, 05:56:53 pm »
The concept is that this:
Code: [Select]
while(forever){
 P = error * Pgain * 0.1;
 I = I + (error * Igain) * 0.1;
 D = (error - error[t-1]) * Dgain * 0.1;
 Out = P+I+D;
 wait(0.1);
}

Is similar to:
Code: [Select]
while(forever){
  dT = Tnow - Tlast;
  Tlast = Tnow;
  P = error * Pgain * dT;
  I = I + (error * Igain)  * dT;
  D = (error - error[t-1]) * Dgain  * dT;
  Out = P+I+D;
  wait(random);
}

Meaning the 0.1 in the first example can be merged with the gains. Which you do implicitly when tuning.

However, I have never made a variable time PID controller.
« Last Edit: March 29, 2017, 08:21:14 pm by Jeroen3 »
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11891
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #27 on: March 29, 2017, 06:01:43 pm »
The concept is that this:
Code: [Select]
while(forever){
 P = error * Pgain * 0.1;
 I = I + (error * Igain) * 0.1;
 D = (error - error[t-1]) * Dgain * 0.1;
 Out = P+I+D;
 wait(0.1);
}

Is similar to:
Code: [Select]
while(forever){
  dT = Tnow - Tlast;
  Tlast = Tnow;
  P = error * Pgain * dT;
  I = I + (error * Igain)  * dT;
  D = (error - error[t-1]) * Dgain  * dT;
  Out = P+I+D;
  wait(random);
}

Meaning the 0.1 in the first example can be merged with the gains. Which you do implicitly when tuning.

However, I have never made a variable time PID controller.

But the code quoted above is incorrect and should not be used for reference. (Which perhaps is connected with your last comment.)
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14206
  • Country: de
Re: C code - implementation of PID in microcontroller
« Reply #28 on: March 29, 2017, 07:37:05 pm »
The proportional term is independent from the time step. Only the integral part is proportional to the time step. The differential is inverse proportional to the time step.

Variable time step PID is rare, but it works within bound (especially the slope part can change if time steps get to short). In many cases the sampling time also sets the extra low pass filtering to make the D term practical.

There are a few cases where a fast PID is needed. One sample is probe high regulation in scanning probe microscopes. Even though it is a mechanical system frequency can reach the 100 kHz range.
 
The following users thanked this post: nForce

Offline pelule

  • Frequent Contributor
  • **
  • Posts: 513
  • Country: de
  • What is business? It’s other people’s money
Re: C code - implementation of PID in microcontroller
« Reply #29 on: March 29, 2017, 08:49:21 pm »
Have a look to following pages:
https://en.wikipedia.org/wiki/PID_controller#PID_controller_theory
https://de.mathworks.com/help/control/ref/pid.html?requestedDomain=www.mathworks.com#responsive_offcanvas.

It may help to understand PID and the dependency of sample time for a PID algorithm tranformed out of a continous time system into a discrete time system (using Laplace- and Z-transformation).

In discrete systems you normally run the PID algorithm/function after each measurement (measure time = PID loop time = sample time). To call the PID more often does not make sense, just waste performance.
If you want to run the PID slower (less often) than after each measurement, the easiest method is, just to skip a number (n) of measurements (to be still syncronous with sampling and to keep the PID calculation simple).
If you like to create a flexible system that is a flexible sample time system (or better more or less skipped measurments).
Lets say, you measure a value every 1ms (1 ms measurement time), but you run the PID just every 10ms (you skip 9 times the PID) your PID sample time is = 10ms.
In that case you have to adopt the time correcting factors in dependency of that "PID" sample time.
So easiest way is to define the system based on the shortest/fastest sample time and just use correcting factors if you use run the PID less often (slower).
For example:
You define KP, KI and KD based on Ti = Td = 1 second, and the fastest sample time of 1 ms.
Then the PID adopting factors is easy to calculate:
at a PID loop time of
1ms => 1000 and 1/1000
10ms = 100 and 1/100...
100ms = 10 and 1/10...
/PeLuLe
You will learn something new every single day
 
The following users thanked this post: Jeroen3, nForce

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #30 on: March 30, 2017, 10:56:18 am »
I was following this tutorial: http://coder-tronics.com/pid-tutorial-c-code-example-pt2/

And in this tutorial, there isn't any "dt" in I and D terms. So I got confused. From all this if I understand correctly we need to multiply with dt in integral term, and with 1/dt in derivative term. Because that implies from definition.

Can someone explain why this guy from the tutorial didn't multiply with a fixed time interval then? 
 

Offline Phoenix

  • Frequent Contributor
  • **
  • Posts: 422
  • Country: au
Re: C code - implementation of PID in microcontroller
« Reply #31 on: March 30, 2017, 11:42:49 am »
Can someone explain why this guy from the tutorial didn't multiply with a fixed time interval then?

They are implicity incorporated in the gains Kd and Ki. All three gains also implicitly incorporate the dimensional and scalling conversion from ADC volts to PWM duty cycle.

Implementation can look very different to theory (even if they are actually the same when pulled apart).
 
The following users thanked this post: nForce

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #32 on: March 30, 2017, 05:30:07 pm »
Can someone explain why this guy from the tutorial didn't multiply with a fixed time interval then?

They are implicity incorporated in the gains Kd and Ki. All three gains also implicitly incorporate the dimensional and scalling conversion from ADC volts to PWM duty cycle.

Implementation can look very different to theory (even if they are actually the same when pulled apart).

Oh I get it now, constants Kd and Ki are already multiplied with "dt". And because it's a fixed interval it doesn't change.
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1905
  • Country: ca
Re: C code - implementation of PID in microcontroller
« Reply #33 on: March 30, 2017, 05:56:09 pm »
Quote
When PID loops get fast, there will be specialized hardware available. Or you're exploring new terrain...

Eg: for power factor control, there are power factor correction IC's that use hardware instead of software. Or at least they make it look like hardware.

Several companies including ST and infineon has done 40KHz PID on only a single 0.5USD cortex M0 @ 48MHz and include lot's of other stuff like soft start etc.., also Microchip has done it on their dsPIC's with open source software. Search their PFC app notes for more info
« Last Edit: March 30, 2017, 05:58:12 pm by ali_asadzadeh »
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #34 on: March 30, 2017, 08:20:07 pm »
Well, then I must be doing it wrong. But I only get about 4 Khz max on an 72 Mhz M3 with Q15.16 mathematics.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4037
  • Country: nz
Re: C code - implementation of PID in microcontroller
« Reply #35 on: March 30, 2017, 08:45:45 pm »
Well, then I must be doing it wrong. But I only get about 4 Khz max on an 72 Mhz M3 with Q15.16 mathematics.

For three fixed point multiplies and two adds? Yeah, sounds wrong.  The M3 should always take 1-2 cycles for a 32x32 multiply. Lower Cortex CPUs can be configured with either 1 cycle or 32 multipliers.

A Q15.16 multiply is simply a 32x32->32 multiply followed by a 15 bit right shift. An add is just an add. The whole PID should be under 10 clock cycles.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11891
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #36 on: March 30, 2017, 10:00:55 pm »
For three fixed point multiplies and two adds? Yeah, sounds wrong.  The M3 should always take 1-2 cycles for a 32x32 multiply. Lower Cortex CPUs can be configured with either 1 cycle or 32 multipliers.

A Q15.16 multiply is simply a 32x32->32 multiply followed by a 15 bit right shift. An add is just an add. The whole PID should be under 10 clock cycles.

But there might be some extra time required for practical things like range limiting and input filtering?
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4037
  • Country: nz
Re: C code - implementation of PID in microcontroller
« Reply #37 on: March 30, 2017, 10:55:20 pm »
For three fixed point multiplies and two adds? Yeah, sounds wrong.  The M3 should always take 1-2 cycles for a 32x32 multiply. Lower Cortex CPUs can be configured with either 1 cycle or 32 multipliers.

A Q15.16 multiply is simply a 32x32->32 multiply followed by a 15 bit right shift. An add is just an add. The whole PID should be under 10 clock cycles.

But there might be some extra time required for practical things like range limiting and input filtering?

Sure, but 4 KHz is 18000 clock cycles. There's quite a gap between 10 cycles and 18000 cycles. What is a bit of range limiting and filtering going to turn than 10 cycles into? 20? 100?
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #38 on: March 31, 2017, 07:37:36 am »
Only in textbooks a pid is 3 multiplications.
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14206
  • Country: de
Re: C code - implementation of PID in microcontroller
« Reply #39 on: March 31, 2017, 09:45:46 am »
Extra filtering in PID is used of the ADC or there feedback value is coming in faster than the PID loop itself. Thus very fast PID loops tend to be without extra filtering, or filtering will be more like a first step to work on the data.

Usually there will be extra anti-windup and limiting / scaling of the output values. So a 10 cycle loop would be hard, but something like 20-50 Cycles is reasonable of it needs to be fast. The glitch free implementation to allow real time changes in the parameters might also add a little - not every time, but worst case.

The 18000 cycle long loop code might be due to software floating point and maybe a division to much. This might very well be OK for a slow process, like most thermal systems. Sometimes more readable code is more important than the last bit of speed.
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #40 on: March 31, 2017, 11:19:27 am »
So is my statement correct?:

Quote
Oh I get it now, constants Kd and Ki are already multiplied with "dt". And because it's a fixed interval it doesn't change.

Sorry I don't understand indirect answers. Simple yes or no will do just fine.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #41 on: March 31, 2017, 02:11:12 pm »
The 18000 cycle long loop code might be due to software floating point and maybe a division to much. This might very well be OK for a slow process, like most thermal systems. Sometimes more readable code is more important than the last bit of speed.
That is correct. The PID uses multiple RMS computations as error. And changes behavior depending on frequency.
There are two arbitrary divisions and one sqrt in the code.

However, if you want to regulate a real life system you often have to compute the real life values.
 

Offline Phoenix

  • Frequent Contributor
  • **
  • Posts: 422
  • Country: au
Re: C code - implementation of PID in microcontroller
« Reply #42 on: April 02, 2017, 02:19:31 am »
Can someone explain why this guy from the tutorial didn't multiply with a fixed time interval then?

They are implicity incorporated in the gains Kd and Ki. All three gains also implicitly incorporate the dimensional and scalling conversion from ADC volts to PWM duty cycle.

Implementation can look very different to theory (even if they are actually the same when pulled apart).

Oh I get it now, constants Kd and Ki are already multiplied with "dt". And because it's a fixed interval it doesn't change.

Ki is already multiplied by dt. Kd is already divided by dt. This is for a practical implementation.

In THEORY Kd and Ki do not contain dt, but since they are constants in practice you can lump them together and save computation.
 
The following users thanked this post: nForce

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #43 on: April 06, 2017, 12:44:44 pm »
I have a few other theoretical questions:

- Which is the highest sample frequency at which the system will still work?
- Which is the lowest sample frequency at which the system will still be stable?

These two questions are from electronics and control theory, they are theoretical so I would be happy if someone can also explain how to get the frequencies.

Thank you :)
 

Offline retrolefty

  • Super Contributor
  • ***
  • Posts: 1648
  • Country: us
  • measurement changes behavior
Re: C code - implementation of PID in microcontroller
« Reply #44 on: April 06, 2017, 01:26:07 pm »
I have a few other theoretical questions:

- Which is the highest sample frequency at which the system will still work?
- Which is the lowest sample frequency at which the system will still be stable?

These two questions are from electronics and control theory, they are theoretical so I would be happy if someone can also explain how to get the frequencies.

Thank you :)

 It is all dominated by the process time lag,volume capacity,physical process limits. I saw process control loops that received new PV input data only once a min used in large petrochemical plants.

That is why loop tuning variables (PID constants) can be such a challenge with such a difference in process applications.
 
 
The following users thanked this post: nForce

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #45 on: April 07, 2017, 10:09:07 am »
Thank you retrolefty for your reply. What about in theory?

Is there some sort of algorithm or formula for calculating stability and possibilty of working?
 

Offline retrolefty

  • Super Contributor
  • ***
  • Posts: 1648
  • Country: us
  • measurement changes behavior
Re: C code - implementation of PID in microcontroller
« Reply #46 on: April 07, 2017, 12:27:41 pm »
Thank you retrolefty for your reply. What about in theory?

Is there some sort of algorithm or formula for calculating stability and possibilty of working?

 If one could model the external process I'm sure there could be, it's just above my pay grade.  :-+
 
The following users thanked this post: nForce

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #47 on: April 08, 2017, 10:59:40 am »
If one could model the external process I'm sure there could be, it's just above my pay grade.  :-+

I meant, for this PID algorithm which we discussed in this topic. See my first post of the question.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11891
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #48 on: April 08, 2017, 04:22:18 pm »
What about in theory?

Is there some sort of algorithm or formula for calculating stability and possibility of working?

Yes, it is called control theory. It is a complex subject involving a lot of mathematics and cannot be explained in a short post. It is something you could spend many months learning about in an advanced college course.

An internet search will turn up some introductory material on the subject of PID controllers, design, implementation, tuning and stability. For example:

http://ingscientif.yolasite.com/resources/pid%20control%20book%202nd.pdf
http://act.rasip.fer.hr/materijali/11/pid_Control_15_1_2007.pdf
https://www.cds.caltech.edu/~murray/courses/cds101/fa02/caltech/astrom-ch6.pdf

The simplest answer is that sample period of a discrete control implementation must be "short" relative to the dominant time constants of the process. Making the sample period too short generally doesn't matter. Making it too long will reduce the stability of the controller.
 

Offline f5r5e5d

  • Frequent Contributor
  • **
  • Posts: 349
Re: C code - implementation of PID in microcontroller
« Reply #49 on: April 08, 2017, 05:01:45 pm »
"too high" a sample frequency becomes a problem with needing additional wordlength in your accumulators/calculations to keep the decreasing differences within your quantization/rounding resolution


control loops are characterized by "unity loop gain intercept" frequency == where the feedback, "excess loop gain" is reduced to unity

for stability, the total phase shift at this unity loop gain frequency of process and controller has to be less than 180 degrees

this includes the controlled process' dynamics and the digital controller's required anti-alias filtering, digital sampling, calculation and ADC/DAC delays

typically just workable digital sampled control uses 4-5x higher sampling than the unity loop gain intercept frequency, but requires close analysis

by 10-20x sample rate the digital controller delays typically become small enough to be ignored in the analysis, control algorithm design
« Last Edit: April 08, 2017, 05:05:36 pm by f5r5e5d »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf