C# S7与西门子( Siemens) 通讯(TCP/IP)批量读写

nuget 搜索 HlgSiemensCommunication

开源地址HlgSiemensCommunication: c# S7 协议批量读写西门子DB块数据 (C# S7 protocol batch read and write Siemens DB block data)

目前仅写入了DB块的封装 0x84 其他区域可根据需求自行修改代码 

不清楚此协议或查看其他源码无法理解的伙伴可以查阅此代码,代码编写接地气,便于理解与上手。

 
        /// <summary>
        /// 拼接命令
        /// </summary>
        /// <returns></returns>
        public byte[] GetReadCommand(List<InputSiemensParams> siemens, out List<SiemensParams> outsiemensParams)
        {
            var virtualsiemens = InitDBVirtual(siemens);
            outsiemensParams = virtualsiemens;

            byte[] resultCommand = new byte[19 + (12 * virtualsiemens.Count)];

            //TPKT 4位
            {
                resultCommand[0] = 0x03;
                resultCommand[1] = 0x00;

                //2-3 整体报文长度
                resultCommand[2] = BitConverter.GetBytes(resultCommand.Length)[1];
                resultCommand[3] = BitConverter.GetBytes(resultCommand.Length)[0];
            }

            //ISO 3位
            {
                resultCommand[4] = 0x02;
                resultCommand[5] = 0xF0;
                resultCommand[6] = 0x80;
            }

            //header  10位
            {
                resultCommand[7] = 0x32;
                resultCommand[8] = 0x01;
                resultCommand[9] = 0x00;
                resultCommand[10] = 0x00;
                resultCommand[11] = 0x00;
                resultCommand[12] = 0x01;
                //13-14 读取的param长度
                resultCommand[13] = BitConverter.GetBytes((12 * virtualsiemens.Count) + 2)[1];
                resultCommand[14] = BitConverter.GetBytes((12 * virtualsiemens.Count) + 2)[0];

                resultCommand[15] = 0x00;
                resultCommand[16] = 0x00;
            }

            //param  2位
            {
                //17(读代码) 
                resultCommand[17] = 0x04;
                //18(总共读取个数) 
                resultCommand[18] = (byte)virtualsiemens.Count;
            }

            //param 组装读取参数 12
            {
                for (int i = 0; i < virtualsiemens.Count; i++)
                {
                    var itemNo = i * 12;
                    resultCommand[19 + itemNo] = 0x12;
                    resultCommand[20 + itemNo] = 0x0a;
                    resultCommand[21 + itemNo] = 0x10;

                    resultCommand[22 + itemNo] = (virtualsiemens[i].ItemType == SiemensDataType.Bool) ? (byte)(0x01) : (byte)0x02;
                    //(数据长度)
                    resultCommand[23 + itemNo] = BitConverter.GetBytes(virtualsiemens[i].Length)[1];
                    resultCommand[24 + itemNo] = BitConverter.GetBytes(virtualsiemens[i].Length)[0];
                    //DB地址
                    resultCommand[25 + itemNo] = BitConverter.GetBytes(virtualsiemens[i].VirtaulDB)[1];
                    resultCommand[26 + itemNo] = BitConverter.GetBytes(virtualsiemens[i].VirtaulDB)[0];
                    //DB块代码)
                    resultCommand[27 + itemNo] = 0x84;
                    //(偏移地址)
                    resultCommand[28 + itemNo] = (byte)(virtualsiemens[i].VirtualOffSet / 256 / 256 % 256);
                    resultCommand[29 + itemNo] = (byte)(virtualsiemens[i].VirtualOffSet / 256 % 256);
                    resultCommand[30 + itemNo] = (byte)(virtualsiemens[i].VirtualOffSet % 256);
                }
            }

            return resultCommand;
        }

使用例程 

   SiemensS7Client s7Client=new s7Client("127.0.0.1");
   s7Client.Conn();
   var ReadByte = s7Client.ReadByte("DB702.DBB9");
   var ReadBool = s7Client.ReadBool("DB702.DBX1.2");
   var ReadInt16 = s7Client.ReadInt16("DB702.DBW20");

   var WriteByte = s7Client.WriteByte("DB702.DBB9", 205);
   var WriteBool = s7Client.WriteBool("DB702.DBX1.2", true);
   var WriteInt16 = s7Client.WriteInt16("DB702.DBW20", 350);
   var output = s7Client.ReadValue(new List<InputSiemensParams>()
    {
        new InputSiemensParams(){  DB = "DB702.DBB7", ItemType = SiemensDataType.Byte },
        new InputSiemensParams(){  DB = "DB702.DBB1.2", ItemType = SiemensDataType.Bool },
        new InputSiemensParams(){  DB = "DB702.DBB8", ItemType = SiemensDataType.Byte },
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte },
    });

    var outputSiemens = s7Client.WriteValue(new List<InputSiemensParams>()
    {
        new InputSiemensParams(){  DB = "DB702.DBB7", ItemType = SiemensDataType.Byte,WriteValue=5},
        new InputSiemensParams(){  DB = "DB702.DBB8", ItemType = SiemensDataType.Byte,WriteValue=57},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
        new InputSiemensParams(){  DB = "DB702.DBB9", ItemType = SiemensDataType.Byte,WriteValue=230},
    });

报文解析

批量读
  TPKT
  03 (固定)
  00 (固定)
  00 37(整体报文总共长度)
  
  ISO 
  02 (固定)
  f0 (固定)
  80 (固定)

  header
  32     (固定)
  01     (固定)
  00 00  (固定)
  00 01  (标识序列号)
  00 26 (读取参数长度) params长度
  00 00

  params
  04(读代码) --1
  03(总共读取个数) --1
  12 0a 10 02 00 0b(数据长度) 00 01(读取个数) 84(DB块代码) 00 00 20(偏移地址) --12
  12 0a 10 02 00 02(数据长度) 00 01(读取个数) 84(DB块代码) 00 00 08(偏移地址) --12
  12 0a 10 02 00 04(数据长度) 00 01(读取个数) 84(DB块代码) 00 0d 20(偏移地址) --12


  批量读数据解析
  TPKT
  03 
  00 
  00 47(总共长度)全部长度
  
  ISO 
  02 (固定)
  f0 (固定)
  80 (固定)
  
  Header
  32 
  03 
  00 00 
  00 00 
  00 02 
  00 32 (数据长度)对应下方Data
  00 (错误)
  00 (错误代码)
  
  Params
  04(读代码)
  03(读取个数) 
  
  Data
  ff 返回代码Success
  04 
  00 08 长度
  03  数据值
  00  filebyte
  
  ff 
  04 
  00 08
  03
  00 --填充字节
  
  ff 
  04 
  01 10
  30 20 31 35 20 20 20 20 20 20 20 00    
  00 00 00 00 14 14 31 32 33 34 35 36 37 38 39 30    
  31 32 33 34 35 36                                  

  批量写
  TPKT
  03 (固定)
  00 (固定)
  00 37(总共长度)全部长度
  
  ISO 
  02 (固定)
  f0 (固定)
  80 (固定)

  header
  32     (固定)
  01     (固定)
  00 00  (固定)
  00 01  (标识序列号)
  00 26 (写入报文参数长度) params长度
  00 00  (数据值 DataLength)

  params
  04(读代码) --1
  03(总共读取个数) --1
  12 0a 10 02(按字节写入/按位写入) 00 0b(数据长度) 00 01(读取个数) 84(DB块代码) 00 00 20(偏移地址) --12
  12 0a 10 02(按字节写入/按位写入) 00 02(数据长度) 00 01(读取个数) 84(DB块代码) 00 00 08(偏移地址) --12
  12 0a 10 02(按字节写入/按位写入) 00 04(数据长度) 00 01(读取个数) 84(DB块代码) 00 0d 20(偏移地址) --12
  

  Data
  00 03    00 01(数据长度)    01 00 (写入数据)
  00 03    00 01(数据长度)    00 00 (写入数据)
  00 04    00 20(数据长度)    44 24 a3 33 (写入数据)                                      

 有编写不正确的地方或还需优化的地方欢迎指正交流,谢谢!

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
C#中与三菱PLC基于TCP/IP技术进行通信,并读写数据的步骤如下: 1. 首先,确保PLC和计算机在同一个网络中,并且能够相互访问。 2. 在C#中,使用Socket类来实现与PLC之间的通信。你可以创建一个Socket对象,并设置其连接参数,包括PLC的IP地址和端口号。 3. 使用Socket对象的Connect方法连接到PLC。如果连接成功,你就可以发送和接收数据了。 4. 在通信过程中,你需要了解PLC的通信协议。三菱PLC通常使用MC Protocol进行通信。你需要根据协议规范构造正确的请求和响应消息。 5. 读取数据: - 构造读取数据的请求消息,包括要读取的寄存器地址、数据类型和读取长度等信息。 - 使用Socket对象的Send方法将请求消息发送到PLC。 - 使用Socket对象的Receive方法接收来自PLC的响应消息。 - 解析响应消息,提取所需的数据。 6. 写入数据: - 构造写入数据的请求消息,包括要写入的寄存器地址、数据类型和写入的数据等信息。 - 使用Socket对象的Send方法将请求消息发送到PLC。 - 使用Socket对象的Receive方法接收来自PLC的响应消息,以确认写入操作是否成功。 需要注意的是,具体的读写数据的请求和响应消息格式可能因PLC型号、通信协议和你的需求而有所不同。请参考三菱PLC的通信手册和C#的Socket编程文档,以获得更详细的信息和示例代码。 此外,还要考虑数据的格式转换、字节顺序等问题,以确保数据在C#和PLC之间正确传输和解析。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值