流量累积问题

已锁定

Letham

西门子1847工业学习平台

  • 帖子

    2021
  • 精华

    43
  • 被关注

    360

论坛等级:至圣

注册时间:2006-04-15

钻石 钻石 如何晋级?

流量累积问题

4297

18

2014-11-03 10:14:46

最近发现找答案 区内不少同行们在进行流量累积编程时出现了一些问题 .最简单问题其实就是大多数问题就是出在
将很大的一个数和一个很小的数字进行相加时,所得结果不准确的情况,其根本原因就是由于浮点数的存储机制造成
的。下面我就分享下我们公司同事所遇到的同样问题,以及我的解决方法。
下面介绍下 现场情况:现场使用的是E+H的 体积和质量流量计,流量计可以输出模拟量信号给PLC 来测量实际流量,同时
可以输出一个脉冲量信号,流量计里面可以设置多少体积或者质量输出一个脉冲信号给PLC,同时该流量计具有流量累积功能
在累积量比较小的情况下,程序可以正常工作,当累积量大于999999时问题出现了。让我帮忙查看问题原因。当然看了他的程序
一眼就可以看出问题所在,累积量采用浮点数,大数+小数 时出现了问题。由于S7-300/400 的浮点数有效位数只有6位。
下面分享下我的编程方式。
最基本原理和大家一样:总累积量+每秒的瞬时流量值。不过我把累积量使用三次累积的方式进行计算 即
(累积量=(X*1000+Y)*1000+Z )的形式进行计算,把总累积量按照千分位隔开。因为实际流量的单位之间换算以1000来进行转换也很
容易理解。比如1T=1000KG,1KG=1000G.1 立方米=1000L,1L=1000ML. 同时为了便于和流量计进行校准比对。我的程序加入了自动校准的功能。
输入当前流量计上实际的总流量后,置位校准命令,程序会自动重新计算X,Y,Z 参数。已达到PLC 中累积量和流量计上保持一致。
下面为我的程序接口说明:
PulseMode : BOOL ; //使用脉冲计算时,为1
PulseIn : BOOL ; //流量到PLC 发出的脉冲信号
Adjust : BOOL ; //流量校准命令
MassVolumePerPulse : REAL ; //Kg or L//每个脉冲代表多少KG 或者L
FlowrateIn : REAL ; //kg/s 或者 L/s
OBScanTime : INT ; //OB1的上一次扫描周期或者循环中断的中断周期,也就是流量计算的采样周期
CutOffValue : REAL ;//小流量切断数值
N : INT ; //N个OB1或者OB35 调用后进行一次累积
Reset : BOOL ;//流量累积复位信号
由于采用了浮点数作为累积量量,所以还是有精度问题。如果有更高累积量要求,建议还是采用双整数进行累积,小数部分采用浮点数进行累积。
// Total<999999.0 累积分辨率可以达到0.1 kg以上
// Total<9999999.0 累积分辨率可以达到1 kg,累积量Z小于1kg,将被忽略,当累积量Z 大于1.0 时,总累积量可以反应出变化
// Total<99999999.0 累积分辨率可以达到10 kg,累积量Z小于10kg,将被忽略,当累积量Z 大于10.0 时,总累积量可以反应出变化
// Total<999999999.0 累积分辨率可以达到100 kg,累积量Z小于100kg,将被忽略,当累积量Z 大于100.0 时,总累积量可以反应出变化
见如下调用方式 子OB35里面调用
//模拟量累计 注意红色部分必须赋值
CALL "ASW_FB_FAccu_Fct" , DB1321
PulseMode :=FALSE //非PULSE 模式
PulseIn :=
Adjust :=
MassVolumePerPulse:=
FlowrateIn :=2.000000e-001 // 实际流量
OBScanTime :=100 //OB 35 中断周期
CutOffValue :=
N :=5
Reset :=

//脉冲计数累计 注意红色部分必须赋值
CALL "ASW_FB_FAccu_Fct" , DB1322
PulseMode :=TRUE //PULSE 模式
PulseIn :="S7_CPU_Pulse500ms" //模拟脉冲输入点
Adjust :=
MassVolumePerPulse:=1.000000e-001 //每个脉冲多少Kg
FlowrateIn :=
OBScanTime :=
CutOffValue :=
N :=5
Reset :=
下面是我程序的STL 源代码
FUNCTION_BLOCK FB1000
TITLE =
//OPYRIGHT: (C) 2012 BY BUHLER CHINA
// WUXI,JIANGSU,CHINA
//
//PRODUCT: GCS7
//
//TITLE: ASW_FB_FAccu_Fct
//
//
//-------------------------------------------------------------------------
//
//IDENT: AUTHOR: DEPT: DATE:
//
//FB1321.1A Hao.Lei BU-AUT 19-DEC-2012
// 1st Release
//
//
//FB1321.1B Hao.Lei BU-AUT 25-JAN-2013
// 2nd Release
//
//FB1321.1C Hao.Lei BU-AUT 14-OCT-2014
// 2nd Release
//-------------------------------------------------------------------------
//
//PURPOSE:
//1A:MassFlow ACC
//1B:MassFlow Acc and add a interface for cutoffvalue and N
//1C:1-The Accumulate value can reach to Maxmuim value of float vlaue and
// 2-add the pulse signal is avaiable
// 3-Total Adjust function is realized.
// Total<999999.0 1 Decimal precision>=0.1
// Total<9999999.0 0 Decimal precision=1.0
// Total<99999999.0 0 Decimal precision=10.0
// Total<999999999.0 0 Decimal precision=100.0
//RESTRICTIONS:
//
//-------------------------------------------------------------------------
//
AUTHOR : Leihao
VERSION : 0.1


VAR_INPUT
PulseMode : BOOL ; //Pulse width must high than OB cyclic time
PulseIn : BOOL ;
Adjust : BOOL ;
MassVolumePerPulse : REAL ; //Kg or L
FlowrateIn : REAL ; //kg/s or L/s
OBScanTime : INT ;
CutOffValue : REAL ;
N : INT ;
END_VAR
VAR_IN_OUT
Reset : BOOL ;
END_VAR
VAR
Flowrate : STRUCT
FlowCalUnits : REAL ; //g/ms or ml/ms
END_STRUCT ;
AccuCal : STRUCT
Total : REAL ; //(Factor_1000TM+Factor_1000KgL)*1000+TotalWeightVolume
AdjustMassVolume : REAL ; //Adjust weight
TotalMassVolume : REAL ; //Kg or L .Always Low than 1000.0
TotalMassVolumeLeft : REAL ; //=TotalWeightVolume-1000.0
LastMassVolume : REAL ;
MassVolumeAddNTimes : REAL ; //units:g or l
MassVolumeAdd : REAL ;
ScanTimes : INT ;
Factor_1000TM : INT ; //N*1000 Ton/m3
Factor_1000KgL : INT ; //N*1000 times Kg/L
END_STRUCT ;
Edge : ARRAY [1 .. 8 ] OF BOOL ;
END_VAR
VAR_TEMP
tmpMassVolume : REAL ;
tmpMassVolume1000 : REAL ;
tmpBool : BOOL ;
END_VAR
BEGIN
NETWORK
TITLE = Flow Accumlate Function
//
//Convert flowrate from Kg/s or L/s to g/s and ml/s.
//
A #Adjust;
JC Adj;
L 0.000000e+000;
T #tmpMassVolume;
A #PulseMode; //使用脉冲进行流量累计
JC PM;
L #FlowrateIn;
L #CutOffValue; //流量小于此流量 时 不计算和流量计上CUTOFFFLOW 设为一致
= #tmpBool;
JC Nacc;

L #FlowrateIn;
T #Flowrate.FlowCalUnits;

L #OBScanTime;
ITD ;
DTR ;
L #Flowrate.FlowCalUnits;
*R ;
JU AM;
PM: A #PulseIn;
FP #Edge[1];
JNB AM;
L #MassVolumePerPulse;
L 1.000000e+003;
*R ;
AM: T #tmpMassVolume;
L #tmpMassVolume;
L #AccuCal.MassVolumeAddNTimes;
+R ;
T #AccuCal.MassVolumeAddNTimes;

L #AccuCal.ScanTimes;
+ 1;
T #AccuCal.ScanTimes;
Nacc: NOP 0;

A( ;
L #AccuCal.ScanTimes;
L #N;
>=I ;
) ;
O #tmpBool;
JNB Nrst;
L #AccuCal.TotalMassVolume;
T #AccuCal.LastMassVolume;

L #AccuCal.TotalMassVolume;
L 1.000000e+003;
*R ;
L #AccuCal.MassVolumeAddNTimes;
+R ;
L 1.000000e+003;
/R ;
T #AccuCal.TotalMassVolume;

L 0;
T #AccuCal.ScanTimes;
L 0.000000e+000;
T #AccuCal.MassVolumeAddNTimes;
L #AccuCal.TotalMassVolume;
L #AccuCal.LastMassVolume;
-R ;
T #AccuCal.MassVolumeAdd;

L #AccuCal.TotalMassVolume;
L 1.000000e+003;
-R ;
L 0.000000e+000;
>=R ;
JNB FKKG;
L #AccuCal.TotalMassVolume;
L 1.000000e+003;
-R ;
T #AccuCal.TotalMassVolumeLeft;
L #AccuCal.Factor_1000KgL;
L 1;
+I ;
T #AccuCal.Factor_1000KgL;
L 0.000000e+000;
T #AccuCal.TotalMassVolume;
FKKG: NOP 0;


L #AccuCal.Factor_1000KgL;
L 1000;
>=I ;
JNB FKT;

L #AccuCal.Factor_1000TM;
L 1;
+I ;
T #AccuCal.Factor_1000TM;
L 0;
T #AccuCal.Factor_1000KgL;
FKT: NOP 0;
JU Cal;
//-----------Adjust Value
Adj: L 0;
T #AccuCal.Factor_1000TM;
T #AccuCal.Factor_1000KgL;
L #AccuCal.AdjustMassVolume;
L 1.000000e+003;
L #AccuCal.AdjustMassVolume;
T #tmpMassVolume1000;
JC K1;
L #AccuCal.AdjustMassVolume;
L 1.000000e+006;
JC K6;

L #AccuCal.AdjustMassVolume;
L 1.000000e+006;
/R ;
TRUNC ;
T #AccuCal.Factor_1000TM;
JU K3;
K6: L 0;
T #AccuCal.Factor_1000TM;

K3: L #AccuCal.Factor_1000TM;
ITD ;
// DTR
L L#1000000;
*D ;
DTR ;
L #AccuCal.AdjustMassVolume;
TAK ;
-R ;
T #tmpMassVolume1000;
L #tmpMassVolume1000;
L 1.000000e+003;
JC K1;
/R ;
TRUNC ;
T #AccuCal.Factor_1000KgL;
JU K0;
K1: L 0;
T #AccuCal.Factor_1000KgL;
K0: L #AccuCal.Factor_1000KgL;
ITD ;
// DTR
L 1000;
*D ;
DTR ;
L #tmpMassVolume1000;
TAK ;
-R ;
T #AccuCal.TotalMassVolume;


SET ;
R #Adjust;
//-----------End Adjust Value
Cal: L #AccuCal.Factor_1000TM;
ITD ;

L 1000; //to units N*E6 base units (base units=kG)
*D ;
L #AccuCal.Factor_1000KgL; //to units N*E3 base units (base units=kG)
ITD ;
+D ;
DTR ;
L 1.000000e+003;
*R ;

L #AccuCal.TotalMassVolume;
+R ;
L #AccuCal.TotalMassVolumeLeft;
+R ;
T #AccuCal.Total;
L 0.000000e+000;
T #AccuCal.TotalMassVolumeLeft;
Nrst: NOP 0;

A #Reset;
JCN Zero;
L 0.000000e+000;
T #AccuCal.TotalMassVolume;
T #AccuCal.MassVolumeAddNTimes;
T #AccuCal.Total;
L 0;
T #AccuCal.Factor_1000KgL;
T #AccuCal.Factor_1000TM;
SET ;
R #Reset;
Zero: NOP 0;
END_FUNCTION_BLOCK
流量累积问题 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-300/400

共有54616条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

  • 分享

  • 只看
    楼主

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。