此功能块计算最新输入的100个数值的均值(浮动平均值)。采集的数据队列达到100个之后,队列每入栈一个新数值,将去掉一个队列里最早进来的数据(先进先出原则)。
功能块 "Floating Average" 将输入的多个浮点型数据计算出算术平均值,提供了一种平滑数据队列的方法。可周期性输入或脉冲触发的方式计算。
http://mpvideo.qpic.cn/0bf2hyafwaaap4adiva34jqvapwdlm7aawya.f10002.mp4?dis_k=ca3174ab4386671fb0caf283e2c773eb&dis_t=1648559115&vid=wxv_2006481786523959300&format_id=10002&support_redirect=0&mmversion=false
说明 此功能块计算最新输入的100个数值的均值(浮动平均值)。采集的数据队列达到100个之后,队列每入栈一个新数值,将去掉一个队列里最早进来的数据(先进先出原则)。
输入数据的计算有两种模式,在“模式”参数中定义。
- 由"Trigger"脉冲触发(cyclicExecutio= false)
- 周期输入(cyclicExecutio=true)
两种模式任选其一,也可在程序中做切换.
输入参数
表格实在是太难排版了.只能用图片来了.
输出参数
参数 | 数据类型 | 说明 | |
---|---|---|---|
average | REAL | 浮点平均值 | |
error | BOOL | 0: 无错误1: 有错误 | |
status | WORD | 状态/错误码 |
状态/错误码
状态码 | 状态 | 含义 | 建议 / 注意 | ||
---|---|---|---|---|---|
1 | 16#0000 | 无错误 | - | ||
1 | 16#8001 | 模式输入错误 | 选择模式(1 or 2). |
注意
- 功能块"Floating Average" 默认计算数据长度为 100 个浮点数的平均值。可以通过块参数接口调整所需的数据个数范围,在 "常数"下更改"WINDOW_SIZE"默认值即可。
- 功能块"Floating Average""不会查询输入数据的数据类型,如果输入的不是浮点数,将执行隐式转换,编译可能报错。 完整SCL代码:
FUNCTION_BLOCK "LGF_FloatingAverage"
TITLE = LGF_FloatingAverage
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : Siemens_Digital_Industry
FAMILY : LGF
NAME : LGF_FloatingAverage
//计算每个周期或每次触发脉冲输入REAL值的浮点算术平均值。
VAR_INPUT
cyclicExecution : Bool := false; // cyclic operation if TRUE, trigger not in use
trigger : Bool; // Trigger calculation
value : LReal; // Input values in real format
windowSize : Int := 100; // Calculation window of floating average
reset : Bool; // Resets function when the signal is true
END_VAR
VAR_OUTPUT
average { ExternalWritable := 'False'} : LReal; // Floating average
windowSizeReached { ExternalWritable := 'False'} : Bool; // Window size reached
error { ExternalWritable := 'False'} : Bool; // False = no error; True = error
status { ExternalWritable := 'False'} : Word; // Status and error codes
END_VAR
VAR
statValues { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[#ZERO_INT..#MAX_WINDOW_SIZE] of LReal; // Stored values for average calculation on a defined window size
statValuesSum { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : LReal := 0.0; // Added sum for average
statArithmeticAverage { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : LReal := 0.0; // Calculated average
statWindowSizeOld { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 0; // Windows size from previous scan
statCounter { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 0; // Counter for number of elements stored in the array
statwindowSizeReached { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Windows size reached memory bit
statTriggerOld { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool := false; // Value of trigger from previous scan. Used for edge detection.
END_VAR
VAR_TEMP
tempValue : LReal; // Temporary variable for value input
tempIndex : Int; // Indexing array
tempTriggerEdge : Bool; // Positive edge for trigger bit
END_VAR
VAR CONSTANT
ZERO_INT : Int := 0; // Zero constant in Int format
ZERO_LREAL : LReal := 0.0; // Zero constant in LReal format
MAX_WINDOW_SIZE : Int := 100; // Number of prev. values for floating average
INCREMENT : Int := 1; // Increment value
STATUS_FINISHED_NO_ERROR : Word := 16#0000; // Status: Execution finished without errors
ERR_WRONG_WINDOW_SIZE : Word := 16#8200; // Error: No correct window size set
END_VAR
BEGIN
REGION Initialization and input data processing
//Copy commonly used data to temp variables
#tempValue := #value;
//Positive edge detection for triggering of calculation
#tempTriggerEdge := #trigger AND NOT #statTriggerOld;
#statTriggerOld := #trigger;
// Reset OR if window size changes the calculation
IF #reset OR (#windowSize <> #statWindowSizeOld) THEN
#statWindowSizeOld := #windowSize;
#statCounter := #ZERO_INT;
#statValuesSum := #ZERO_LREAL;
#statArithmeticAverage := #ZERO_LREAL;
#average := #ZERO_LREAL;
#windowSizeReached := FALSE;
#statwindowSizeReached := FALSE;
#error := false;
#status := #STATUS_FINISHED_NO_ERROR;
RETURN;
// Check window size, in case of incorrect window size setup an error
ELSIF (#windowSize <= #ZERO_INT) OR (#windowSize > #MAX_WINDOW_SIZE) THEN
#statWindowSizeOld := #windowSize;
#statCounter := #ZERO_INT;
#statValuesSum := #ZERO_LREAL;
#statArithmeticAverage := #ZERO_LREAL;
#average := #ZERO_LREAL;
#statwindowSizeReached := FALSE;
#windowSizeReached := FALSE;
#error := TRUE;
#status := #ERR_WRONG_WINDOW_SIZE; // Info "No correct set of window size"
RETURN;
END_IF;
END_REGION
REGION Floating average calculation
// Triggered calculation OR cyclicly operation
IF #cyclicExecution OR #tempTriggerEdge THEN
//Calculate array counter
#tempIndex := #statCounter MOD #windowSize;
// First filling of the Array with values
IF (#statCounter < #windowSize) THEN
#statValues[#tempIndex] := #tempValue;
//Add value to sum
#statValuesSum = #tempValue;
//Increment counter
#statCounter = #INCREMENT;
//Calculate avarage value
#statArithmeticAverage := #statValuesSum / #statCounter;
ELSE
#statwindowSizeReached := TRUE;
//Manipulate first value of window
IF (#tempIndex = #ZERO_INT) THEN
//Add value to sum
#statValuesSum = #tempValue - #statValues[#ZERO_INT];
#statValues[#tempIndex] := #tempValue;
//Increment counter
#statCounter := #windowSize #INCREMENT;
//Calculate avarage value
#statArithmeticAverage := #statValuesSum / #windowSize;
ELSE
//Add value to sum
#statValuesSum = #tempValue - #statValues[#tempIndex];
//Add value to window
#statValues[#tempIndex] := #tempValue;
//Increment counter
#statCounter := #statCounter #INCREMENT;
//Calculate avarage value
#statArithmeticAverage := #statValuesSum / #windowSize;
END_IF;
END_IF;
END_IF;
END_REGION
REGION Outputs
#average := #statArithmeticAverage;
#windowSizeReached := #statwindowSizeReached;
#error := FALSE;
#status := #STATUS_FINISHED_NO_ERROR;
//ENO mechanism is not used - forced to true
ENO := TRUE;
END_REGION
END_FUNCTION_BLOCK