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

0 Members and 1 Guest are viewing this topic.

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
C code - implementation of PID in microcontroller
« on: March 23, 2017, 08:35:29 pm »
Hello,

I have written a PID regulator in C, for some microcontroller. The call_interrupt function is a periodic function which is called periodically with switch frequency of 20000 Hz. The PID has to be written in a such a way, so that if we change the sample frequency (SAMPLE_FREQ) with the prescale value, there is no need to change the parameters of PID (Kp, Ki, Kd). How can I achieve that?

Code: [Select]

#define     SWITCH_FREQ     20000
#define     SAMP_PRESCALE   1
#define     SAMPLE_FREQ     (SWITCH_FREQ/SAMP_PRESCALE)

float Kp = 1.0;
float Ki = 1.0;
float Kd = 1.0;

float error_sum = 1.0;
float temp = 0.0;
float error = 0.0;

void call_interrupt(void){
        // some code

        error = reference_value - voltage;
        error_sum += error;

        PID = (Kp * error) + (Ki * error_sum) + (Kd * (error - temp));
        temp = error;

        //some code
}
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14080
  • Country: de
Re: C code - implementation of PID in microcontroller
« Reply #1 on: March 23, 2017, 08:51:37 pm »
One way to implement a PID that allows for a variable call rate, is to do the integral part by including the scaling factor KI already there. So instead of
error_sum += error
use
integral_part += Ki * error * dt

As a side effect this also allows changing Ki on the fly without adding glitches.
 
The following users thanked this post: nForce

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4068
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #2 on: March 24, 2017, 08:19:46 am »
You'll need some other things as well.
Such as:
- Stop the I accumulator when the ouput is clamped.
- Saturating calculations. (although with float chances are small)

Also PID with floats 20 KHz will need some fast microcontroller. What's the core speed?
I think you might be better of using fixed point math.
 
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 #3 on: March 24, 2017, 10:34:33 am »
The core speed of microcontroller is 90 Mhz.

Code: [Select]
integral_part += Ki * error * dt
What do you mean here by dt? dt is the differential of time, so it should be 1/frequency?

Quote
Stop the I accumulator when the ouput is clamped.
Like so (sort of):

Code: [Select]
if (PID > 1.0){
      integral_sum = 1
}
if (PID < 0){
      integral_sum = 0
}
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4002
  • Country: nz
Re: C code - implementation of PID in microcontroller
« Reply #4 on: March 24, 2017, 11:11:18 am »
You'll need some other things as well.
Such as:
- Stop the I accumulator when the ouput is clamped.
- Saturating calculations. (although with float chances are small)

Also PID with floats 20 KHz will need some fast microcontroller. What's the core speed?
I think you might be better of using fixed point math.

16 MHz AVR takes about 8 - 10 us per soft float multiply or add. So 20 KHz with six or sven operations in the loop is not *quite* possible -- 10 KHz could be doable.

You'd hope a 90 MHz would be OK though ... even with software FP.
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1896
  • Country: ca
Re: C code - implementation of PID in microcontroller
« Reply #5 on: March 24, 2017, 11:15:00 am »
Quote
Like so (sort of):

Code: [Select]
if (PID > 1.0){
      integral_sum = 1
}
if (PID < 0){
      integral_sum = 0
}
Yes :)
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 
The following users thanked this post: nForce

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4068
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #6 on: March 24, 2017, 11:47:50 am »
16 MHz AVR takes about 8 - 10 us per soft float multiply or add. So 20 KHz with six or sven operations in the loop is not *quite* possible -- 10 KHz could be doable.

You'd hope a 90 MHz would be OK though ... even with software FP.
If the PID is the only thing the chips doing, yes. But the chip is not. It will need to perform data aqcuisition and filtering.
And the % of cpu that takes is depending on the samplerate.

10 Khz is a more realistic maximum. Assuming you want to keep the load low enough to not miss deadlines.

I don't know that the ouput of the PID is connected to. But it is pointless in running the PID faster than you can change the output. (eg: with 100 hz pwm)
« Last Edit: March 24, 2017, 12:41:24 pm by Jeroen3 »
 

Offline danadak

  • Super Contributor
  • ***
  • Posts: 1875
  • Country: us
  • Reactor Operator SSN-583, Retired EE
Re: C code - implementation of PID in microcontroller
« Reply #7 on: March 24, 2017, 12:11:17 pm »
PID control including most of the analog stuff you will need can be found on
PSOC -


http://www.cypress.com/documentation/application-notes/an66627-psoc-3-and-psoc-5lp-intelligent-fan-controller


http://www.cypress.com/documentation/application-notes/an89346-psoc-4-intelligent-fan-controller


http://www.cypress.com/documentation/application-notes/an2208-psoc-1-temperature-pid-using-thermoregulator     For ref, if you
use this example port in to PSOC 3, 4, 5LP CPU.

PSOC has -



1) Routability
2) Fast 12 bit SAR A/D and slow 20 bit DelSig
3) DFB (Digital Filter Block) that is dual channel, handle FIR or IIR filters, or DFB
can be used as a GP fast processor block, similar to RISC block
4) MSI logic elements GUI based and/or the UDB Verilog capability. Eg. the FPGA
like capability
5) Onboard Vref
6) IDAC, VDAC, OpAmps (up to 4), comparator, mixer, switch cap, analog mux....
7) LCD,  COM, UART, I2C, I2S, One Wire, SPI, Parallel, LIN, CAN, BLE, USB
9) Custom components capability, create with schematic capture or Verilog
10) DMA to offload processes like filters, COM, Display
11) ARM M0 (PSOC 4) or M3 (PSOC  5LP) or 8051 core(PSOC 3)
12) Extensive clock generation capabilities
13) All components supported by extensive prewritten APIs

https://www.element14.com/community/thread/23736/l/100-projects-in-100-days?displayFullThread=true

http://www.cypress.com/documentation/code-examples/psoc-345-code-examples

Great video library

Attached component list.  A component is an on chip HW resource.

Free GUI design tool with schematic capture, "Creator". Components have rich API library attached
to each component. Compilers free as well.

PSOC 4 is low end of family, consider 5LP parts as well. PSOC 4 also has arduino footprint boards (pioneer) as well

https://www.elektormagazine.com/labs/robot-build-with-cypress-psoc

http://www.cypress.com/products/32-bit-arm-cortex-m-psoc



Regards, Dana.
« Last Edit: March 24, 2017, 12:14:25 pm by danadak »
Love Cypress PSOC, ATTiny, Bit Slice, OpAmps, Oscilloscopes, and Analog Gurus like Pease, Miller, Widlar, Dobkin, obsessed with being an engineer
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4002
  • Country: nz
Re: C code - implementation of PID in microcontroller
« Reply #8 on: March 24, 2017, 01:46:20 pm »
16 MHz AVR takes about 8 - 10 us per soft float multiply or add. So 20 KHz with six or sven operations in the loop is not *quite* possible -- 10 KHz could be doable.

You'd hope a 90 MHz would be OK though ... even with software FP.
If the PID is the only thing the chips doing, yes. But the chip is not. It will need to perform data aqcuisition and filtering.
And the % of cpu that takes is depending on the samplerate.

10 Khz is a more realistic maximum. Assuming you want to keep the load low enough to not miss deadlines.

I don't know that the ouput of the PID is connected to. But it is pointless in running the PID faster than you can change the output. (eg: with 100 hz pwm)

Of course.

I don't know what you'd be doing that you'd need to run a PID that fast. Nothing mechanical. Self-balancing, steering cars or planes, traction control ... all are fine with orders of magnitude slower control rates than that.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4068
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #9 on: March 24, 2017, 02:38:56 pm »
I can think of very fast pick&placers that might need fast PID loops. Or software controlled loadbanks.
 

Offline retrolefty

  • Super Contributor
  • ***
  • Posts: 1648
  • Country: us
  • measurement changes behavior
Re: C code - implementation of PID in microcontroller
« Reply #10 on: March 24, 2017, 02:53:16 pm »
16 MHz AVR takes about 8 - 10 us per soft float multiply or add. So 20 KHz with six or sven operations in the loop is not *quite* possible -- 10 KHz could be doable.

You'd hope a 90 MHz would be OK though ... even with software FP.
If the PID is the only thing the chips doing, yes. But the chip is not. It will need to perform data aqcuisition and filtering.
And the % of cpu that takes is depending on the samplerate.

10 Khz is a more realistic maximum. Assuming you want to keep the load low enough to not miss deadlines.

I don't know that the ouput of the PID is connected to. But it is pointless in running the PID faster than you can change the output. (eg: with 100 hz pwm)

Of course.

I don't know what you'd be doing that you'd need to run a PID that fast. Nothing mechanical. Self-balancing, steering cars or planes, traction control ... all are fine with orders of magnitude slower control rates than that.

 :-+

 And that is to say nothing about the speed of the process to be controled. Mechanical inertia, thermal mass, etc usually establishes the upper limit as far as sample speed requirement. At large refinery plants under a cental control system with hundreds of PID control loops, a sample speed of 1 sec was usually more then fast enough.

 Also hard coding of PID tuning values is an especially bad idea. Too many external variations to not
have user access to adjusting them under actual process conditions.

 

Offline sagnikbasu

  • Contributor
  • Posts: 19
  • Country: in
Re: C code - implementation of PID in microcontroller
« Reply #11 on: March 24, 2017, 03:12:05 pm »
I think you will need some kind of adaptive PID algorithms like twiddle or Ziggler Nichols method.Search for them in Google.
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #12 on: March 26, 2017, 05:23:15 pm »
I am still waiting for Kleinstein answer:


Code: [Select]
integral_part += Ki * error * dt
What do you mean here by dt? dt is the differential of time, so it should be 1/frequency?

Many thanks!
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4068
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #13 on: March 26, 2017, 08:04:26 pm »
Only I and D are have a time factor. Usually time factor is fixed in the execution interval.
However, if you want to change this runtime you need to factor in this time change to keep the I and D gains identical.

Normal, time factor in calculation interval:
integral_part += Ki * error

Time compensated:
integral_part += Ki * error * dt
Where dT is the time elapsed since the last calculation.

Eg: if a short time has elapsed dT will be small, but if a long time has passed dT will be long. The system was allowed to drift further away in a long time, and thus requires more control.
This should make the PID capable of variable speeds. However, it's easier to keep the speed fixed unless your application is special.
 
The following users thanked this post: nForce

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #14 on: March 26, 2017, 08:19:41 pm »
I am still waiting for Kleinstein answer:


Code: [Select]
integral_part += Ki * error * dt
What do you mean here by dt? dt is the differential of time, so it should be 1/frequency?

Many thanks!

Remember how a PID control algorithm is defined.

    Action = Proportional + Integral + Derivative

Where:

    Proportional action = Kp * error

Therefore if the error is normalized to percent and the output action is scaled to percent, then Kp is dimensionless. (Normalizing input and output to a fraction of the range is normal when implementing PID controllers.)

    Integral action = Kp * Ki * (time integral of error)

Therefore since the time integral of the error has units of (percent * time) then Ki must have units of (1/time). Ki is not dimensionless!

This means you must include the units of Ki when you input it (e.g. Ki = 0.2 repeats per second) and you must include time in your control implementation.

Lastly,

    Derivative action = Kp * Kd * (time derivative of error)

Therefore since the time derivative of the error has units of (percent / time) then Ki must have units of time. Kd is not dimensionless either. You must include the units of measure of Kd when you input it, e.g. 20 seconds.
« Last Edit: March 26, 2017, 08:22:58 pm by IanB »
 
The following users thanked this post: nForce

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1896
  • Country: ca
Re: C code - implementation of PID in microcontroller
« Reply #15 on: March 27, 2017, 08:14:41 am »
why so many of you think that we only need slow PID, PFC control is a simple app that needs PID loop of at least 40Kz there are several many others too.
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4068
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: C code - implementation of PID in microcontroller
« Reply #16 on: March 27, 2017, 09:09:22 am »
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.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4002
  • Country: nz
Re: C code - implementation of PID in microcontroller
« Reply #17 on: March 27, 2017, 09:59:45 am »
why so many of you think that we only need slow PID, PFC control is a simple app that needs PID loop of at least 40Kz there are several many others too.

No one says things requiring fast PID don't exist. And it's easy enough to make it as fast as you want, sofeware-wise at least, with a cheap microcontroller. Just perhaps not the very cheapest unless you do some very careful fixed-point arithmetic. Floating point makes it much easier to not fail catastrophically, but requires either a lot of clock cycles or hardware FP or at least a fast full-precision integer multiplier (and careful fixed-point programming, preferably including clamping)

I'm guessing here, but I suspect Power Factor Control is best done by someone who has studied control system theory formally, including complex [number] analysis, eigenvalues and the like. They'll be the people answering the questions about PIDs on public forums, not asking about them.
 

Offline snarkysparky

  • Frequent Contributor
  • **
  • Posts: 414
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #18 on: March 27, 2017, 11:45:28 am »
I found an arm cortex m0+ does fixed point math with 64 signed integer quite fast as long as you can make your divisions by a power of two only.
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #19 on: March 27, 2017, 01:25:51 pm »
Sorry IanB, but I don't understand why do we here:

Quote
Integral action = Kp * Ki * (time integral of error)

include the proportinal (Kp) parameter for calculating the integral term?

From theory of PID regulators it's only Integral action = Ki * time integral of error.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #20 on: March 27, 2017, 01:46:48 pm »
Sorry IanB, but I don't understand why do we here:

Quote
Integral action = Kp * Ki * (time integral of error)

include the proportinal (Kp) parameter for calculating the integral term?

From theory of PID regulators it's only Integral action = Ki * time integral of error.

See, for example, these references:

http://blog.opticontrols.com/archives/124
http://www.expertune.com/artCE87.aspx

Look at the variety of PID algorithms, but see particularly the "ideal" or "standard" form. In the ideal form of the PID control algorithm the gain applies to the integral and derivative terms as well as the error. Experience has shown that this form is more useful in practice than the pure "parallel" form often seen in textbooks.
 
The following users thanked this post: nForce

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4002
  • Country: nz
Re: C code - implementation of PID in microcontroller
« Reply #21 on: March 27, 2017, 02:05:26 pm »
I found an arm cortex m0+ does fixed point math with 64 signed integer quite fast as long as you can make your divisions by a power of two only.

If you're always dividing by the same thing (or at least by the same thing dozens or hundreds of times) then you can do a 32 bit divide with a 32x32 multiply and a shift, so that's pretty quick.

Even on ancient ARM7TDMI, the 32x32 -> 64 multiply took 2-5 I cycles plus 1 S cycle. Plus 1 extra I cycle if you wanted to add the result to what was already in the destination pair. For the divide trick it'll always be the full 6 cycles.

10 - 15 years ago ARM7TDMI were running at 1 - 10 MHz, but these days ST has them at 66 MHz, Atmel at 75 MHz, and I saw a reference to Fujitsu at 100 MHz.

Of course anything Cortex is far superior, not least because Thumb2 not ARM+Thumb1.
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #22 on: March 28, 2017, 09:21:09 am »
Sorry IanB, but I don't understand why do we here:

Quote
Integral action = Kp * Ki * (time integral of error)

include the proportinal (Kp) parameter for calculating the integral term?

From theory of PID regulators it's only Integral action = Ki * time integral of error.

See, for example, these references:

http://blog.opticontrols.com/archives/124
http://www.expertune.com/artCE87.aspx

Look at the variety of PID algorithms, but see particularly the "ideal" or "standard" form. In the ideal form of the PID control algorithm the gain applies to the integral and derivative terms as well as the error. Experience has shown that this form is more useful in practice than the pure "parallel" form often seen in textbooks.

Oh, sorry I didn't know that there were 3 different algorithms. Why don't we multiply the PID terms with dt in all cases of implementing the algorithm in microcontroller?
 

Offline nForceTopic starter

  • Frequent Contributor
  • **
  • Posts: 393
  • Country: ee
Re: C code - implementation of PID in microcontroller
« Reply #23 on: March 29, 2017, 03:13:18 pm »
Quote
Why don't we multiply the PID terms with dt in all cases of implementing the algorithm in microcontroller?

Does my question make any sense? Because I can redefine it.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11790
  • Country: us
Re: C code - implementation of PID in microcontroller
« Reply #24 on: March 29, 2017, 04:33:18 pm »
Quote
Why don't we multiply the PID terms with dt in all cases of implementing the algorithm in microcontroller?

Does my question make any sense? Because I can redefine it.

No, your question doesn't make any sense. I was hoping you would try to answer the question by yourself by thinking about it some more. Have you tried to understand how time fits into the PID calculations?

You may have trouble with this unless you have an understanding of what mathematical integration and differentiation mean. Have you studied these concepts in your mathematics classes?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf