中国工控网 - 中国工控网,专业工控信息服务平台 !

商业资讯: 企业新闻 | 人物专访 | 企业关注 | 专家观点 | 技术文摘 | 解决方案 | 展会新闻 | 工控知识 | 工控百科 | 产品推荐

你现在的位置: 首页 > 商业资讯 > 工控知识 > 运用VC#编程通过OPC方式实现PC机与西门子PLC通讯

运用VC#编程通过OPC方式实现PC机与西门子PLC通讯

信息来源:gkong.biz  时间:2009-06-24  浏览次数:185

  运用VC#编程通过OPC方式实现PC机与西门子 PLC通讯 -- 同步 篇 1、OPC服务介绍 西门子提供的最新软件:-2005为各种组态软件的开发提供了一个统一的平台,它建立的PC站既为
  运用VC#编程通过OPC方式实现PC机与西门子PLC通讯--同步篇
  1、 OPC服务介绍
  西门子提供的最新软件: Net PC- CD 2005为各种组态软件的开发提供了一个统一的平台,它建立的PC站既为一些组态软件,如:、等提供了与PLC的通讯平台,也提供了一套编程接口,可使用高级语言编程通过 Net访问PLC数据。本文讨论的主要就是这个编程接口,最新版的 NET支持五种编程方式:
  <1>、控件
  提供了一系列数据访问控件,以便于向VB6这种语言使用控件的方式与PLC通讯。
  <2>、OPC自动化
  为VB6、等语言运用OLE 自动化的方式进行编程。
  <3>、OPC用户接口
  这是专门为VC++提供的一种高效编程方式,其灵活程度与执行效率比前面的两种方式均要高得多。
  <4>、针对微软的.NET平台的OPC用户接口
  这也是一种非常灵活的编程接口,不过它针对的是.NET平台,其提供了大量的.NET类库,以便于像VC#、等高级语言编程。本文将详细的介绍该接口。
  <5>、OPL XML接口
  顾名思义,主要是针对XML编程的。
  对于<2>、<3>、<4>编程方式,他们各自又可以分为同步访问方式和异步访问方式。按西门子的文档解释:同步通讯指的是当一个客户在访问服务器时,其他客户的访问必须等待,直到服务器处理完该客户的请求,才能继续进行下一个服务,异步访问与之正好相反,本文主要讲的是同步编程篇,异步篇以后再提供。
  2、 配置OPC服务器
  要进行编程,必须先配置服务器。本文以 DP网络为例,介绍PC站的配置。其内容主要来自西门子文档。
  需要的软件:
  Step7 V5.3
   Net PC- CD 2005
  需要的硬件:
  至少为CP5611或以上级别,笔记本可以为CP5511,带DP口的S7-300 PLC(若使用 NET的仿真功能可以不需要这些硬件,后面会介绍到)
  <1>、组态一个S7站,配置 DP网络,其DP地址设为3,并下载到PLC,然后把网线由MPI口转到DP口。S7站的配置这里就不介绍了。
  <2>、在 Step7 V5.3中建立一个新工程,插入一个PC站,并把该PC站的名字改成与你的计算机名字相同。打开该PC站的硬件组态界面。插入OPC服务器和连接卡CP5611(或者CP5511),他们在PC槽中处的位置可以任意,
  注:在插入CP5611时,应该选择与组态S7站一样的网络,并将网络地址设为2,一定不要与PLC的地址冲突。
  然后点击下面工具条标为红色的按钮:
  选中”OPC ”,然后插入一个新的连接,
  在弹出的对话框中选择连接类型为S7 ,
  在OK后,然后在新对话框的红色标志位置输入3,表示PLC的地址,
  并选择 …,设置CPU的槽号为2,
  OK后,然后编译并保存。
  <3>、然后建立OPC服务器,有两种方式,本文介绍较简单的一种。
  打开, Net中的 ,一般安装后,他会自动启动,并点击 …按钮,找到你刚才在Step 7中建立PC站时创建的
  XDBs文件夹下的XDB文件,然后导入成功。
  <4>、可以使用 Net中的OPC ,并选择 NET服务,然后在它下面创建组,然后在组下创建变量,这样可以监控PLC数据,VC#编程不需要使用该程序,但熟悉使用OPC 有利于了解 Net中的编程结构。
  说明:打开 Net中的 ,选中S7进行如下的配置后,可以不需要PLC、CP5611等并可以模拟,
  上面的所有步骤,均可在 下,PC 的根树下,选择相应的帮助文档得到。
  3、 OPC编程
  <1>、西门子的变量结构如下:
  ----------------------服务器------------------------------
  / .... (一系列类型的服务器)
  / 1 2 3 ...(把更新时间一致的变量统一为一个组)
  / Item1 Item2 ... (变量:I、Q、M、DB等,指向网络中某个PC站OPC 服务的某个连接)
  -----------------------------------------------------------------------------------------------------------------
  第一层是不同种类的服务器,如:类型,类型,等一系列类型,这里选择类型。
  第二层是,一个服务器下可以有多个组,可以把组理解为扫描周期相同的一系列变量的集合。在开发组态界面时,可以把一个界面中的所有变量统一到一个组中。
  第三层是Item,项是指向网络中某个PC站OPC 服务的某个连接的一系列变量,如:I、Q、M、DB等
  <2>、项的命名
  项即Item,在S7连接中针对的直接是PLC中的变量,因此它的命名很重要:
  格式: :[]
  其中的表示连接类型,在上面的组态PC站时可以选择,这里应该与它一致,类型有9种,最常用的为S7,即S7连接,其他类型请参看文档。
  :顾名思义,即在上面的组态PC站时产生的连接名,如果使用仿真功能,连接名为DEMO :变量名有一系列规则,这里举例说明,读者也可以使用OPC 创建变量,学习程序是如何生成变量名的。
  S7:[DEMO]MB1 :表示连接类型为S7,连接名为DEMO(这里为仿真),变量为MB1
  S7:[DEMO]QB0,3: 表示为从QB0开始的三个连续变量。
  S7:[DEMO]DB10,X4.6 :表示DB10的DBX4.6。
  <3>、添加引用
  在VC#开发环境中添加对库的引用引用,该库属于.NET库,不属于COM库,西门子虽然编写了类库,以提供对.NET平台的支持,但这些类库仍然难于编程,
  里面包含了大量的在托管和非托管区传输数据,因此我们需要在它的基础上再开发一个类库,以简化以后的编程,首先在类的开头使用命名空间:
   ;
   ;
   ;
  <4>、编程
  1、 在类的开头部分生名变量
   ="";
   ; // OPC 接口
   1; // to
   int ; // for the
   =new (11); //用于记录组名和组ID号
   =new (17); //用于记录项名和项ID号
   Guid ;
   int = 0; //客户组号
   int =0; //Item号
  2、 创建服务器,编写Open()方法
  /// 创建一个OPC 接口
  ///
  /// 返回错误信息
  /// 若为true,创建成功,否则创建失败
   bool Open(out )
  {
  ="";bool =true;
  Type ;
  //获取 OPC COM 接口
   = ();
   = ();
  try
  {
  //创建接口
   =()();
  ="";
  }
   ( err) //捕捉失败信息
  {
  ="错误信息:"+;=;
  }
   true;
  }
  3、 在服务器上添加用于添加的函数
  /// 添加组
  /// 组名
  /// /创建时,组是否被激活
  /// //组的刷新频率,以ms为单位
  /// 返回错误信息
  /// 若为true,添加成功,否则添加失败
   bool ( ,int ,int ,out )
  {
  ="";
  int = 0x407; //本地语言为英语
  int ;
   = 0;
  // 处理非托管COM内存
   ;
   = ;
   = (,);
  try
  {
  (, //组名
  , //创建时,组是否被激活
  , //组的刷新频率,以ms为单位
  , //客户号
  , //这里不使用
  (),
  , //本地语言
  out , //移去组时,用到的组ID号
  out , //返回组中的变量改变时的最短通知时间间隔
  ref ,
  out 1); //指向要求的接口
  =+1;
  int =;
  (,);
  }
   ( err) //捕捉失败信息
  {
  ="错误信息:"+;
  }
  {
  if () ();
  }
  if(=="")
   true;
  else
   ;
  }
  4、 向指定的组中添加变量的函数
  /// 添加多个项到组
  ///
  /// 指定组名
  /// 指定项名
  /// 由函数返回的服务器确定的项ID号
  /// 无错误,返回true,否则返回
   bool ( ,[] ,int[] )
  {
  bool =true;
  [] =new [];
  for(int i=0;i{
  =+1;
  [i] = ""; // 可选的通道路径,对于 Net不需要。
  [i] = [i]; // , see
  [i] = 1; // item is
  [i] = ; //
  [i] = 0; // blob size
  [i] = ; // to blob
  [i] = 2; //Word数据类型
  }
  //初始化输出参数
   = ;
   = ;
  try
  {
  // 添加项到组
  (()())(,,out ,out );
  // to get the out fom the m_
  // the
  int[] = new int[];
  (, , 0,);
   pos = ;
  for(int i=0;i
  {
  if ([i] == 0)
  {
   = ()(pos, ());
  [i] = ;
  ([i],);
  pos = new (32() + (()));
  }
  else
  {
  =;
  ;
  }
  }
  }
   ( err) // for in
  {
  =;
  }
  {
  // 释放非托管内存
  if( != )
  {
  ();
   = ;
  }
  if( != )
  {
  ();
   = ;
  }
  }
   ;
  }
  说明:使用该函数时,在类的开头,应该先声明整数数据,以用于保存由本函数返回的服务器对每一项分配的Item ID号:
  5、 向指定组中指定的一系列项变量写入数据的公开方法
  ///
  /// 一次性写入多个值
  ///
  /// 指定组名
  /// 由服务器给每个项分配的标志号
  /// 一系列值
  /// 无错误,返回true,否则返回
   bool ( ,int[] ,[] )
  {
  bool =true;
   = ;
  if(() != null)
  {
  try
  { //同步写入
  (()())(,,,out );
  int[] = new int[];
  (, , 0,);
  for(int i=0;i
  {
  if ([i] != 0)
  {
   = ;
  =;
  }
  }
  }
  ( )
  {
  =;
  }
  }
   ;
  }
  注:参数int[] 应该是与函数中的int[] 参数相对应。
  6、 编写获取变量值的函数
  /// 一次性读取多个数据
  /// 指定组名
  /// >由服务器给每个项分配的标志号
  /// 返回的值
  /// 无错误,返回true,否则返回
   bool Read( ,int[] ,[] )
  {
  bool =true;
  //指向非托管内存
  //指向非托管内存
   = ;
   = ;
  if(()!=null)
  {
  try
  { //同步读取
  (()())(_DS_,,,out ,out );
  int[] = new int[];
  (, , 0,);
  [] =new [];
   pos = ;
  for(int i=0;i
  {
  if ([i] == 0)
  {
  //从非托管区封送数据到托管区
  [i] = ()(pos,());
  pos = new (32() + (()));
  [i]=[i];
  }
  }
  }
  ( )
  {
   ;
  }
  }
   ;
  }
  注:同()函数一样,参数int[] 应该是与函数中的int[] 参数相对应。
  通过给类编写上面的几个最重要的函数,我们已经可以读写PLC数据了,下面给出例子。
  创建一个C#工程,添加对上面开发的类库的引用,并在窗体类的开头,声名:
  int[] nt=new int[2];int[] nt1=new int[2];
  S7 ;
  其中的即为上面开发的类。
  <1>、创建服务器接口
  在程序初始化处,添加:
   =new S7(S7_);
  <2>、打开连接
   err;
  (out err);
  <3>、添加组
  ("",1,350,out err);
  ("1",1,350,out err);
  <4>、添加项(即变量),同样在程序的初始化中,将一系列项添加到他们各自得组。
  [] m1={"S7:[DEMO]MB1","S7:[DEMO]MW3"};
  [] m2={"S7:[DEMO]MB6","S7:[DEMO]MW8"};
  ("",m1,nt);
  ("1",m2,nt1);
  <5>、读写数据,这里以写数据为例:
  obj[0]=2;
  obj[1]=3;
  if(1)
  {
  ("",nt,obj);
  }
  else if(2)
  {
  ("1",nt1,obj);
  }
  至此并完成了数据的通讯,如何,只要你把类库开发完善,在它的基础上再开发,会异常简单,本人已开发了完善的类库,上面的类库只是把最重要的部分讲解出来,我曾经在网上求助过很多次这方面的知识,无人应答。唉!太不容易了,等待 NET软件花费了我一个月的时间,然后读几百页的英文文档,到开发程序,并测试花费了我一个星期的空闲时间,写这篇文章,又花费了我一个晚上的时间,不过我还是愿意把这些摸索出来的东西发给大家。

    ——本信息真实性未经中国工控网证实,仅供您参考