C#上位机与三菱PLC的通信06--MC协议之QnA-3E报文测试

news2024/9/22 22:29:32

1、A-3E报文回顾

1、存储区分类及访问规则 

2、命令类型

命令由主命令+子命令组成

 

3、报文结构

 2、启动mc服务器

3、创建VS项目

这节继续使用上节的VS2022的项目,增加一个方法 MCTestA3E(),具体怎么创建项目,见上节的过程。C#上位机与三菱PLC的通信04--MC协议之A-1E报文测试

 

4、报文组装与测试

 1、 读字数据,读取D100开始的2个数据, short/ushort

 

  /// <summary>
  /// A-3E报文测试
  /// </summary>
  private static void MCTestA3E()
  {
      // 连接
      Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      socket.Connect("192.168.1.7", 6000);

      #region 1、 读字数据,读取D100开始的2个数据, short/ushort

      byte[] bytes = new byte[]
      {
          0x50,0x00,//请求副头部,固定50 00
          0x00,// 网络号,可变,根据PLC的设置
          0xFF,//PLC编号,固定值
          0xFF,0x03,//目标模块IO编号,固定FF 03
          0x00,// 可变,目标模块站号
          0x0C,0x00,  // 剩余字节长度,当前字节往后
          0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
          0x01,0x04,// 成批读出,主命令
          0x00,0x00,// 字操作,子命令
          0x64,0x00,0x00,// 起始地址
          0xA8,// 区域代码 
          0x02,0x00 //读取长度     //  如果请求一个Float   2;2Float  4
      };

      socket.Send(bytes);

      // 暂时以这种方式来处理  
      byte[] respBytes = new byte[15];
      socket.Receive(respBytes);

      for (int i = 11; i < respBytes.Length; i++)
      {
          // 小端处理,每2个字节作为一个数据
          byte[] dataBytes = new byte[2];
          dataBytes[0] = respBytes[i];
          dataBytes[1] = respBytes[++i];
          Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
      }

      #endregion
  }

 2、 读字数据,读取D102开始的1个数据, float类型

 

 /// <summary>
 /// A-3E报文测试
 /// </summary>
 private static void MCTestA3E()
 {
     // 连接
     Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     socket.Connect("192.168.1.7", 6000);

     #region 1、 读字数据,读取D100开始的2个数据, short/ushort

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 网络号,可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度,当前字节往后
     //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
     //    0x01,0x04,// 成批读出,主命令
     //    0x00,0x00,// 字操作,子命令
     //    0x64,0x00,0x00,// 起始地址
     //    0xA8,// 区域代码 
     //    0x02,0x00 //读取长度     //  如果请求一个Float   2;2Float  4
     //};

     //socket.Send(bytes);

      暂时以这种方式来处理  
     //byte[] respBytes = new byte[15];
     //socket.Receive(respBytes);

     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    // 小端处理,每2个字节作为一个数据
     //    byte[] dataBytes = new byte[2];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
     //}

     #endregion

     #region 2、 读字数据,读取D102开始的1个数据, float类型

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 网络号,可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度,当前字节往后
     //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
     //    0x01,0x04,// 成批读出,主命令
     //    0x00,0x00,// 字操作,子命令
     //    0x66,0x00,0x00,// 起始地址102
     //    0xA8,// 区域代码 
     //    0x02,0x00 //读取长度     //   请求一个Float占2个字节 
     //};

     //socket.Send(bytes);

      暂时以这种方式来处理  
     //byte[] respBytes = new byte[15];
     //socket.Receive(respBytes);

     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    //小端处理,每4个字节作为一组才是数据
     //    byte[] dataBytes = new byte[4];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    dataBytes[2] = respBytes[++i];
     //    dataBytes[3] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToSingle(dataBytes,0));//字节转换成浮点数
     //}

     #endregion

      
 }

 3、 读位数据,即X102开始的1个位(true/false)

/// <summary>
/// A-3E报文测试
/// </summary>
private static void MCTestA3E()
{
    // 连接
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect("192.168.1.7", 6000);

    #region 1、 读字数据,读取D100开始的2个数据, short/ushort

    //byte[] bytes = new byte[]
    //{
    //    0x50,0x00,//请求副头部,固定50 00
    //    0x00,// 网络号,可变,根据PLC的设置
    //    0xFF,//PLC编号,固定值
    //    0xFF,0x03,//目标模块IO编号,固定FF 03
    //    0x00,// 可变,目标模块站号
    //    0x0C,0x00,  // 剩余字节长度,当前字节往后
    //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
    //    0x01,0x04,// 成批读出,主命令
    //    0x00,0x00,// 字操作,子命令
    //    0x64,0x00,0x00,// 起始地址
    //    0xA8,// 区域代码 
    //    0x02,0x00 //读取长度     //  如果请求一个Float   2;2Float  4
    //};

    //socket.Send(bytes);

     暂时以这种方式来处理  
    //byte[] respBytes = new byte[15];
    //socket.Receive(respBytes);

    //for (int i = 11; i < respBytes.Length; i++)
    //{
    //    // 小端处理,每2个字节作为一个数据
    //    byte[] dataBytes = new byte[2];
    //    dataBytes[0] = respBytes[i];
    //    dataBytes[1] = respBytes[++i];
    //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
    //}

    #endregion

    #region 2、 读字数据,读取D102开始的1个数据, float类型

    //byte[] bytes = new byte[]
    //{
    //    0x50,0x00,//请求副头部,固定50 00
    //    0x00,// 网络号,可变,根据PLC的设置
    //    0xFF,//PLC编号,固定值
    //    0xFF,0x03,//目标模块IO编号,固定FF 03
    //    0x00,// 可变,目标模块站号
    //    0x0C,0x00,  // 剩余字节长度,当前字节往后
    //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
    //    0x01,0x04,// 成批读出,主命令
    //    0x00,0x00,// 字操作,子命令
    //    0x66,0x00,0x00,// 起始地址102
    //    0xA8,// 区域代码 
    //    0x02,0x00 //读取长度     //   请求一个Float占2个字节 
    //};

    //socket.Send(bytes);

     暂时以这种方式来处理  
    //byte[] respBytes = new byte[15];
    //socket.Receive(respBytes);

    //for (int i = 11; i < respBytes.Length; i++)
    //{
    //    //小端处理,每4个字节作为一组才是数据
    //    byte[] dataBytes = new byte[4];
    //    dataBytes[0] = respBytes[i];
    //    dataBytes[1] = respBytes[++i];
    //    dataBytes[2] = respBytes[++i];
    //    dataBytes[3] = respBytes[++i];
    //    Console.WriteLine(BitConverter.ToSingle(dataBytes,0));//字节转换成浮点数
    //}

    #endregion

    #region 3、 读位数据,即X102开始的1个位(true/false)

    byte[] bytes = new byte[]
    {
        0x50,0x00,//请求副头部,固定50 00
        0x00,// 可变,根据PLC的设置
        0xFF,//PLC编号,固定值
        0xFF,0x03,//目标模块IO编号,固定FF 03
        0x00,// 可变 ,目标模块站号
        0x0C,0x00,  // 剩余字节长度
        0x0A,0x00, //PLC响应超时时间,以250ms为单位计算
        0x01,0x4,// 成批读出 ,主命令
        0x01,0x00,// 子命令 - 位操作 
        0x02,0x01,0x00,// 起始地址,占3个字节,地址是102,用000102表示,因为是小端,前后颠倒,变成了020100
        0x9C,// 区域代码   X元件就是9C
        0x01,0x00 //读取长度     
    };
    socket.Send(bytes);

    byte[] respBytes = new byte[12];
    socket.Receive(respBytes);
    var obj = respBytes;
    string binaryStr = Convert.ToString(respBytes[11], 2).PadLeft(8, '0');//左移8位
    List<string> tempList = new List<string>();
    // 每转换一次可以拿两个位信息
    tempList.Add(binaryStr.Substring(0, 4));
    tempList.Add(binaryStr.Substring(4));

    for (int i = 0; i < 1; i++)
    {
        Console.WriteLine(tempList[i] == "0001");
    }

    #endregion

}

 4、 读字数据,即读取X100地址的int16类型数据,short或ushort类型的,如-79,35

 /// <summary>
 /// A-3E报文测试
 /// </summary>
 private static void MCTestA3E()
 {
     // 连接
     Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     socket.Connect("192.168.1.7", 6000);

     #region 1、 读字数据,读取D100开始的2个数据, short/ushort

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 网络号,可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度,当前字节往后
     //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
     //    0x01,0x04,// 成批读出,主命令
     //    0x00,0x00,// 字操作,子命令
     //    0x64,0x00,0x00,// 起始地址
     //    0xA8,// 区域代码 
     //    0x02,0x00 //读取长度     //  如果请求一个Float   2;2Float  4
     //};

     //socket.Send(bytes);

      暂时以这种方式来处理  
     //byte[] respBytes = new byte[15];
     //socket.Receive(respBytes);

     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    // 小端处理,每2个字节作为一个数据
     //    byte[] dataBytes = new byte[2];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
     //}

     #endregion

     #region 2、 读字数据,读取D102开始的1个数据, float类型

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 网络号,可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度,当前字节往后
     //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
     //    0x01,0x04,// 成批读出,主命令
     //    0x00,0x00,// 字操作,子命令
     //    0x66,0x00,0x00,// 起始地址102
     //    0xA8,// 区域代码 
     //    0x02,0x00 //读取长度     //   请求一个Float占2个字节 
     //};

     //socket.Send(bytes);

      暂时以这种方式来处理  
     //byte[] respBytes = new byte[15];
     //socket.Receive(respBytes);

     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    //小端处理,每4个字节作为一组才是数据
     //    byte[] dataBytes = new byte[4];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    dataBytes[2] = respBytes[++i];
     //    dataBytes[3] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToSingle(dataBytes,0));//字节转换成浮点数
     //}

     #endregion

     #region 3、 读位数据,即X102开始的1个位(true/false)

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变 ,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度
     //    0x0A,0x00, //PLC响应超时时间,以250ms为单位计算
     //    0x01,0x4,// 成批读出 ,主命令
     //    0x01,0x00,// 子命令 - 位操作 
     //    0x02,0x01,0x00,// 起始地址,占3个字节,地址是102,用000102表示,因为是小端,前后颠倒,变成了020100
     //    0x9C,// 区域代码   X元件就是9C
     //    0x01,0x00 //读取长度     
     //};
     //socket.Send(bytes);

     //byte[] respBytes = new byte[12];
     //socket.Receive(respBytes);
     //var obj = respBytes;
     //string binaryStr = Convert.ToString(respBytes[11], 2).PadLeft(8, '0');//左移8位
     //List<string> tempList = new List<string>();
      每转换一次可以拿两个位信息
     //tempList.Add(binaryStr.Substring(0, 4));
     //tempList.Add(binaryStr.Substring(4));

     //for (int i = 0; i < 1; i++)
     //{
     //    Console.WriteLine(tempList[i] == "0001");
     //}

     #endregion

     #region 4、 读字数据,即读取X100地址的int16类型数据,short或ushort类型的,如-79,35

     byte[] bytes = new byte[]
     {
         0x50,0x00,
         0x00,// 可变,根据PLC的设置
         0xFF,
         0xFF,0x03,
         0x00,// 可变 
         0x0C,0x00,  // 剩余字节长度
         0x0A,0x00, 
         0x01,0x4,// 成批读出,主操作命令
         0x00,0x00,// 子命令 - 字操作 
         0x00,0x01,0x00,// 起始地址,100用3个字节表示就是000100,小端处理前后倒置就是000100
         0x9C,// 区域代码   X
         0x01,0x00 //读取长度     
     };
     socket.Send(bytes);

     byte[] respBytes = new byte[13];
     socket.Receive(respBytes);
     var obj = respBytes;
     for (int i = 11; i < respBytes.Length; i++)
     {
         // 小端处理
         byte[] dataBytes = new byte[2];
         dataBytes[0] = respBytes[i];
         dataBytes[1] = respBytes[++i];
         Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
     }

     #endregion
 }

5、写入字数据,即按字写入地址为D100开始的2个数据short类型的,即111/222

  /// <summary>
  /// A-3E报文测试
  /// </summary>
  private static void MCTestA3E()
  {
      // 连接
      Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      socket.Connect("192.168.1.7", 6000);

      #region 1、 读字数据,读取D100开始的2个数据, short/ushort

      //byte[] bytes = new byte[]
      //{
      //    0x50,0x00,//请求副头部,固定50 00
      //    0x00,// 网络号,可变,根据PLC的设置
      //    0xFF,//PLC编号,固定值
      //    0xFF,0x03,//目标模块IO编号,固定FF 03
      //    0x00,// 可变,目标模块站号
      //    0x0C,0x00,  // 剩余字节长度,当前字节往后
      //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
      //    0x01,0x04,// 成批读出,主命令
      //    0x00,0x00,// 字操作,子命令
      //    0x64,0x00,0x00,// 起始地址
      //    0xA8,// 区域代码 
      //    0x02,0x00 //读取长度     //  如果请求一个Float   2;2Float  4
      //};

      //socket.Send(bytes);

       暂时以这种方式来处理  
      //byte[] respBytes = new byte[15];
      //socket.Receive(respBytes);

      //for (int i = 11; i < respBytes.Length; i++)
      //{
      //    // 小端处理,每2个字节作为一个数据
      //    byte[] dataBytes = new byte[2];
      //    dataBytes[0] = respBytes[i];
      //    dataBytes[1] = respBytes[++i];
      //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
      //}

      #endregion

      #region 2、 读字数据,读取D102开始的1个数据, float类型

      //byte[] bytes = new byte[]
      //{
      //    0x50,0x00,//请求副头部,固定50 00
      //    0x00,// 网络号,可变,根据PLC的设置
      //    0xFF,//PLC编号,固定值
      //    0xFF,0x03,//目标模块IO编号,固定FF 03
      //    0x00,// 可变,目标模块站号
      //    0x0C,0x00,  // 剩余字节长度,当前字节往后
      //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
      //    0x01,0x04,// 成批读出,主命令
      //    0x00,0x00,// 字操作,子命令
      //    0x66,0x00,0x00,// 起始地址102
      //    0xA8,// 区域代码 
      //    0x02,0x00 //读取长度     //   请求一个Float占2个字节 
      //};

      //socket.Send(bytes);

       暂时以这种方式来处理  
      //byte[] respBytes = new byte[15];
      //socket.Receive(respBytes);

      //for (int i = 11; i < respBytes.Length; i++)
      //{
      //    //小端处理,每4个字节作为一组才是数据
      //    byte[] dataBytes = new byte[4];
      //    dataBytes[0] = respBytes[i];
      //    dataBytes[1] = respBytes[++i];
      //    dataBytes[2] = respBytes[++i];
      //    dataBytes[3] = respBytes[++i];
      //    Console.WriteLine(BitConverter.ToSingle(dataBytes,0));//字节转换成浮点数
      //}

      #endregion

      #region 3、 读位数据,即X102开始的1个位(true/false)

      //byte[] bytes = new byte[]
      //{
      //    0x50,0x00,//请求副头部,固定50 00
      //    0x00,// 可变,根据PLC的设置
      //    0xFF,//PLC编号,固定值
      //    0xFF,0x03,//目标模块IO编号,固定FF 03
      //    0x00,// 可变 ,目标模块站号
      //    0x0C,0x00,  // 剩余字节长度
      //    0x0A,0x00, //PLC响应超时时间,以250ms为单位计算
      //    0x01,0x4,// 成批读出 ,主命令
      //    0x01,0x00,// 子命令 - 位操作 
      //    0x02,0x01,0x00,// 起始地址,占3个字节,地址是102,用000102表示,因为是小端,前后颠倒,变成了020100
      //    0x9C,// 区域代码   X元件就是9C
      //    0x01,0x00 //读取长度     
      //};
      //socket.Send(bytes);

      //byte[] respBytes = new byte[12];
      //socket.Receive(respBytes);
      //var obj = respBytes;
      //string binaryStr = Convert.ToString(respBytes[11], 2).PadLeft(8, '0');//左移8位
      //List<string> tempList = new List<string>();
       每转换一次可以拿两个位信息
      //tempList.Add(binaryStr.Substring(0, 4));
      //tempList.Add(binaryStr.Substring(4));

      //for (int i = 0; i < 1; i++)
      //{
      //    Console.WriteLine(tempList[i] == "0001");
      //}

      #endregion

      #region 4、 读字数据,即读取X100地址的int16类型数据,short或ushort类型的,如-79,35

      //byte[] bytes = new byte[]
      //{
      //    0x50,0x00,
      //    0x00,// 可变,根据PLC的设置
      //    0xFF,
      //    0xFF,0x03,
      //    0x00,// 可变 
      //    0x0C,0x00,  // 剩余字节长度
      //    0x0A,0x00, 
      //    0x01,0x4,// 成批读出,主操作命令
      //    0x00,0x00,// 子命令 - 字操作 
      //    0x00,0x01,0x00,// 起始地址,100用3个字节表示就是000100,小端处理前后倒置就是000100
      //    0x9C,// 区域代码   X
      //    0x01,0x00 //读取长度     
      //};
      //socket.Send(bytes);

      //byte[] respBytes = new byte[13];
      //socket.Receive(respBytes);
      //var obj = respBytes;
      //for (int i = 11; i < respBytes.Length; i++)
      //{
      //    // 小端处理
      //    byte[] dataBytes = new byte[2];
      //    dataBytes[0] = respBytes[i];
      //    dataBytes[1] = respBytes[++i];
      //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
      //}

      #endregion

      #region 5、写入字数据,即按字写入地址为D100开始的2个数据short类型的,即111/222

      byte[] bytes = new byte[]
      {
          0x50,0x00,
          0x00,// 可变,根据PLC的设置
          0xFF,
          0xFF,0x03,
          0x00,// 可变 
          0x10,0x00,  // 剩余字节长度
          0x0A,0x00, 
          0x01,0x14,// 成批写入
          0x00,0x00,// 字操作 
          0x64,0x00,0x00,// 起始地址
          0xA8,// 区域代码 
          0x02,0x00, //写入长度
          //具体的数据值,111转换成16进制就是6f,小端处理就是6f00,222小端处理就是de00
          (byte)(111%256),//低位
          (byte)(111/256%256),//高位
          (byte)(222%256),
          (byte)(222/256%256)
      };
      socket.Send(bytes);

      byte[] respBytes = new byte[11];
      socket.Receive(respBytes);
      var obj = respBytes;
      //最后2个字节是状态码,0X00,0X00是状态码,如果是0,表示成功
      for (int i = 9; i < respBytes.Length; i++)
      {
          // 小端处理,每2个字节作为一个数据
          byte[] dataBytes = new byte[2];
          dataBytes[0] = respBytes[i];
          dataBytes[1] = respBytes[++i];
          if (BitConverter.ToInt16(dataBytes,0) == 0)
          {
              Console.WriteLine("写入成功");
          }
      }

      #endregion
  }

 6、写入字数据,即按字写入地址为D102开始的1个数据,即float类型的13.9

 /// <summary>
 /// A-3E报文测试
 /// </summary>
 private static void MCTestA3E()
 {
     // 连接
     Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     socket.Connect("192.168.1.7", 6000);

     #region 1、 读字数据,读取D100开始的2个数据, short/ushort

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 网络号,可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度,当前字节往后
     //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
     //    0x01,0x04,// 成批读出,主命令
     //    0x00,0x00,// 字操作,子命令
     //    0x64,0x00,0x00,// 起始地址
     //    0xA8,// 区域代码 
     //    0x02,0x00 //读取长度     //  如果请求一个Float   2;2Float  4
     //};

     //socket.Send(bytes);

      暂时以这种方式来处理  
     //byte[] respBytes = new byte[15];
     //socket.Receive(respBytes);

     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    // 小端处理,每2个字节作为一个数据
     //    byte[] dataBytes = new byte[2];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
     //}

     #endregion

     #region 2、 读字数据,读取D102开始的1个数据, float类型

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 网络号,可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度,当前字节往后
     //    0x0A,0x00,//PLC响应超时时间,以250ms为单位计算
     //    0x01,0x04,// 成批读出,主命令
     //    0x00,0x00,// 字操作,子命令
     //    0x66,0x00,0x00,// 起始地址102
     //    0xA8,// 区域代码 
     //    0x02,0x00 //读取长度     //   请求一个Float占2个字节 
     //};

     //socket.Send(bytes);

      暂时以这种方式来处理  
     //byte[] respBytes = new byte[15];
     //socket.Receive(respBytes);

     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    //小端处理,每4个字节作为一组才是数据
     //    byte[] dataBytes = new byte[4];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    dataBytes[2] = respBytes[++i];
     //    dataBytes[3] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToSingle(dataBytes,0));//字节转换成浮点数
     //}

     #endregion

     #region 3、 读位数据,即X102开始的1个位(true/false)

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,//请求副头部,固定50 00
     //    0x00,// 可变,根据PLC的设置
     //    0xFF,//PLC编号,固定值
     //    0xFF,0x03,//目标模块IO编号,固定FF 03
     //    0x00,// 可变 ,目标模块站号
     //    0x0C,0x00,  // 剩余字节长度
     //    0x0A,0x00, //PLC响应超时时间,以250ms为单位计算
     //    0x01,0x4,// 成批读出 ,主命令
     //    0x01,0x00,// 子命令 - 位操作 
     //    0x02,0x01,0x00,// 起始地址,占3个字节,地址是102,用000102表示,因为是小端,前后颠倒,变成了020100
     //    0x9C,// 区域代码   X元件就是9C
     //    0x01,0x00 //读取长度     
     //};
     //socket.Send(bytes);

     //byte[] respBytes = new byte[12];
     //socket.Receive(respBytes);
     //var obj = respBytes;
     //string binaryStr = Convert.ToString(respBytes[11], 2).PadLeft(8, '0');//左移8位
     //List<string> tempList = new List<string>();
      每转换一次可以拿两个位信息
     //tempList.Add(binaryStr.Substring(0, 4));
     //tempList.Add(binaryStr.Substring(4));

     //for (int i = 0; i < 1; i++)
     //{
     //    Console.WriteLine(tempList[i] == "0001");
     //}

     #endregion

     #region 4、 读字数据,即读取X100地址的int16类型数据,short或ushort类型的,如-79,35

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,
     //    0x00,// 可变,根据PLC的设置
     //    0xFF,
     //    0xFF,0x03,
     //    0x00,// 可变 
     //    0x0C,0x00,  // 剩余字节长度
     //    0x0A,0x00, 
     //    0x01,0x4,// 成批读出,主操作命令
     //    0x00,0x00,// 子命令 - 字操作 
     //    0x00,0x01,0x00,// 起始地址,100用3个字节表示就是000100,小端处理前后倒置就是000100
     //    0x9C,// 区域代码   X
     //    0x01,0x00 //读取长度     
     //};
     //socket.Send(bytes);

     //byte[] respBytes = new byte[13];
     //socket.Receive(respBytes);
     //var obj = respBytes;
     //for (int i = 11; i < respBytes.Length; i++)
     //{
     //    // 小端处理
     //    byte[] dataBytes = new byte[2];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    Console.WriteLine(BitConverter.ToInt16(dataBytes,0));
     //}

     #endregion

     #region 5、写入字数据,即按字写入地址为D100开始的2个数据short类型的,即111/222

     //byte[] bytes = new byte[]
     //{
     //    0x50,0x00,
     //    0x00,// 可变,根据PLC的设置
     //    0xFF,
     //    0xFF,0x03,
     //    0x00,// 可变 
     //    0x10,0x00,  // 剩余字节长度
     //    0x0A,0x00, 
     //    0x01,0x14,// 成批写入
     //    0x00,0x00,// 字操作 
     //    0x64,0x00,0x00,// 起始地址
     //    0xA8,// 区域代码 
     //    0x02,0x00, //写入长度
     //    //具体的数据值,111转换成16进制就是6f,小端处理就是6f00,222小端处理就是de00
     //    (byte)(111%256),//低位
     //    (byte)(111/256%256),//高位
     //    (byte)(222%256),
     //    (byte)(222/256%256)
     //};
     //socket.Send(bytes);

     //byte[] respBytes = new byte[11];
     //socket.Receive(respBytes);
     //var obj = respBytes;
     最后2个字节是状态码,0X00,0X00是状态码,如果是0,表示成功
     //for (int i = 9; i < respBytes.Length; i++)
     //{
     //    // 小端处理,每2个字节作为一个数据
     //    byte[] dataBytes = new byte[2];
     //    dataBytes[0] = respBytes[i];
     //    dataBytes[1] = respBytes[++i];
     //    if (BitConverter.ToInt16(dataBytes,0) == 0)
     //    {
     //        Console.WriteLine("写入成功");
     //    }
     //}

     #endregion

     #region 6、写入字数据,即按字写入地址为D102开始的1个数据,即float类型的13.9

     float value = 13.9f;
     byte[] bytes = new byte[]
     {
         0x50,0x00,
         0x00,// 可变,根据PLC的设置
         0xFF,
         0xFF,0x03,
         0x00,// 可变 
         0x10,0x00,  // 剩余字节长度
         0x0A,0x00,
         0x01,0x14,// 成批写入
         0x00,0x00,// 字操作 
         0x66,0x00,0x00,// 起始地址,占3个字节,102转换成16进制的小端格式是660000
         0xA8,// 区域代码 
         0x02,0x00, //写入长度,float的长度是2个
         //具体的数据值,float占4个字节,分别是66,66,5e,41
         BitConverter.GetBytes(value)[0],
         BitConverter.GetBytes(value)[1],
         BitConverter.GetBytes(value)[2],
         BitConverter.GetBytes(value)[3]
     };
     socket.Send(bytes);

     byte[] respBytes = new byte[11];
     socket.Receive(respBytes);
     var obj = respBytes;
     //最后2个字节是状态码,0X00,0X00是状态码,如果是0,表示成功
     for (int i = 9; i < respBytes.Length; i++)
     {
         // 小端处理,每2个字节作为一个数据
         byte[] dataBytes = new byte[2];
         dataBytes[0] = respBytes[i];
         dataBytes[1] = respBytes[++i];
         if (BitConverter.ToInt16(dataBytes,0) == 0)
         {
             Console.WriteLine("写入成功");
         }
     }

     #endregion
 }

5、小结

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1463904.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Security学习(六)——配置多个Provider(存在两种认证规则)

前言 《Spring Security学习&#xff08;五&#xff09;——账号密码的存取》一文已经能满足一般应用的情况。但实际商业应用也会存在如下的情况&#xff1a;用户提交的账号密码&#xff0c;能在本地的保存的账号密码匹配上&#xff0c;或者能在远端服务认证中匹配上&#xff…

171基于matlab的随机共振微弱信号检测

基于matlab的随机共振微弱信号检测&#xff0c;随机共振描述了过阻尼布朗粒子受周期性信号和随机噪声的共同作用下,在非线性双稳态系统中所发生的跃迁现象. 随机共振可用于弱信号的检测。程序已调通&#xff0c;可直接运行。

Linux用到的命令

1 压缩文件 tar -czf wonderful.tar.gz pm 这个命令的作用就是创建一个以.tar.gz结尾的包文件&#xff0c;然后调用gzip程序将当前目录下的pm文件夹压缩到这个以.tar.gz结尾的文件里面去

Colmap学习笔记(一):Pixelwise View Selection for Unstructured Multi-View Stereo论文阅读

1. 摘要 本文展示一套MVS系统&#xff0c;该系统利用非结构化的图片实现鲁棒且稠密的建模。本文的主要贡献是深度和法向量的联合估计&#xff0c;用光度和几何先验进行像素筛选&#xff0c;多视图几何一致项&#xff0c;该项同时进行精修和基于图片的深度和法向量的融合。在标…

C2-1.6 Dropout正则化——提高泛化能力

C2-1.6 Dropout正则化——提高泛化能力 1、参考书籍 2、什么是Dropout正则化 以图一为例&#xff1a; 假设在训练图一所示的神经网络&#xff0c;它存在过拟合&#xff08;模型过于复杂情况&#xff09;&#xff0c;dropout 会遍历网络的每一层&#xff08;每一层设置的阈值不…

StarRocks加速查询——低基数全局字典

前言 StarRocks-2.0引入了低基数全局字典&#xff0c;可以通过全局字典将字符串的相关操作转换成整型相关操作&#xff0c;极大提升了查询性能。StarRocks 2.0后的版本默认会开启低基数字典优化。 一、低基数字典 对于利用整型替代字符串进行处理&#xff0c;通常使用字典编码…

Docker之查看并获取最新Ubuntu镜像(十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

在vue3中使用canvas实现雨滴效果

在vue3中使用canvas实现雨滴效果 这是封装的一个组件DotAndRain&#xff08; &#xff09; <script setup> import { ref, onMounted } from "vue"; import { onUnmounted } from "vue";let animationFrameId null;const el ref(null); let canv…

Java零基础 - 赋值运算符

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

redis入门指南

文章目录 Redis概述Redis基本数据类型Redis与MySQL的区别以及使用场景如何保持双写一致性&#xff08;缓存一致性&#xff09;1. 延迟双删2. 分布式锁&#xff08;强一致性时使用&#xff09;3. 中间件 Redis持久化机制RDB&#xff08;redis database&#xff09;AOF&#xff0…

Python算法100例-1.10 数制转换

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.字符与数字进行转换6.其他数制转换成十进制7.十进制转换成其他数制8.完整的程序 1&#xff0e;问题描述 给定一个M进制的数x&#xff0c;实现对x向任意一个非M进制…

SwiftUI 集合视图(Grid)拖放交换 Cell 的极简实现

概览 自从 SwiftUI 横空出世那天起&#xff0c;小伙伴们都感受到了它惊人的简单与便捷。而在本课中&#xff0c;我们将会用一个小“栗子”更直观的让大家体验到它无与伦比简洁的描述性特质&#xff1a; 如上图所示&#xff0c;我们在 SwiftUI 中实现了 Grid 中拖放交换 Cell 的…

开开开开开,干

大家新年快乐&#xff0c;开工啦啦啦啦 其实每天很多人都会问&#xff1a; 有协同过滤的算法吗&#xff0c;有的&#xff0c;可以给你解释原理… 有的小伙伴只开了一部分逻辑&#xff0c;我要实现用户可以下单功能 但是细细考虑下单&#xff0c;需要现有用户&#xff0c;维护…

[Git] 配置Access Token 解决Github 认证弹窗

[Git] 配置Access Token 解决Github 认证弹窗 1. 前言2. 解决2.1 申请Personal Access Token2.2. 配置Token2.3. 授权激活Token 博主热门文章推荐&#xff1a; 1. 前言 最近从bitbucket切换到了Github Enterprise, 刚使用几次发现 每次操作 都有弹窗认证&#xff0c; 虽然手动点…

波奇学Linux:进程通信管道

进程通信 管道&#xff1a;基于文件级别的单向通信 创建父子进程&#xff0c;使得进程的struct file*fd_array[]的文件描述符指向同一个struct file文件&#xff0c;这个文件是内存级文件。 父进程关写端&#xff0c;子进程再关闭读端。实现单向通信 子进程写入&#xff0c;父进…

个人博客搭建

使用彩虹云主机百度云域名WordPress 下载WordPress https://cn.wordpress.org/ 购买主机 购买彩虹云主机&#xff0c;购买香港高防主机https://www.cccyun.net/ 购买之后点击 管理 进入后点 击前往控制面板 -> 一键登录控制面板 可进入控制面板。 选择文件管理 在线…

cuda加速:memory coalescing,Bank Conflicts

cuda加速&#xff1a;memory coalescing 1.memory coalescing2.Shared Memory Bank Conflicts参考文献 1.memory coalescing 参考【1】中给出的定义&#xff1a;一个warp中&#xff0c;thread 0到thread 31访问连续的内存空间&#xff0c;则这些线程的访问被合并为一次访问。 …

2.21学习总结

1.【模板】ST 表 2.Balanced Lineup G 3.景区导游 4.最近公共祖先&#xff08;LCA&#xff09; 倍增思想&#xff1a;主要用于LCA问题&#xff0c;RMQ问题。在进行 递推 时&#xff0c;如果 状态空间很大&#xff0c;通常的 线性递推 无法满足 时间 与 空间复杂度 的要求&…

BabylonJS 6.0文档 Deep Dive 动画(一):动画介绍

1. 动画介绍 无论动画如何实现&#xff0c;它都必须考虑所需的动作、时间、产生所需流动性所需的帧数以及序列中的关键点。这个介绍应该有助于理解Babylon.js是如何进行动画的&#xff0c;以及它们是如何实现的。 动画由一系列图像、帧生成&#xff0c;这些图像、帧一个接一个地…

做跨境电商,为什么要建独立站,2024年的机会在哪里?一次性讲清楚...

做跨境电商&#xff0c; 是选择依托第三方平台&#xff1f; 还是自建独立网站&#xff1f; 01 什么是自建独立站 最简单的说法&#xff1a;独立站对于我们跨境电商这个行业来说&#xff0c;就是那些不是主流平台的网站&#xff0c;是某个企业或者个人自己做和运营的搭建电商…