最近编了段流量累计的程序,觉得不理想,敬请高手们指点一下,看累计误差怎样才能做到最小。欢迎大家拍砖
具体代码如下:
FUNCTION_BLOCK FB1007
TITLE = '流量采集及积算'
//
// 本程序只能在OB35里调用
// 一、监测说明
// 1、高高限设定值和高限设定值同时设定为‘0’,则高限报警和高高限报警被屏蔽
// 2、低低限设定值和低限设定值同时设定为‘0’,则低限报警和低低限报警被屏蔽
// 3、高高限设定值等于高限设定值且不为‘0,则意味着只有高限报警而没有高高限报警
// 4、低低限设定值等于低限设定值且不为‘0,则意味着只有低限报警而没有低低限报警
// 二、设定要求
// 1、高高限设定值需大于等于高限设定值,否则报设定错误
// 2、低低限设定值需大于等于低限设定值,否则报设定错误
// 三、累计流量误差大时需复位清零
VERSION: '1.0'
AUTHOR: Ping
NAME: FluxSum
FAMILY: Bjzh
VAR_INPUT
IOadr : WORD; // 硬件组态里的输入地址
HiLim : REAL; // 满量程
LoLim : REAL; // 最小量程
Rest : BOOL; // 复位
HHSp : REAL:=0.0; //高高限设定值
HiSp : REAL:=0.0; //高限设定值
LoSp : REAL:=0.0; //低限设定值
LLSp : REAL:=0.0; //低低限设定值
END_VAR
VAR_OUTPUT
ActVal: REAL; //瞬时值
SumVal: REAL; //累积值
AdOK : BOOL := FALSE; //信号采集OK
ADErr : BOOL := FALSE; //传感器断线
HH : BOOL := FALSE; //高高限报警到达
Hi : BOOL := FALSE; //高限报警到达
Lo : BOOL := FALSE; //低限报警到达
LL : BOOL := FALSE; //低低限报警到达
HHSpErr : BOOL := FALSE; //高高限设定值错误
LLSpErr : BOOL := FALSE; //低低限设定值错误
END_VAR
VAR
x : INT:=0;
Ms : INT:=0; //100毫秒
S : INT:=0; //秒
M : INT:=0; //分钟
H : INT:=0; //小时
D : INT:=0; //天
Msval : DINT:=0; //毫秒累计值
Sval : DINT:=0; //秒累计值
Mval : DINT:=0; //分累计值
Hval : DINT:=0; //时累计值
Dval : DINT:=0; //天累计值
END_VAR
VAR_TEMP
n : INT;
HSignalOK : BOOL;
LSignalOK : BOOL;
ComAct : REAL;
END_VAR
BEGIN
// 复位
IF Rest THEN
x := 0 ;
AdOK := TRUE;
HH := FALSE;
Hi := FALSE;
Lo := FALSE;
LL := FALSE;
ADErr := FALSE;
Ms :=0;
S :=0;
M :=0;
H :=0;
Msval :=0;
Sval :=0;
Mval :=0;
Hval :=0;
Dval :=0;
ELSE
//模拟采样
n := WORD_TO_INT(IOadr);
IF (IOadr = 16#7FFF) OR (IOadr = 16#8000) THEN
x:=x+1;
IF ( x>=50) THEN ADErr := TRUE;ActVal :=0.0;END_IF;
ELSE
x := 0 ;
ADErr := FALSE;
ComAct := ((HiLim - LoLim) / 27648.0 * INT_TO_REAL(n)) + LoLim;
ActVal := ComAct/3600.0; //瞬时值 以秒为单位
END_IF;
// 高高限设定和比较
IF NOT ADErr THEN
IF (HHSp = 0.0) AND (HiSp = 0.0) THEN
HH := FALSE;
Hi := FALSE;
HHSpErr := FALSE;
ELSE
// 高高限和高限报警
IF (HiSp > HHSp) THEN
HHSpErr:=TRUE;
ELSE
HHSpErr :=FALSE;
IF (ComAct >= HiSp) AND (ComAct < HHSp) THEN
Hi :=TRUE;
ELSE
Hi :=FALSE;
END_IF;
IF (ComAct >= HHSp)THEN
IF (HHSp = HiSp) THEN
Hi :=TRUE;
HH :=FALSE;
ELSE
Hi :=FALSE;
HH :=TRUE;
END_IF;
ELSE
HH :=FALSE;
END_IF;
END_IF;
END_IF;
// 低低限设定和比较
IF (LLSp = 0.0) AND (LoSp = 0.0) THEN
LLSpErr := FALSE;
Lo := FALSE;
LL := FALSE;
ELSE
// 低低限给低限报警
IF (LLSp > LoSp) THEN
LLSpErr:= TRUE;
ELSE
LLSpErr:=FALSE;
IF (ComAct <= LoSp) AND (ComAct > LLSp) THEN
Lo := TRUE;
ELSE
Lo :=FALSE;
END_IF;
IF (ComAct < LLSp)THEN
IF (LoSp = LLSp)THEN
Lo := TRUE;
LL :=FALSE;
ELSE
Lo :=FALSE;
LL := TRUE;
END_IF;
ELSE
LL :=FALSE;
END_IF;
END_IF;
END_IF;
IF NOT HH AND NOT Hi THEN HSignalOK:=TRUE;ELSE HSignalOK:=FALSE;END_IF;
IF NOT LL AND NOT Lo THEN LSignalOK:=TRUE;ELSE LSignalOK:=FALSE;END_IF;
IF HSignalOK AND LSignalOK THEN AdOK:=TRUE;ELSE AdOK:=FALSE; END_IF;
// 流量累计
IF ( Ms < 9 )THEN //毫秒
Ms:=Ms+1;
Msval:=Msval+INT_TO_DINT(n);
ELSE //秒
Sval:=Sval+Msval;
Ms:=0;
Msval:=0;
IF ( S < 59 )THEN
S:=S+1;
ELSE //分钟
Mval:=Mval+Sval;
S:=0;
Sval:=0;
IF ( M < 59 )THEN
M:=M+1;
ELSE //小时
Hval:=Hval+Mval;
M:=0;
Mval:=0;
IF ( H < 23 )THEN
H:=H+1;
ELSE //天
Dval:=Dval+Hval;
D:=D+1;
H:=0;
Hval:=0;
END_IF;
END_IF;
END_IF;
END_IF;
SumVal:= (DINT_TO_REAL(Msval+Sval+Mval+Hval+Dval))/36000.0;//流量累计
ELSE //断线复位
AdOK := FALSE;
HH := FALSE;
Hi := FALSE;
Lo := FALSE;
LL := FALSE;
Ms :=0;
S :=0;
M :=0;
H :=0;
Msval :=0;
Sval :=0;
Mval :=0;
Hval :=0;
END_IF;
END_IF;
END_FUNCTION_BLOCK