S7-SCL 算术平均值--附代码

2022-03-29 21:06:27 浏览数 (1)

此功能块计算最新输入的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代码:
代码语言:javascript复制
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


0 人点赞