Author Topic: Digital PID regulator implementation, q15_t output to register  (Read 3102 times)

0 Members and 1 Guest are viewing this topic.

Offline YansiTopic starter

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Hello!

I am trying to implement a digital control loop for something, that requires a PI regulator. I have available already implemented optimized PID controller function, that takes both input and all gains (Kp, Ki, Kd) in a fractional Q1.15 format. The output of the regulator is also Q1.15 format. (It is the arm_pid_q15 function)

What I am unable to figure out, is how to interface the regulator's output to a register, that controls for example a PWM signal, the correct way.

Imagine a register, that controls some kind of PWM and has the range of 0 to 240. The best thing I could come up with, is to scale the regulator output to 240 and saturate it for this range (i.e. not use the negative values at all). Looks like this:

Code: [Select]
q15_t err = setpoint - measured;
q15_t out = arm_pid_q15(&S, err); 
/* Limit (only positive output) */
if (out < 0) out = 0;
/* Scale to 240 */
out = (out * 240UL)  >> 15;
PWMREG = out;

This seems to me it might be correct to do it that way. However based on what the regulator does and how the Q/fractional format works, the regulator itself cannot have gain larger than 1. If I set Kp as MAX value (0.9999 or 32767 respectively) while leaving Ki = Kd = 0, the error input variable should be copied directly to the output. (Which it indeed seems to be doing, based on what I see). What is the correct way to implement gains larger than 1? One cannot regulate much if at all, at loop gains lower than 1.

It seems to me, that to implement gains > 1, I could pretend the regulator output is not Q1.15 but for example Q4.12 to obtain gain range of +-8. It should then look like this:

Code: [Select]
q15_t err = setpoint - measured;
q15_t out = arm_pid_q15(&S, err); 
/* Limit to only positive output) */
if (out < 0) out = 0;
/* Scale to 240 */
out = (out * 240UL)  >> 12;  /* Q4.12  */
/* Limit the range to 240 */
if (out > 240) out = 240;
PWMREG = out;

Still this looks kind of silly to me. What have I missed?

Thanks for help,
Yan
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Digital PID regulator implementation, q15_t output to register
« Reply #1 on: May 24, 2017, 05:57:49 am »
You can't pretend q15 is q3.12, the implementation of arm_pid_q15 needs to have different arithmetics for that.
You can change it arm_pid_q12 though, the source is open.
 

Offline YansiTopic starter

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Re: Digital PID regulator implementation, q15_t output to register
« Reply #2 on: May 24, 2017, 08:58:32 am »
But noone talked about Q3.12. (you have missed a bit there) :)

However I do understand your point.  But the question wasn't how to or shall I modify the function, but how to use a regulator function with gains up to 1 in a real application, as I couldn't really figure out.

Otherwise you telling me the function is useless in the original format? That would be odd.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Digital PID regulator implementation, q15_t output to register
« Reply #3 on: May 24, 2017, 09:15:25 am »
You also normalize what enters the system. Your setpoint and error are q15 as well.
Having gains above 1 doesn't make sense, because you'll turn the system in an on/off controller.
 

Offline YansiTopic starter

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Re: Digital PID regulator implementation, q15_t output to register
« Reply #4 on: May 24, 2017, 11:34:37 am »
Quote
Having gains above 1 doesn't make sense, because you'll turn the system in an on/off controller.

Strongly doubt that. Can you make a proof?

How do you make an "on/off regulator" by amplifying the error input by more than 1? That's pure nonsense, isn't it? I am really no expert on control theory, but I am not aware of any theorem saying you cannot use gains larger than 1.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Digital PID regulator implementation, q15_t output to register
« Reply #5 on: May 24, 2017, 12:36:06 pm »
This is the implementation and you can perfectly set Kx to maximum of q15. But, it saturates the output as well.
Code: [Select]
y[n] = y[n-1] + (Kp + Ki + Kd) * x[n] + ((-Kp ) - (2 * Kd )) * x[n-1] + Kd * x[n-2]

There is however nothing preventing you from using any other number as base for your q15.
Such as 240 instead of 1. However, you have to convert the error to this range as well.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf