PDA

View Full Version : PID Filter Coefficient



JESmitter
- 11th December 2019, 20:58
Hi everyone, this is my first post.

I have implemented Henrik's PID INC routine in my controller for regulating flame temperature in an external combustion chamber. The PID filter is excellent and appears to function as advertised.

Next, I wanted to characterize the plant using Simulink's PID Tuner in order to obtain as accurate as possible gain factors for P, I, and D. However, there's another variable that their concerned with called "Filter Coefficient (N)" which is part of the Derivative function in the PID Block.

Is there any example code for implementing this?

Thanks!

HenrikOlsson
- 12th December 2019, 11:23
Hi,
If I read the documentation correctly the N-parameter serves as a low pass filter for the derivative term. My routine does not have that option.
I have ZERO experience with Simulink but looking at this page (https://www.mathworks.com/help/simulink/slref/pidcontroller.html#br9ejg0-18) it seems you can turn "Filtered derivative" off.

Not sure that helps a whole alot but that's what I've got at the moment :-)

/Henrik.

JESmitter
- 12th December 2019, 21:58
Thanks for the reply Henrik,

I thought that I might have to disable that feature in Simulink. The PID Tuner should still be able to generate the optimum P, I, and D gains.

I can add noise filtering (a few R's and C's) to my thermocouple amplifier that senses the flame temperature and provides the feedback signal.

If you or anyone comes across a way to provide some first order filtering in the digital domain for a PIC16F1937 for this application, I would love to see it!

Thanks again,

Jacob

HenrikOlsson
- 13th December 2019, 15:42
Take a look at Tracy Allens pages (http://www.emesystems.com/OLDSITE/BS2index.htm) on math (and other stuff) routines for the BasicStamp, specifically this page (http://emesystems.com/OLDSITE/BS2math5.htm) when digital filtering is covered. I've adopted one of the routines for PBP. I believe, at one point, I stuck that routine to the output of the PID filter but I've never posted it and I don't think I've done/tested anything with it. I'll leave you with the filter itself for you to what you want with.



'************************************************* ***************
'* Name : LowPassFilter.pbp *
'* Author : Henrik Olsson *
'* Notice : Copyright (c) 2010 Henrik Olsson 2010 *
'* : All Rights Reserved *
'* Date : 2010-09-01 *
'* Version : 1.0 *
'* Notes : Adopted from Tracy Allens BS2Math pages. *
'* : *
'************************************************* ***************

'--Variables accessed from "outside"--
LowPassFilter_Constant VAR BYTE
LowPassFilter_Input VAR WORD
LowPassFilter_Output VAR WORD

'--Variable used internally
Filter_Sign VAR BIT
Filter_Value VAR WORD
Filter_Z VAR WORD
Filter_Y VAR WORD



'--User must set LowPassFilter_Constant to 0-9 and then GOSUB InitLowPassFilter before
'--calling the actual filter routine.

pid_LP_Filter_Init:
Select Case LowPassFilter_Constant
CASE 0
Filter_Value = 65535
Case 1
Filter_Value = 32768
Case 2
Filter_Value = 21846
Case 3
Filter_Value = 16384
Case 4
Filter_Value = 13108
Case 5
Filter_Value = 10923
Case 6
Filter_Value = 9363
Case 7
Filter_Value = 8192
CASE 8
Filter_Value = 7282
Case 9
Filter_Value = 6554
End Select
RETURN

LowPassFilter:

If LowPassFilter_Constant = 0 then
LowPassFilter_Output = LowPassFilter_Input
Goto LowPassFilterDone
ENDIF

'Max difference between current filter output and a new input to the filter
'is 2048 so it's recomended to all input values clamped to +/-1024 or unexpected
'results may occur,

'Complete filter executes in 174-177 cycles----

'Multiply input by 16 (shift left by 4) then subtract the current output (times 16) to get the difference. (47 cycles)
Filter_Z = LowPassFIlter_Input << 4
Filter_Z = Filter_Z - Filter_Y

'Get the sign of the difference then convert to ABSolute value (7 cycles).
Filter_Sign = Filter_Z.15 ' sign of the difference (4 cycles)
Filter_Z = abs Filter_Z ' magnitude of the difference (3 cycles)

'Add then divide. Basically this is the same as A=(A+1)/2, A=(A+2)/3, A=(A+3)/4 etc.
'All in all 52 cycles.
Filter_Z = Filter_Z + LowPassFilter_Constant '(52 cycles including ** operation on next line
Filter_Z = Filter_Z ** Filter_Value

'Now the value is scaled and needs to be added to or subtracted from the output. (8 or 10 cycles)
If Filter_Sign then
Filter_Y = Filter_Y - Filter_Z
ELSE
Filter_Y = Filter_Y + Filter_Z
ENDIF

Filter_Sign = Filter_Y.15 ' sign of total output (4 cycles)

'Get absoulte value and divide by 16 to scale down the value to the same scale
'as the original input value. Then re-apply the sign. (50 or 52 cycles)
LowPassFilter_Output = (ABS Filter_Y) >> 4

If Filter_Sign then LowPassFilter_Output = -LowPassFilter_Output '(4 or 7 cycles)

LowPassFilterDone:
RETURN

JESmitter
- 13th December 2019, 17:09
Now that is a cool routine! I am looking forward to experimenting with it.

I have seen filtering applied to the PID output signal before. I'm not quite sure why except for maybe any minimal noise present in the error signal gets amplified in the PID gain block becoming a significant noise issue.

What I usually see is filtering on the Process Variable to remove noise signals that might interfere with the Derivative action. This type of noise is electrical in nature and can be caused by RFI, EMI, PWS noise, etc. It is picked up by long lead lengths and poor shielding between the sensor transmitter and controller.

And, now that I think about it, an analog filter would be preferred to target just the electrical noise thereby minimizing any filter delay that might impair control performance.

So now, I think that both the digital filter on the Controller Output and the analog filter on the Sensor Output is great way to harden the PID Controller against noise when used in harsh or noisy environments.

Thank you for the extraordinary research and help in jump-starting my brain cells!

Jacob

HenrikOlsson
- 13th December 2019, 18:12
Like I said, I think I just tacked it to the output without really knowing if it would help or make things worse. My main application for the PID routine is motor control and it's been over a decade since I initially wrote it. Now, with more knowledge gained, filtering the input signal or, as in your orginial question, the error prior to it getting to the derivative term may be better. Then again, I suppose it all depends on what issues you're trying to "fix".

If the input is noisy due to electrical noise perhaps some simple averaging is enough.

Keep us posted!