几种常用滤波方法 1;算术平均滤波法;2:递推平均滤波法;3:中位值平均滤波法
简单算法如下
算术平均滤波法;
连续取N个采样值进行算术平均运算
N值较大时:信号平滑度较高,但灵敏度较低
N值较小时:信号平滑度较低,但灵敏度较高
递推平均滤波法
把连续取N个采样值看成一个队列队列的长度固定为N
每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据.(先进先出原则)
把队列中的N个数据进行算术平均运算,就可获得新的滤波结果
中位值平均滤波法
相当于“中位值滤波法”+“算术平均滤波法”
连续采样N个数据,去掉一个最大值和一个最小值然后计算N-2个数据的算术平均 值
以前做过一个 将三种滤波方法放在一起的SCL程序块(三种方法有些类似,都需要占用一定的存储空间来存储采样值),通过参数来指定采样什么样的滤波。希望大家多多指教,看看有什么不足之处。
绿色部分为注释
TYPE UDT2000
STRUCT
InValue,OutValue:REAL;
QueuePostion:INT;
InIntervalFastTask,SampleInterval:DINT;
Queue:ARRAY[1..32] OF REAL;
END_STRUCT;
END_TYPE
FUNCTION_BLOCK FB2000
TITLE = 'Digital Filter Algorithm'
(*
COPYRIGHT: (C) 2012 BY BUHLER China
Wuxi,Jiangsu,China
PRODUCT: GCS7
TITLE: Median Average /Average/Moving average Filter Algorithm
-------------------------------------------------------------------------
IDENT: AUTHOR: DEPT: DATE:
FC200.1C Hao.Lei BU-AUT 23-JAN-2013
1B Release
-------------------------------------------------------------------------
RELEASE:
1A:Median Average Filter Algorithm
1B:Median Average Filter Algorithm and Enter the data to the Queue
1C:Median Average/Average/Moving average Filter are integrated in one FB
RESTRICTIONS:
-------------------------------------------------------------------------
Functions
=========
*)
VERSION: '1.0'
AUTHOR: Leihao
NAME: DFA
FAMILY: 'BU-AUT'
VAR_TEMP
tmpBool:BOOL;
tmpMax,tmpMin,tmpSum:REAL;
tmpAddr,tmpIndex:INT;
END_VAR
VAR_INPUT
FilterFactor:INT:=5;
InIntervalFastTask:DINT:=20;//Unit--MS 调用此功能块的循环OB周期
SampleInterval:DINT:=1000;//Unit--MS 采样周期》=循环OB周期
Invalue:REAL;//采样值
Queue:POINTER; //存放采样值的数据区,比如数组 等
tmpPointer AT Queue:STRUCT
DBNO:WORD;
Addr:DWORD;
END_STRUCT;
MovingAverage,MedianAverage,ParNoFilter,ParExternalQueue:BOOL;
END_VAR
VAR_IN_OUT
OutValue:REAL;
CheckParameter:BOOL;//Enable check the Parameter
END_VAR
VAR
QueueInternal:ARRAY[1..16] OF REAL;//内置的存放采样值得数组,不够用,可是在IN 接口里通过 Queue来指定,同时设定ParExternalQueue=1
QueuePostion:INT;
FastTaskTimes:INT;
END_VAR
VAR_OUTPUT
ErrorCode:INT;
Error:BOOL;
END_VAR
LABEL
End;
END_LABEL
BEGIN
(*
Median Average /Average/Moving average Filter Algorithm
//-How to set parameter MovingAverage and MedianAverage
//-MovingAverage=1 and MedianAverage=1 ----->Moving / Median average Filter Algorithm
//-MovingAverage=1 and MedianAverage=0 ----->Moving average Filter Algorithm
//-MovingAverage=0 and MedianAverage=1 ----->Median Average Algorithm
//-MovingAverage=0 and MedianAverage=0 ----->Average Algorithm
*)
IF ParNoFilter THEN
QueuePostion:=0;
OutValue:=Invalue;
ELSE//====Using the filter Algorithm
(*====Error handle
Code:1001-1003:Factor assign error
Code:2001:Internal error,Try to download the datablock
Code:3001-3002:The interace assign to Queue Error
Code:4001-4002:The InIntervalFastTask and SampleInterval parameters are not correct
*)
IF CheckParameter THEN
IF MedianAverage AND FilterFactor<2 THEN
ErrorCode:=1001;//The Filter factor is low than 3 when using the Median and Average Algorithm
Error:=TRUE;
GOTO End;
ELSIF FilterFactor>16 AND ParExternalQueue=0 THEN
ErrorCode:=1002; //The Filter factor is High than 16 .The maxmum filter factor is 16 when using interal data area.
Error:=TRUE;
GOTO End;
ELSIF FilterFactor<1 THEN
ErrorCode:=1003; //The Filter factor is Low than 1 .The minmumfor filter factor is 1
Error:=TRUE;
GOTO End;
ELSIF QueuePostion<0 THEN
ErrorCode:=2001; //Internal error,Please try to download the Data //block of this Function block.
Error:=TRUE;
GOTO End;
ELSIF (ParExternalQueue AND (WORD_TO_INT(tmpPointer.DBNO)=0)) THEN
ErrorCode:=3001; //can only assign DB,DI memory to "Queue interface" When using the External memory.or no paramenter is assign to "Queue interface".
Error:=TRUE;
GOTO End;
ELSIF (ParExternalQueue AND (tmpPointer.Addr AND DW#16#00000007)<>DW#16#0) THEN
ErrorCode:=3002; //The start address of actual parameter for "Queue interface" must start with "x.0".
Error:=TRUE;
GOTO End;
ELSIF InIntervalFastTask>SampleInterval THEN
ErrorCode:=4001; //The SampleInterval must be high or equal to the called intrval(for example OB35,OB33 cycle intrval)
Error:=TRUE;
GOTO End;
ELSIF SampleInterval MOD InIntervalFastTask<>0 THEN
ErrorCode:=4002; //The SampleInterval must be equal to (N*InIntervalFastTask,N=1,2,3....)
Error:=TRUE;
GOTO End;
ELSE
ErrorCode:=0;
Error:=FALSE;
END_IF;
END_IF;
FastTaskTimes:=FastTaskTimes+1;
//Begin to sample the value
IF FastTaskTimes>=SampleInterval/InIntervalFastTask Then
FastTaskTimes:=0;
IF ParExternalQueue THEN //=====Enter the data to external Queue memory
tmpAddr:=DWORD_TO_INT(SHR(IN:=(tmpPointer.Addr AND DW#16#00FFFFFF),N:=3));
WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr+QueuePostion*4]:=REAL_TO_DWORD(Invalue);
ELSE //=====Enter the data to Internal Queue memory
QueueInternal[QueuePostion+1]:=Invalue;
END_IF;
QueuePostion:=QueuePostion+1;
IF QueuePostion>=FilterFactor THEN
tmpBool:=True;
QueuePostion:=0;
END_IF;
(*
Data sampling end or using the moving average filter,begin to calculate the
Max. Min. Sum. and calculate the value after filter Algorithm.
*)
IF tmpBool OR MovingAverage THEN
tmpSum:=0.0;tmpMax:=0.0;//====Initilizatize the tmpSum,tmpMin,tmpMax
IF ParExternalQueue THEN
tmpMin:=DWORD_TO_REAL(WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr]);//====Initilizatize tmpMin
ELSE
tmpMin:=QueueInternal[1];//====Initilizatize tmpMin
END_IF;
FOR tmpIndex:=0 TO FilterFactor-1 BY 1 DO
IF MedianAverage THEN //need to calculate the Max and Min value
IF ParExternalQueue THEN
IF tmpMin>=DWORD_TO_REAL(WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr+tmpIndex*4]) THEN
tmpMin:=DWORD_TO_REAL(WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr+tmpIndex*4]);
END_IF;
IF tmpMax<=DWORD_TO_REAL(WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr+tmpIndex*4]) THEN
tmpMax:=DWORD_TO_REAL(WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr+tmpIndex*4]);
END_IF;
ELSE
IF tmpMin>= QueueInternal[tmpIndex+1] THEN tmpMin:=QueueInternal[tmpIndex+1]; END_IF;
IF tmpMax<= QueueInternal[tmpIndex+1] THEN tmpMax:=QueueInternal[tmpIndex+1]; END_IF;
END_IF;
END_IF;
//====Calculate the Summary value
IF ParExternalQueue THEN
tmpSum:=tmpSum+DWORD_TO_REAL(WORD_TO_BLOCK_DB(tmpPointer.DBNO).DD[tmpAddr+tmpIndex*4]);
ELSE
tmpSum:=tmpSum+QueueInternal[tmpIndex+1];
END_IF;
END_FOR;
//====Calculate the output of the filter
IF NOT MedianAverage THEN
OutValue:=tmpSum/INT_TO_REAL(FilterFactor);
ELSE
OutValue:=(tmpSum-tmpMax-tmpMin)/INT_TO_REAL(FilterFactor-2);
END_IF;
END_IF;
END_IF;
END_IF;
End:RETURN;
END_FUNCTION_BLOCK