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

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、小结

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

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

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

three.js 3D可视化地图

threejs地图 可视化地图——three.js实现 this.provinceInfo document.getElementById(provinceInfo); // 渲染器 this.renderer new THREE.WebGLRenderer({antialias: true }); this.renderer.setSize(window.innerWidth, window.innerHeight); this.container.appendChild…

GZ036 区块链技术应用赛项赛题第6套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;6卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 近年来&#xff0c;食品安全问题层出不穷&#xff0c;涉及到各种食品类别&#xff0c;如肉类、水果、蔬菜等。食品安全事…

SQL32 截取出年龄(substring_index函数的用法)

代码 select substring_index(substring_index(profile,,,3),,,-1) as age ,count(device_id) from user_submit group by age知识点 substring_index(FIELD, sep, n)可以将字段FIELD按照sep分隔&#xff1a; (1).当n大于0时取第n个分隔符(n从1开始)之前的全部内容&#xff1…

【Vision Pro 应用分享】Make It Spatial——将普通照片转化为Spatial空间照片,以在Vision Pro视界眼镜上观看3D效果

该应用目前在Mac App Store上免费提供 下载地址:‎Make It Spatial on the Mac App Store Read reviews, compare customer ratings, see screenshots, and learn more about Make It Spatial. Download Make It Spatial for macOS 14.0 or later and enjoy it on your Mac.h…

BUGKU-WEB 变量1

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; flag In the variable !<?php error_reporting(0); include "flag1.php"; highlight_file(__file__); if(isset($_GET[args])){$args $_GET[args];if(!preg_match("/^\w$/",$args…

Airtest-Selenium实操小课:爬取新榜数据

1. 前言 最近看到群里很多小伙伴都在用Airtest-Selenium做一些web自动化的尝试&#xff0c;正好趁此机会&#xff0c;我们也出几个关于web自动化的实操小课&#xff0c;仅供大家参考~ 今天跟大家分享的是一个非常简单的爬取网页信息的小练习&#xff0c;在百度找到新榜网页&a…

前端工程化面试题 | 09.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

从零开始学习数据结构—【链表】—【探索环形链的设计之美】

环形链表 文章目录 环形链表1.结构图2.具体实现2.1.环形链表结构2.2.头部添加数据2.2.1.具体实现2.2.2.测试添加数据 2.3.尾部添加数据2.3.1.具体实现2.3.2.添加测试数据 2.4.删除头部数据2.4.1.具体实现2.4.2.测试删除数据 2.5.删除尾部数据2.5.1.具体实现2.5.2.测试删除数据 …

PFA洗气瓶配空气采样泵用PFA气体吸收瓶的特点

PFA洗气瓶是一种洗去气体中杂质的器皿&#xff0c;是将不纯气体通过选定的适宜液体介质鼓泡吸收&#xff08;溶解或由于发生化学反应&#xff09;&#xff0c;从而洗去杂质气体&#xff0c;以达净化气体的目的。在设计时&#xff0c;四氟球的周围都布满小孔。一般情况下&#x…

【教学类-19-10】20240214《ABAB式-规律黏贴18格-手工纸15*15CM-一页3种图案,AB一组样板,纵向、有边框》(中班)

背景需求 利用15*15CM手工纸制作AB色块手环&#xff08;手工纸自带色彩&#xff09;&#xff0c;一页3个图案&#xff0c;2条为一组&#xff0c;画图案&#xff0c;黏贴成一个手环。 素材准备 代码展示 # # 作者&#xff1a;阿夏 # 时间&#xff1a;2024年2月14日 # 名称&…

LeetCode刷题计划---day2

07 #include <iostream> #include <iomanip> // 头文件用于控制输出格式 using namespace std;int main() {const int n 5; // 等级个数double grade[n] {4.0, 3.0, 2.0, 1.0, 0.0}; // 每个等级对应的分数string input;while (getline(cin, input)) { // 读入一…

我国纯自研水陆两栖大飞机,鲲龙AG600M完成高寒试飞任务

据航空工业官微介绍&#xff0c;近期我国自主研制的大型水陆两栖飞机“鲲龙”AG600M在海拉尔完成最后一项高寒试飞任务。 其动力装置系统、燃油系统、液压系统、飞控系统、航电系统、起落架系统等关键系统通过了高寒地面试验和试飞验证&#xff0c;可满足我国全疆域范围内的森…

如何将阿里云服务器迁移

&#x1f4d1;前言 本文主要是如何将阿里云服务器迁移实现数据转移的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️** &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日…

【hcie-cloud】【30】华为云Stack应用安全于防护

文章目录 前言Web技术基础和常见Web漏洞Web技术Web系统组成URL结构Web后端技术HTTP/HTTPS协议Cookie/Session简介OWASP TOP 10OWASP TOP 10 2021年版访问控制失效 - 越权访问控制失效 - 跨站请求伪造&#xff08;CSRF&#xff09;URL不安全跳转应用安全法律法规及行业规范 Web应…

React 更改程序入口点(index.js文件位置变更)

食用前提示&#xff1a;本文基于已经快速配置好的React环境而作&#xff0c;配置React环境详见拙作&#xff1a;React环境配置-CSDN博客~ 一、了解默认入口点 使用create-react-app快速搭建react环境后&#xff0c;npm start启动程序的默认入口点为/src/index(即src目录下的ind…

【JavaEE】_HTTP请求首行

目录 1. URL 2. 方法 2.1 GET方法 2.2 POST方法 2.3 GET与POST的区别 2.4 低频使用方法 1. URL 在mysql JDBC中已经提到过URL的相关概念&#xff1a; 如需查看有关JDBC更多内容&#xff0c;原文链接如下&#xff1a; 【MySQL】_JDBC编程-CSDN博客 URL用于描述某个资源…

揭秘京东商品背后的秘密:一键获取详细数据,打造全新购物体验

京东商品详情原数据API接口技术详解 一、概述 京东商品详情原数据API接口是京东开放平台提供的一套用于获取商品详细信息的接口。通过调用该接口&#xff0c;第三方开发者可以获取包括商品描述、价格、图片、评价等详细信息&#xff0c;进而在自己的应用或网站中展示给用户&a…

听说解锁字节扣子,能轻松搭建你的私人AI助手!

一、引子 几年前低代码平台推出了&#xff0c;这种概念应该是未来的一种趋势&#xff0c;不过一直没有被大面积推广起来&#xff0c;或许技术方面还不算成熟。不过随着科技的发展&#xff0c;区块链技术、元宇宙技术、AI技术这些对我们来说触不可及的技术也已经走进大家的视线…

自定义类型详解 ----结构体,位段,枚举,联合

目录 结构体 1.不完全声明 2.结构体的自引用 3.定义与初始化 4.结构体内存对齐与结构体类型的大小 结构体嵌套问题 位段 1.什么是位段&#xff1f; 2.位段的内存分配 枚举 1.枚举类型的定义 2.枚举的优点 联合&#xff08;共同体&#xff09; 1.联合体类型的声明以…

PyCharm 自动添加文件头注释

PyCharm 自动添加文件头注释 1. File and Code Templates2. Python FileReferences 1. File and Code Templates File -> Settings -> Editor -> File and Code Templates -> Python Script Reformat according to style & Enable Live Templates Created by…