/// <summary> /// 从地址,长度,是否位读取进行创建读取Ascii格式的MC的核心报文 /// </summary> /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param> /// <param name="length">读取的长度信息</param> /// <param name="isBit">是否进行了位读取操作</param> /// <param name="analysisAddress">对地址分析的委托方法</param> /// <returns>带有成功标识的报文对象</returns> public static OperateResult <byte[]> BuildAsciiReadMcCoreCommand(string address, ushort length, bool isBit, Func <string, OperateResult <MelsecMcDataType, int> > analysisAddress) { OperateResult <MelsecMcDataType, int> analysis = analysisAddress(address); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } byte[] command = new byte[20]; command[0] = 0x30; // 批量读取数据命令 command[1] = 0x34; command[2] = 0x30; command[3] = 0x31; command[4] = 0x30; // 以点为单位还是字为单位成批读取 command[5] = 0x30; command[6] = 0x30; command[7] = isBit ? (byte)0x31 : (byte)0x30; command[8] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[0]; // 软元件类型 command[9] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[1]; command[10] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[0]; // 起始地址的地位 command[11] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[1]; command[12] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[2]; command[13] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[3]; command[14] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[4]; command[15] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[5]; command[16] = MelsecHelper.BuildBytesFromData(length)[0]; // 软元件点数 command[17] = MelsecHelper.BuildBytesFromData(length)[1]; command[18] = MelsecHelper.BuildBytesFromData(length)[2]; command[19] = MelsecHelper.BuildBytesFromData(length)[3]; return(OperateResult.CreateSuccessResult(command)); }
/// <summary> /// 以位为单位,创建ASCII数据写入的核心报文 /// </summary> /// <param name="addressData">三菱Mc协议的数据地址</param> /// <param name="value">原始的bool数组数据</param> /// <returns>带有成功标识的报文对象</returns> public static byte[] BuildAsciiWriteBitCoreCommand(McAddressData addressData, bool[] value) { if (value == null) { value = new bool[0]; } byte[] buffer = value.Select(m => m ? (byte)0x31 : (byte)0x30).ToArray( ); byte[] command = new byte[20 + buffer.Length]; command[0] = 0x31; // 批量写入的命令 command[1] = 0x34; command[2] = 0x30; command[3] = 0x31; command[4] = 0x30; // 子命令 command[5] = 0x30; command[6] = 0x30; command[7] = 0x31; command[8] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0]; // 软元件类型 command[9] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1]; command[10] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0]; // 起始地址的地位 command[11] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1]; command[12] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2]; command[13] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3]; command[14] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4]; command[15] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5]; command[16] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[0]; // 软元件点数 command[17] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[1]; command[18] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[2]; command[19] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[3]; buffer.CopyTo(command, 20); return(command); }
/// <summary> /// 从三菱地址,是否位读取进行创建读取Ascii格式的MC的核心报文 /// </summary> /// <param name="addressData">三菱Mc协议的数据地址</param> /// <param name="isBit">是否进行了位读取操作</param> /// <returns>带有成功标识的报文对象</returns> public static byte[] BuildAsciiReadMcCoreCommand(McAddressData addressData, bool isBit) { byte[] command = new byte[20]; command[0] = 0x30; // 批量读取数据命令 command[1] = 0x34; command[2] = 0x30; command[3] = 0x31; command[4] = 0x30; // 以点为单位还是字为单位成批读取 command[5] = 0x30; command[6] = 0x30; command[7] = isBit ? (byte)0x31 : (byte)0x30; command[8] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0]; // 软元件类型 command[9] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1]; command[10] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0]; // 起始地址的地位 command[11] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1]; command[12] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2]; command[13] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3]; command[14] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4]; command[15] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5]; command[16] = MelsecHelper.BuildBytesFromData(addressData.Length)[0]; // 软元件点数 command[17] = MelsecHelper.BuildBytesFromData(addressData.Length)[1]; command[18] = MelsecHelper.BuildBytesFromData(addressData.Length)[2]; command[19] = MelsecHelper.BuildBytesFromData(addressData.Length)[3]; return(command); }
/// <summary> /// 根据类型地址长度确认需要读取的报文 /// </summary> /// <param name="address">起始地址</param> /// <param name="length">长度</param> /// <param name="networkNumber">网络号信息</param> /// <param name="networkStationNumber">网络站号信息</param> /// <returns>带有成功标志的指令数据</returns> public static OperateResult <byte[]> BuildReadCommand(string address, ushort length, byte networkNumber = 0, byte networkStationNumber = 0) { OperateResult <MelsecMcDataType, ushort> analysis = MelsecHelper.McAnalysisAddress(address); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } // 默认信息----注意:高低字节交错 byte[] _PLCCommand = new byte[42]; _PLCCommand[0] = 0x35; // 副标题 _PLCCommand[1] = 0x30; _PLCCommand[2] = 0x30; _PLCCommand[3] = 0x30; _PLCCommand[4] = MelsecHelper.BuildBytesFromData(networkNumber)[0]; // 网络号 _PLCCommand[5] = MelsecHelper.BuildBytesFromData(networkNumber)[1]; _PLCCommand[6] = 0x46; // PLC编号 _PLCCommand[7] = 0x46; _PLCCommand[8] = 0x30; // 目标模块IO编号 _PLCCommand[9] = 0x33; _PLCCommand[10] = 0x46; _PLCCommand[11] = 0x46; _PLCCommand[12] = MelsecHelper.BuildBytesFromData(networkStationNumber)[0]; // 目标模块站号 _PLCCommand[13] = MelsecHelper.BuildBytesFromData(networkStationNumber)[1]; _PLCCommand[14] = 0x30; // 请求数据长度 _PLCCommand[15] = 0x30; _PLCCommand[16] = 0x31; _PLCCommand[17] = 0x38; _PLCCommand[18] = 0x30; // CPU监视定时器 _PLCCommand[19] = 0x30; _PLCCommand[20] = 0x31; _PLCCommand[21] = 0x30; _PLCCommand[22] = 0x30; // 批量读取数据命令 _PLCCommand[23] = 0x34; _PLCCommand[24] = 0x30; _PLCCommand[25] = 0x31; _PLCCommand[26] = 0x30; // 以点为单位还是字为单位成批读取 _PLCCommand[27] = 0x30; _PLCCommand[28] = 0x30; _PLCCommand[29] = analysis.Content1.DataType == 0 ? (byte)0x30 : (byte)0x31; _PLCCommand[30] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[0]; // 软元件类型 _PLCCommand[31] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[1]; _PLCCommand[32] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[0]; // 起始地址的地位 _PLCCommand[33] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[1]; _PLCCommand[34] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[2]; _PLCCommand[35] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[3]; _PLCCommand[36] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[4]; _PLCCommand[37] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[5]; _PLCCommand[38] = MelsecHelper.BuildBytesFromData(length)[0]; // 软元件点数 _PLCCommand[39] = MelsecHelper.BuildBytesFromData(length)[1]; _PLCCommand[40] = MelsecHelper.BuildBytesFromData(length)[2]; _PLCCommand[41] = MelsecHelper.BuildBytesFromData(length)[3]; return(OperateResult.CreateSuccessResult(_PLCCommand)); }
/// <summary> /// 以字为单位,创建ASCII数据写入的核心报文 /// </summary> /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param> /// <param name="value">实际的原始数据信息</param> /// <param name="analysisAddress">对地址分析的委托方法</param> /// <returns>带有成功标识的报文对象</returns> public static OperateResult <byte[]> BuildAsciiWriteWordCoreCommand(string address, byte[] value, Func <string, OperateResult <MelsecMcDataType, int> > analysisAddress) { OperateResult <MelsecMcDataType, int> analysis = analysisAddress(address); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } if (value == null) { value = new byte[0]; } byte[] buffer = new byte[value.Length * 2]; for (int i = 0; i < value.Length / 2; i++) { MelsecHelper.BuildBytesFromData(BitConverter.ToUInt16(value, i * 2)).CopyTo(buffer, 4 * i); } value = buffer; byte[] command = new byte[20 + value.Length]; command[0] = 0x31; // 批量写入的命令 command[1] = 0x34; command[2] = 0x30; command[3] = 0x31; command[4] = 0x30; // 子命令 command[5] = 0x30; command[6] = 0x30; command[7] = 0x30; command[8] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[0]; // 软元件类型 command[9] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[1]; command[10] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[0]; // 起始地址的地位 command[11] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[1]; command[12] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[2]; command[13] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[3]; command[14] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[4]; command[15] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[5]; command[16] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[0]; // 软元件点数 command[17] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[1]; command[18] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[2]; command[19] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[3]; value.CopyTo(command, 20); return(OperateResult.CreateSuccessResult(command)); }
/// <summary> /// 以位为单位,创建ASCII数据写入的核心报文 /// </summary> /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param> /// <param name="value">原始的bool数组数据</param> /// <param name="analysisAddress">对地址分析的委托方法</param> /// <returns>带有成功标识的报文对象</returns> public static OperateResult <byte[]> BuildAsciiWriteBitCoreCommand(string address, bool[] value, Func <string, OperateResult <MelsecMcDataType, int> > analysisAddress) { OperateResult <MelsecMcDataType, int> analysis = analysisAddress(address); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } if (value == null) { value = new bool[0]; } byte[] buffer = value.Select(m => m ? (byte)0x31 : (byte)0x30).ToArray( ); byte[] command = new byte[20 + buffer.Length]; command[0] = 0x31; // 批量写入的命令 command[1] = 0x34; command[2] = 0x30; command[3] = 0x31; command[4] = 0x30; // 子命令 command[5] = 0x30; command[6] = 0x30; command[7] = 0x31; command[8] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[0]; // 软元件类型 command[9] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[1]; command[10] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[0]; // 起始地址的地位 command[11] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[1]; command[12] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[2]; command[13] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[3]; command[14] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[4]; command[15] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[5]; command[16] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[0]; // 软元件点数 command[17] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[1]; command[18] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[2]; command[19] = MelsecHelper.BuildBytesFromData((ushort)(value.Length))[3]; value.CopyTo(command, 20); return(OperateResult.CreateSuccessResult(command)); }
/// <summary> /// 以字为单位,创建ASCII数据写入的核心报文 /// </summary> /// <param name="addressData">三菱Mc协议的数据地址</param> /// <param name="value">实际的原始数据信息</param> /// <returns>带有成功标识的报文对象</returns> public static byte[] BuildAsciiWriteWordCoreCommand(McAddressData addressData, byte[] value) { if (value == null) { value = new byte[0]; } byte[] buffer = new byte[value.Length * 2]; for (int i = 0; i < value.Length / 2; i++) { MelsecHelper.BuildBytesFromData(BitConverter.ToUInt16(value, i * 2)).CopyTo(buffer, 4 * i); } value = buffer; byte[] command = new byte[20 + value.Length]; command[0] = 0x31; // 批量写入的命令 command[1] = 0x34; command[2] = 0x30; command[3] = 0x31; command[4] = 0x30; // 子命令 command[5] = 0x30; command[6] = 0x30; command[7] = 0x30; command[8] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[0]; // 软元件类型 command[9] = Encoding.ASCII.GetBytes(addressData.McDataType.AsciiCode)[1]; command[10] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[0]; // 起始地址的地位 command[11] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[1]; command[12] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[2]; command[13] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[3]; command[14] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[4]; command[15] = MelsecHelper.BuildBytesFromAddress(addressData.AddressStart, addressData.McDataType)[5]; command[16] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[0]; // 软元件点数 command[17] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[1]; command[18] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[2]; command[19] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[3]; value.CopyTo(command, 20); return(command); }
/// <summary> /// 根据类型地址以及需要写入的数据来生成报文 /// </summary> /// <param name="address">起始地址</param> /// <param name="value">写入数据的实际值</param> /// <param name="networkNumber">网络号</param> /// <param name="networkStationNumber">网络站号</param> /// <returns>带有成功标志的指令数据</returns> public static OperateResult <byte[]> BuildWriteCommand(string address, byte[] value, byte networkNumber = 0, byte networkStationNumber = 0) { OperateResult <MelsecMcDataType, ushort> analysis = MelsecHelper.McAnalysisAddress(address); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } // 预处理指令 if (analysis.Content1.DataType == 0x01) { // 位写入 value = value.Select(m => m == 0x00 ? (byte)0x30 : (byte)0x31).ToArray( ); } else { // 字写入 byte[] buffer = new byte[value.Length * 2]; for (int i = 0; i < value.Length / 2; i++) { MelsecHelper.BuildBytesFromData(BitConverter.ToUInt16(value, i * 2)).CopyTo(buffer, 4 * i); } value = buffer; } // 默认信息----注意:高低字节交错 byte[] _PLCCommand = new byte[42 + value.Length]; _PLCCommand[0] = 0x35; // 副标题 _PLCCommand[1] = 0x30; _PLCCommand[2] = 0x30; _PLCCommand[3] = 0x30; _PLCCommand[4] = MelsecHelper.BuildBytesFromData(networkNumber)[0]; // 网络号 _PLCCommand[5] = MelsecHelper.BuildBytesFromData(networkNumber)[1]; _PLCCommand[6] = 0x46; // PLC编号 _PLCCommand[7] = 0x46; _PLCCommand[8] = 0x30; // 目标模块IO编号 _PLCCommand[9] = 0x33; _PLCCommand[10] = 0x46; _PLCCommand[11] = 0x46; _PLCCommand[12] = MelsecHelper.BuildBytesFromData(networkStationNumber)[0]; // 目标模块站号 _PLCCommand[13] = MelsecHelper.BuildBytesFromData(networkStationNumber)[1]; _PLCCommand[14] = MelsecHelper.BuildBytesFromData((ushort)(_PLCCommand.Length - 18))[0]; // 请求数据长度 _PLCCommand[15] = MelsecHelper.BuildBytesFromData((ushort)(_PLCCommand.Length - 18))[1]; _PLCCommand[16] = MelsecHelper.BuildBytesFromData((ushort)(_PLCCommand.Length - 18))[2]; _PLCCommand[17] = MelsecHelper.BuildBytesFromData((ushort)(_PLCCommand.Length - 18))[3]; _PLCCommand[18] = 0x30; // CPU监视定时器 _PLCCommand[19] = 0x30; _PLCCommand[20] = 0x31; _PLCCommand[21] = 0x30; _PLCCommand[22] = 0x31; // 批量写入的命令 _PLCCommand[23] = 0x34; _PLCCommand[24] = 0x30; _PLCCommand[25] = 0x31; _PLCCommand[26] = 0x30; // 子命令 _PLCCommand[27] = 0x30; _PLCCommand[28] = 0x30; _PLCCommand[29] = analysis.Content1.DataType == 0 ? (byte)0x30 : (byte)0x31; _PLCCommand[30] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[0]; // 软元件类型 _PLCCommand[31] = Encoding.ASCII.GetBytes(analysis.Content1.AsciiCode)[1]; _PLCCommand[32] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[0]; // 起始地址的地位 _PLCCommand[33] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[1]; _PLCCommand[34] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[2]; _PLCCommand[35] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[3]; _PLCCommand[36] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[4]; _PLCCommand[37] = MelsecHelper.BuildBytesFromAddress(analysis.Content2, analysis.Content1)[5]; // 判断是否进行位操作 if (analysis.Content1.DataType == 1) { _PLCCommand[38] = MelsecHelper.BuildBytesFromData((ushort)value.Length)[0]; // 软元件点数 _PLCCommand[39] = MelsecHelper.BuildBytesFromData((ushort)value.Length)[1]; _PLCCommand[40] = MelsecHelper.BuildBytesFromData((ushort)value.Length)[2]; _PLCCommand[41] = MelsecHelper.BuildBytesFromData((ushort)value.Length)[3]; } else { _PLCCommand[38] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[0]; // 软元件点数 _PLCCommand[39] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[1]; _PLCCommand[40] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[2]; _PLCCommand[41] = MelsecHelper.BuildBytesFromData((ushort)(value.Length / 4))[3]; } Array.Copy(value, 0, _PLCCommand, 42, value.Length); return(OperateResult.CreateSuccessResult(_PLCCommand)); }