SCIENCE &TECHNOLOGY VISION
科技视界作者简介:于广吉(1974—),男,1999年毕业于吉林化工学院工业自动化专业,本科学历,工程师,现主要从事煤化工项目建设方面的工作。
基于C 语言的WINCC 在线趋势控件的应用
于广吉
(神华宁夏煤业集团甲醇制烯烃筹建处
宁夏
灵武
750411)
【摘要】随着信息处理技术的快速发展,工控自动化领域发生了日新月异的变化。对于现代化工生产中自动化程度和数据处理要求的不断提高,新技术、新概念也不断出现。为了更好的控制工艺指标,加强各相关参数间的对比性,提升工艺操作人员的操作能力;实现对工艺参数的在线对比检测、监视及稳定的控制。
从而提高劳动生产率,降低工人的劳动强度,使得经济效益明显提高。本文使用SIMATIC WinCC Explorer 中提供的WINCC ONLINE TREND CONTROL(在线趋势控件),利用C 语言及相关内部变量,利用画中画技术实现对位号的选择,在在线趋势控件中添加所选位号的曲线显示。
【关键词】C 语言;WINCC ;在线趋势控件
本文中使用的组态环境为WinCC Runtime V7.0+SP1+HF4
1建立相关内部变量
为了在WINCC 系统中对在线趋势控件的相关数据进行读取和写入,以便保存和获取用户的设置,首先要建立对应的内部变量。在SIMATIC WinCC Explorer 中选择Tag Man⁃agement,打开下部的子项,在Internal tags 中建立所需的变
量;右键点击选项后,选择New Group,建立变量组TREND_D,点击后保存,以后在线趋势控件的所有设置数据都要建立在这个组中,方便对数据进行处理。
图1
1.1
根据现场实际设备数量的多少,在变量组中建立记录复
选框数据的变量,并以CheckBox 开头来命名;例如,实际设备有十二项,就建立CheckBox1、CheckBox2……CheckBox12,数据类型为32位的浮点数。1.2
建立在线趋势控件中八条曲线所需的变量,用来记录画
面中趋势的相关设置,每一条曲线所需的变量一共有6个,分别为趋势名称、趋势的链接点、趋势的上限、趋势的下限、趋势的精确定标、趋势的粗略定标,建立方法为在Structure tag 目录中右键点击New Structure Type,建立变量组类型,添加上述的六个子变量,并定义数据类型,完成后建立八条曲线的变量组,实际结果如图1所示。
在变量组中建立的每一个变量,在Tag Management 中会自动生成对应的六个变量,并且以变量组.子变量来命名,这些变量的使用在下面的C 语言编程中会有所体现。
2建立C 语言全局子程序
为了简化在画面中使用C 脚本的使用,并且使得常用功能得以重复使用,需要在C 脚本编辑器中建立全局脚本C,打开Global Script,选择C-Editor,右键打开,进入Global Script C 编辑器环境,在Project functions 中新建所需要的子程序。2.1建立全局脚本———SetTrendTag,功能为定义变量组的写
入方法
#pragma option()
void SetTrendTag (long Index,char*TagName,long Dec⁃
Point,double MinValue,double MaxValue,double CGValue,dou⁃ble FGValue){
//声明SetTrendTag 功能块中所用的变量以及数据类型char Tr[32];char TrTag[32];
//定义程序中所用到的临时变量以及类型和长度sprintf(Tr,"Trend%d",Index);
//将曲线号码还原成曲线的名称
sprintf(TrTag,"%s.TagName",Tr);
38. All Rights Reserved.
SetTagCharWait(TrTag,TagName);
sprintf(TrTag,"%s.DecPoint",Tr); SetTagSDWordWait(TrTag,DecPoint);
sprintf(TrTag,"%s.Min",Tr); SetTagDoubleWait(TrTag,MinValue);
sprintf(TrTag,"%s.Max",Tr); SetTagDoubleWait(TrTag,MaxValue);
sprintf(TrTag,"%s.CG",Tr); SetTagDoubleWait(TrTag,CGValue);
sprintf(TrTag,"%s.FG",Tr); SetTagDoubleWait(TrTag,FGValue);
}
一直到这个地方程序所完成的都是把从子程序接口中读取的数据,按照规定的格式写入第一步中建立的变量组中,即把定义位置上的数据写入子变量中。例如SetTrendTag (1,"TT54321",AI/TI54321,0.0,250.0,10.0,1.0)
就是把第一条曲线——
—TREND1的曲线名称定义为TT54321,链接点为AI/TI54321,温度的量程为0~250,精确定标CGValue=10,粗略定标FGValue=1,保存到内部变量当中,以保存用户设置
2.2建立全局脚本———TrendCheckCount,功能为设置每个复选框选择后,对应变量的具体参数以及返回选择复选框的总个数(默认小于8)
#include"trend.h"
#pragma option()
int TrendCheckCount(){
#define PDL"(弹出画面).pdl"
//定义PDL为趋势选择的弹出画面名称
long Data;
int Cnt;
Cnt=0;
//趋势选择的总数清零
下面的程序是判断CheckBox1的复选框的选择,由于复选框的Process属性是按照2的N次方来标识具体选择了那个复选框,通过按位相与的方法取出每一个的赋值,判断是否选中。
Data=(long)GetProcess(PDL,"CheckBox1");
if((Data&0x01)==0x01&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"TT54321",AI/TI54321,0.0,250.0,0.0,0.0) ;}
当选中后,将具体的位号以及相关属性写入,以方便对在线趋势控件的属性进行设置。下面是对第二到第八个复选框的判断,名称用X代替,相与的数据使用八进制来表示,同时对曲线的编号在不大于八进行自加一。
if((Data&0x02)==0x02&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X2",0,0.0,100.0,20.0,10.0);}
if((Data&0x04)==0x04&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X3",0,0.0,100.0,20.0,10.0);}
if((Data&0x08)==0x08&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X4",0,0.0,100.0,20.0,10.0);}
if((Data&0x10)==0x10&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X5",0,0.0,100.0,20.0,10.0);}
if((Data&0x20)==0x20&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X6",0,0.0,100.0,20.0,10.0);}
if((Data&0x40)==0x40&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X7",0,0.0,100.0,20.0,10.0);}
if((Data&0x80)==0x80&&Cnt<8){Cnt=Cnt+1;Set⁃TrendTag(Cnt,"X8",0,0.0,100.0,20.0,10.0);}
上面是一个复选框的程序,多个复选框时将CheckBox1替换为CheckBox2……,下部的程序可以重复使用,具体与实际的设备数量有关。
全部复选框判断完成后,返回选择的总数Cnt return(Cnt);
}
2.3建立全局脚本———TrendWrite,功能为把写入在线趋势控件之中,并且定义曲线颜
#include"Trend.h"
#define PDL"趋势显示画面"
//定义显示在线趋势控件的画面。
#pragma option()
void TrendWrite(){
char TrdTag[80],Tr[32],TagName[32];
long TColor,DecPoint;
double Min,Max,CG,FG;
int i,j;
for(i=0;i<8;i++){
sprintf(Tr,"Trend%d",i+1);
sprintf(TrdTag,"%s.TagName",Tr);
sprintf(TagName,"%s",GetTagChar(TrdTag));
}
//读取内部变量TREND1~8的曲线名称和链接点
if(strcmp(TagName,"")==0)return;
//当曲线名称为空时,跳出此次循环程序不处理,这个用来把原来显示的曲线清除。
sprintf(TrdTag,"%s.DecPoint",Tr); DecPoint=GetTagSDWord(TrdTag);
sprintf(TrdTag,"%s.Min",Tr);
Min=GetTagDouble(TrdTag);
sprintf(TrdTag,"%s.Max",Tr);
Max=GetTagDouble(TrdTag);
39
. All Rights Reserved.
SCIENCE&TECHNOLOGY VISION科技视界
SCIENCE &TECHNOLOGY VISION
科技视界sprintf(TrdTag,"%s.CG",Tr);CG =GetTagDouble(TrdTag);sprintf(TrdTag,"%s.FG",Tr);
FG =GetTagDouble(TrdTag);读取内部变量的各个值,写入中间变量,用来给下面
的程序来使用。
strcat(TrdTag,TagName);
//由于上面的程序多次使用TrdTag,剪切字符串TagName 写到TrdTag,复原TrdTag 实际值
SetPropWord(PDL,"Trend","Index",i);//设置曲线的索引号,对在线趋势控件进行设置前,必须指定所要使用的曲线号。
switch(i){case 0:
TColor =0x0000FF;//Line Color Red break;
case 1:
TColor =0xFF0000;//Line Color Blue break;
case 2:
TColor =0x008000;//Line Color Green
break;
case 3:
TColor =0xFF00FF;//Line Color Purple break;
case 4:
TColor =0x0080FF;//Line Color Orange break;
case 5:
TColor =0x808040;//Line Color Darkblue break;
case 6:
TColor =0x004080;//Line Color Brown break;
case 7:
TColor =0x000000;//Line Color Black break;
default:TColor =0x000000;//Line Color
}
//修改每一条曲线的颜,能够避免出现两条曲线颜相同。
SetPropWord(PDL,"Trend","Color",TColor);SetPropChar(PDL,"Trend","Tagname",TrdTag);SetPropChar(PDL,"Trend","Name",TagName);SetPropWord(PDL,"Trend","Precisions",DecPoint);SetPropWord(PDL,"Trend","Autorange",0);SetPropDouble(PDL,"Trend","BeginValue",Min);SetPropDouble(PDL,"Trend","EndValue",Max);SetPropDouble(PDL,"Trend","CoarseGridValue",CG);SetPropDouble(PDL,"Trend","FineGridValue",FG);}}
调用趋势显示画面中的在线趋势控件,将最终的结果写入在线趋势控件之中。
3建立上位画面,最终功能实现
在第二步中完成的三个子程序都会再画面中调用,要显示曲线,就要建立一个空白画面,作为主显示画面,拖入在线趋势控件,添加选择位号按钮;再建立一个空白画面,作为弹出子画面,添加各个复选框、确定、清除所有的按钮。程序运行起来后,操作员只要点击选择位号按钮,就会弹出子画面,勾选对应的位号确定后,主画面中就会添加对应的曲线显示。
具体的实现方法分为四步:
第一步,在选择位号的按钮的左键按下动作中,把1(显示)值赋值给子画面的显示属性中,实现点击画面后,选择位号画面弹出。
第二步:由于复选框的属性不会自动记录,这样就要建立数据的反写,把复选框的属性在打开画面时显示出来。在子画面的画面打开动作中,编辑C 脚本,读取CHECKBOX 的值,写入复选框的Process 属性中,实现代码为:
#include "apdefap.h"void OnOpenPicture
(char*
lpszPictureName,
char*
lpszObjectName,char*lpszPropertyName)
{
#pragma option()int i;
char sWork[16];double dWork;for(i=1;i<=24;i++){
sprintf(sWork,"CheckBox%d",i);dWork =GetTagDouble(sWork);SetProcess(<;子画面的全名称>,sWork,dWork);
c语言中的sprintf用法}
第三步:当确定键按下后,要读取本画面的各个复选框的属性值,调用各个子程序,完成对在线趋势控件设置的功能。
#include "apdefap.h"void
OnClick
(char*
lpszPictureName,
char*
lpszObjectName,char*lpszPropertyName)
40
. All Rights Reserved.
{
#pragma option()
#define PIC"主画面的全名称"
int Cnt,i;
char sWork[32];
double dWork;
for(i=1;i<=8;i++){
SetTrendTag(i,"",0,0.0,0.0,0.0,0.0);
}
/
/调用写命令,清除原有曲线的设置,方便新曲线设置的写入。
Cnt=TrendCheckCount();
//调用属性读取的子程序,把具体参数写入内部变量中,并且返回曲线的总数量。
if(Cnt<=0){
SetVisible(PIC,"子画面的全名称",0); return;
}
//如果没有一个复选框被选择,则关闭子画面,并且跳过下面的程序,只是清除曲线。SetPropWord(PIC,"Trend","NumItems",Cnt); TrendWrite();
调用趋势写入的子程序,把每一个曲线的设置实际写入。
for(i=1;i<=24;i++){
sprintf(sWork,"CheckBox%d",i);
dWork=GetProcess(lpszPictureName,sWork); SetTagDouble(sWork,dWork);
}
//保存每一个复选的值到内部变量之中,建立双向的数据连接。
SetVisible(PIC,"子画面的全名称",0); SetPropChar(PIC,"Trend","Command","Reload");
}
关闭画面,重新装载在线趋势控件。
第四步:完成清除全部复选框的选择。
#include"apdefap.h"
void OnClick(char*lpszPictureName,char*lpszObjectName,char*lpszPropertyName){
#pragma option()
int i;
char sWork[16];
for(i=1;i<=24;i++){
sprintf(sWork,"CheckBox%d",i); SetProcess(子画面的全名称,sWork,0.0);
}
for(i=1;i<=8;i++){
SetTrendTag(i,"",0,0.0,0.0,0.0,0.0); TrendWrite();
SetVisible(PIC,"子画面的全名称",0); SetPropChar(PIC,"Trend","Command","Reload");
}
到此所有的程序都已经完成,实现的画面如图2所示。
图2
4结束语
利用C语言的灵活,可以实现原有控件无法实现的功能,将画中画技术与脚本的完美结合,极大方便了
操作员的操作,简单明了,根据这种思路,可以结合多种WINCC控件,完成各种现场工况下的复杂环境。
[责任编辑:常鹏飞
]
41
. All Rights Reserved.
SCIENCE&TECHNOLOGY VISION科技视界
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论