到目前为止,还没有网上有哪个文章有我如此的报文分析,操作实例,一大批都是抄来抄去,没有截图,没有说明,没有实例,有卵用呀,仅以此文章献给最爱的粉丝,希望对各位大师有些启示。
原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。
原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。
原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。
1、A-1E协议回顾
上节文章完成了下面几项操作:
1、读取D100地址开始的2个int类型数据
2、 通过A1E进行D102的双字 DWord(Float) 读取,即读取float类型--4Byte
3、通过A1E进行位的读取M16,M区的地址要转换成16进制,即读取bool类型数据
4、通过A1E进行字的写入,即向 D20,D21写入34,45
5、通过A1E向 D30 写入一个Float数据24.5,一个float占4个字节
通过5个操作实例掌握了报文的结构,发送和接收都有报文的结构,但那是通过工具软件“网络调试助手”实现的,这节来通过C#代码组成报文结构并测试效果,需要用到vs2022开发工具,字节数组,socket通信等知识。
2、启动mc服务器
3、创建项目方案
打开VS2022,创建控制台项目
4、报文组装与测试
1、读取D100地址开始的2个int类型数据
发送:01 FF 0A 00 64 00 00 00 20 44 02 00
响应:81 00 19 00 26 00
2、 通过A1E进行D102的双字 DWord(Float) 读取,即读取float类型--4Byte
发送:01 FF 0A 00 66 00 00 00 20 44 04 00
接收:81 00 33 33 35 42 00 00 00 00
3、通过A1E进行位的读取M16,M区的地址要转换成16进制,即读取bool类型数据
发送:00 FF 0A 00 10 00 00 00 20 4D 01 00
接收:80 00 10
4、通过A1E进行字的写入,即向 D20,D21写入34,45
发送:03 FF 0A 00 14 00 00 00 20 44 02 00 22 00 2D 00
接收:83 00
5、通过A1E向 D30 写入一个Float数据24.5,一个float占4个字节
发送:03 FF 0A 00 1E 00 00 00 20 44 02 00 00 00 C4 41
接收:83 00
6、完整代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;namespace MitSUBISHI.MCProtocol.Test
{internal class Program{static void Main(string[] args){MCTestA1E(); Console.WriteLine("执行完成!");Console.ReadKey();}private static void MCTestA1E(){// 连接Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);socket.Connect("192.168.1.3", 6000);#region 1、通过A1E进行D100地址按字进行读取2个,即读取int类型 //int len = 2;//byte[] bytes = new byte[] {// 0x01,// 0xFF,0x0A,0x00,// 0x64,0x00,0x00,0x00, // 起始地址// 0x20,0x44, // 存储区 // (byte)(len%256),// (byte)(len/256%256) // 读取长度// };//socket.Send(bytes);//byte[] respBytes = new byte[len * 2 + 2];//socket.Receive(respBytes);//for (int i = 2; i < respBytes.Length; i++)//{// //每2个字节一组// byte[] temp = new byte[2];// temp[0] = respBytes[i];// temp[1] = respBytes[++i];// Console.WriteLine(BitConverter.ToInt16(temp, 0));//字节数组转换成int16数据//}#endregion#region 2、通过A1E进行D102的双字 DWord(Float) 读取,即读取float类型--4Byte //int len = 2;//byte[] bytes = new byte[] {// 0x01,//0x01代表按批量字// 0xFF,0x0A,0x00,// 0x66,0x00,0x00,0x00, // 起始地址// 0x20,0x44, // 存储区 // (byte)(len*2%256),// (byte)(len*2/256%256) // 读取长度//};//socket.Send(bytes);//byte[] respBytes = new byte[len * 2 * 2 + 2];//socket.Receive(respBytes);//for (int i = 2; i < respBytes.Length; i++)//{// //每4个字节一组// byte[] temp = new byte[4];// temp[0] = respBytes[i];// temp[1] = respBytes[++i];// temp[2] = respBytes[++i];// temp[3] = respBytes[++i];// Console.WriteLine(BitConverter.ToSingle(temp, 0));//字节数组转换成float数据//}#endregion#region 3、通过A1E进行位的读取M16,M区的地址要转换成16进制,即读取bool类型数据//int len = 1;//byte[] bytes = new byte[] {// 0x00, // 代表批量位// 0xFF,0x0A,0x00,// 0x10,0x00,0x00,0x00, // 起始地址// 0x20,0x4D, // 存储区 // (byte)(len%256),// (byte)(len/256%256) // 读取长度//};//socket.Send(bytes);最终的数据长度是多少个字节 //int readLen = (int)Math.Ceiling(len * 1.0 / 2);//byte[] respBytes = new byte[readLen + 2];//socket.Receive(respBytes);//string binaryStr = "";//List<string> tempList = new List<string>();//for (int i = 2; i < respBytes.Length; i++)//{// binaryStr = Convert.ToString(respBytes[i], 2).PadLeft(8, '0');// // 每转换一次可以拿两个位信息// tempList.Add(binaryStr.Substring(0, 4));// tempList.Add(binaryStr.Substring(4));//}//for (int i = 0; i < len; i++)//{// Console.WriteLine(tempList[i] == "0001");//}#endregion#region 4、通过A1E进行字的写入,即向 D20,D21写入34,45//int len = 2;//short v1 = 34, v2 = 45;//byte[] bytes = new byte[] {// 0x03, // 代表批量位字// 0xFF,0x0A,0x00,// 0x14,0x00,0x00,0x00, // 起始地址// 0x20,0x44, // 存储区 // // 写入长度// (byte)(len%256),//低位// (byte)(len/256%256), //高位// //第一个数据// (byte)(v1%256),//低位// (byte)(v1/256%256),//高位// //第二个数据// (byte)(v2%256),// (byte)(v2/256%256)//};//socket.Send(bytes);//int readLen = (int)Math.Ceiling(len * 1.0 / 2);//byte[] respBytes = new byte[2];//socket.Receive(respBytes);//var obj = respBytes;//if (Convert.ToInt16(respBytes[1]) == 0)//{// Console.WriteLine("写入成功");//}#endregion#region 5、通过A1E向 D30 写入一个Float数据24.5,一个float占4个字节int len = 1; // 一个值是4个字节 2个寄存器float value = 24.5f;byte[] bytes = new byte[] {0x03, // 代表批量字0xFF,0x0A,0x00,0x1E,0x00,0x00,0x00, // 起始地址0x20,0x44, // 存储区 (byte)(len*2%256),(byte)(len*2/256%256), // 写入长度BitConverter.GetBytes(value)[0],BitConverter.GetBytes(value)[1],BitConverter.GetBytes(value)[2],BitConverter.GetBytes(value)[3]};socket.Send(bytes);int readLen = (int)Math.Ceiling(len * 1.0 / 2);byte[] respBytes = new byte[2];socket.Receive(respBytes);var obj = respBytes;if (Convert.ToInt16(respBytes[1]) == 0){Console.WriteLine("写入成功");}#endregion}}
}
5、小结
到目前为止,还没有网上有哪个文章有我如此的报文分析,操作实例,一大批都是抄来抄去,仅以此文章献给最爱的粉丝,希望对各位大师有些启示。
原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。
原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。
原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。