zoukankan      html  css  js  c++  java
  • c#基于TCP/IP、CIP协议的欧姆龙PLC通信

     引用:http://www.360doc.com/content/20/0622/09/13826502_919829722.shtml

     

    一、关于CIP协议

      CIP通信是Common Industrial Protocl(CIP)的简称,它是一个点到点的面向对象协议,能够实现工业器件(传感器,执行器)之间的连接,和高等级的控制器之间的连接。目前,有3种网络DeviceNet,ControlNet,EtherNet/IP使用CIP通信协议作为其上层网络协议,由ODVA组织统一管理,以确保其一致性和精确性。

    二、EtherNet/IP通信

      EtherNet/IP(Ethernet/Industrial Protocol),是一个工业级的通信网络,用于工业器件间高速的信息交换,这些器件包括简单的IO器件(传感器),还有复杂的控制器(机器人,PLC,焊机,过程控制器)。EtherNet/IP使用CIP(Common Industrial Protocl),其使用EtherNet和TCP/IP技术传送CIP通信包,CIP作为开放的应用层,位于EtherNet和TCP/IP协议之上。

    三、CIP通信报文

    1.注册会话ID  

    private byte[] Registercmd = new byte[28]
    {

      //--------------------------------------------------------Header 24byte-------------------------------------
      0x6F,0x00,//命令 2byte
      0x04,0x00,//Header后面数据的长度 2byte
      0x00,0x00,0x00,0x00,//会话句柄 4byte
      0x00,0x00,0x00,0x00,//状态默认0 4byte
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//发送方描述默认0 8byte
      0x00,0x00,0x00,0x00,//选项默认0 4byte

           //-------------------------------------------------------CommandSpecificData 指令指定数据 4byte

      0x01,0x00,//协议版本 2byte

      0x00,0x00,//选项标记 2byte
    };

    2.提取会话ID-注册请求的应答报文

    private byte[] RefRegistercmd = new byte[28] 
    {

      //--------------------------------------------------------Header 24byte-------------------------------------
      0x6F,0x00,//命令 2byte
      0x04,0x00,//CommandSpecificData的长度 2byte
      0x6B,0x01,0x01,0x00,//会话句柄 4byte 由PLC生成
      0x00,0x00,0x00,0x00,//状态默认0 4byte
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//发送方描述默认0 8byte
      0x00,0x00,0x00,0x00,//选项默认0 4byte

       //-------------------------------------------------------CommandSpecificData 指令指定数据 4byte

      0x01,0x00,//协议版本 2byte

      0x00,0x00,//选项标记 2byte
    };

    public byte[] SessionHandle=new byte[4]{0x6B,0x01,0x01,0x00};//从应答报文提取的会话ID

    后续读写PLC的报文中,需要包含PLC返回的会话ID


    3.读数据服务请求报文

     报文由三部分组成 Header 24个字节 、CommandSpecificData 16个字节、以及CIP消息(由读取的标签生成)

     实例,读取单个标签名为 TAG1的报文总长度为64个字节

    private byte[] Header = new byte[24]
    {
      0x6F,0x00,//命令 2byte
      0x28,0x00,//长度 2byte(总长度-Header的长度)=40 
      0x6B,0x01,0x01,0x00,//会话句柄 4byte
      0x00,0x00,0x00,0x00,//状态默认0 4byte
      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//发送方描述默认0 8byte
      0x00,0x00,0x00,0x00,//选项默认0 4byte
    };

    private byte[] CommandSpecificData = new byte[16]
    {
      0x00,0x00,0x00,0x00,//接口句柄 CIP默认为0x00000000 4byte
      0x01,0x00,//超时默认0x0001 4byte
      0x02,0x00,//项数默认0x0002 4byte
      0x00,0x00,//空地址项默认0x0000 2byte
      0x00,0x00,//长度默认0x0000 2byte
      0xb2,0x00,//未连接数据项默认为 0x00b2
      0x18,0x00,//后面数据包的长度 24个字节(总长度-Header的长度-CommandSpecificData的长度)
    };

    private byte[] CipMessage = new byte[24]
    {

       0x52,0x02     //服务默认0x52  请求路径大小 默认2
      0x22,06,0x24,0x01,//请求路径 默认0x01240622 4byte
      0x0A,0xF0,//超时默认0xF00A 4byte
      0x0A,0x00,//Cip指令长度  服务标识到服务命令指定数据的长度 
      0x4C,//服务标识固定为0x4C 1byte  
      0x03,// 节点长度 2byte  规律为 (标签名的长度+1/2)+1
      0x91,//扩展符号 默认为 0x91
      0x04,//标签名的长度

      0x54,0x41,0x47,0x31,//标签名 :TAG1转换成ASCII字节 当标签名的长度为奇数时,需要在末尾补0  比如TAG转换成ASCII为0x54,0x41,0x47,

         需要在末尾补0 变成 0x54,0x41,0x47,0

      0x01,0x00,//服务命令指定数据 默认为0x0001 

       0x01,0x00,0x01,0x00//最后一位是PLC的槽号

    };

    PLC回复报文:

    6F0018006B01010000000000000000000000000000000000000000000100020000000000B200 08 00 CC 00 0000 C100  0000 

    CC-服务标识 00-填充字节  0000-状态 0为正常  0800:CC-0000的长度  C100-数据类型:Bool   0000为数据false


     实例,读取多个标签名为 TAG、TAG1的报文总长度为86个字节

    6F003E006B01010000000000000000000000000000000000000000000100020000000000B2002E005202200624010AF020000A02200224010200060010004C0391035441470001004C03910454414731010001000100

    Header:6F003E006B01010000000000000000000000000000000000      24byte      

    CommandSpecificData: 00 00 00 00 0100020000000000B2002E00     16byte    

    CipMessage:52 02  20062401  0AF0 2000 0A 02  20022401  0200  0600 1000  4C0391 03 54414700 0100  4C039104544147310100  01000100

    52-服务代码 02 -请求路径大小 20062401-请求路径  0AF0超时   20 00 CIP指令长度 (0A-00之间的长度为32个字节)

    0A-服务代码(多个标签) 02-请求路径大小  20022401请求路径 0200 标签的数量  0600 偏移量(初始值为:2+标签数量*2)

    1000 偏移量 =标签服务长度+初始偏移量(有几个标签就有几个偏移量)

    4C 03 91 03 54414700 0100  标签TAG  4C039104544147310100  标签TAG1

    PLC回复报文:

    6F0034006B01010000000000000000000000000000000000000000000100020000000000B20024008A000000020006001300CC000000D00005003232323232CC000000D00005003232323232    76byte

    Header:6F0034006B01010000000000000000000000000000000000  24byte

    CommandSpecificData:000000000100020000000000B2002400  16byte

    CipMessage:8A00 0000 0200 0600 1300 CC 00 0000  D000 0500 3232323232  CC000000D00005003232323232

    8A-多个标签   0000 -状态  0200-项数  0600-标签TAG偏移量  1300-标签TAG1偏移量  0000-状态0正常 D000-数据类型:string 

    0500:字符串长度(字符串类型特有的)

    3232323232-数据 "22222":

    目前常用的数据类型: C1-BOOL C2-SINT C3-Short C4-Int  C7-UShort C8-UInt  CA-Float CB -Double  D0-String


    4.写入数据服务报文

    实例,往标签名为:TAG1 写入true  数据类型为 bool

    写入报文:68byte

    6F002C006B01010000000000000000000000000000000000 000000000100020000000000B2001C00 5202200624010AF00E004D03910454414731C1000100010001000100      

    header:6F002C006B01010000000000000000000000000000000000   24byte

    CommandSpecificData:000000000100020000000000B2001C00     16byte

    CIPmessage:52  02 20062401 0AF0  0E00 4D 03 91 04 54414731 C100 0100 0100 01000100   28byte

    52-服务标识     02-请求路径大小  20062401-请求路径,默认   0AF0-超时           0E00-CIP指令长度(绿色部分的长度)

    4D-写入标识     03-(标签名的长度+1)/2+1   91-扩展符号    04-标签TAG1的长度   54414731 -标签名的ASCII表示

    C100-数据类型    0100-默认项   0100-数据 TRUE(2byte)          01000100 - 默认最后一位为PLC槽号

    PLC回复报文:

    6F0014006B0101 00000 00000000000000000000000000000 000000000100020000000000B2000400CD000000   44byte

    header:6F0014006B01010000000000000000000000000000000000 24byte

     CommandSpecificData:000000000100020000000000B2000400  16byte

    CIPMessage:CD 00 0000     CD-服务标识  00-填充字节  0000-状态好

    注意:当写入字符串类型时,写入的数据长度为奇数时,需要在数据后填充一个字节0


    5.扩展知识

      首先建立起TCP连接,CIP通信端口默认为44818。TCP连接成功后,发送会话消息,获取四个字节的会话ID,就可以正常读写了。

       header:6F0014006B0101 0000 000000000000000000000000000000 24byte

      0x0000:状态正常(在报文里低位在前高位在后)

      0x0001:发出了无效或不受支持的封装命令;

      0x0002:接收器中的内存资源不足,无法处理命令;

      0x0003:封装消息的数据部分中的数据形成不良或不正确;

      0x0004:Reserved for legacy(RA);

      0x0064:向目标发送封装消息时,始发者使用了无效的会话句柄;

       0x0065:目标收到一个无效长度的信息

       0x0069:不支持的封装协议修订

        CIPMessage:CD00 0000

      0x0000-成功

      0x0004-它没有正确生成或匹配标记不存在

      0x0005-引用的特定项(通常是实例)无法找到

      0x0006-请求的数据量不适合响应缓冲区。 发生了部分数据传输

      0x000A-尝试处理其中一个属性时发生错误

      0x0013-命令中没有提供足够的命令数据/参数来执行所请求的服务

      0x001C-与属性计数相比,提供的属性数量不足

      0x001E-此服务中的服务请求出错

      0x0020-命令中参数的数据类型与实际参数的数据类型不一致

      0x0026-IOI字长与处理的IOI数量不匹配

    HK
  • 相关阅读:
    day27_递归
    Linux常用命令
    Linux中的标准输入输出文件
    秋招日记《三》——字节三面挂
    《秋招日记》阿里一面
    秋招日记<->PDD一面挂
    十大排序
    第 254 场周赛 数组元素的最小非零乘积
    找不到boost/bind.hpp
    如何在Google浏览器中批量下载网页上的图片
  • 原文地址:https://www.cnblogs.com/HarryK4952/p/14707409.html
Copyright © 2011-2022 走看看