/// <summary> /// 向PLC写入数据,数据格式为原始的字节类型 /// </summary> /// <param name="address">初始地址</param> /// <param name="value">原始的字节数据</param> /// <example> /// 假设起始地址为D100,D100存储了温度,100.6℃值为1006,D101存储了压力,1.23Mpa值为123,D102,D103存储了产量计数,写入如下: /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecAscii.cs" region="WriteExample2" title="Write示例" /> /// 以下是读取不同类型数据的示例 /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecAscii.cs" region="WriteExample1" title="Write示例" /> /// </example> /// <returns>结果</returns> public override OperateResult Write(string address, byte[] value) { // 分析地址 OperateResult <McAddressData> addressResult = McAnalysisAddress(address, 0); if (!addressResult.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(addressResult)); } // 地址分析 byte[] coreResult = MelsecHelper.BuildAsciiWriteWordCoreCommand(addressResult.Content, value); // 核心交互 OperateResult <byte[]> read = ReadFromCoreServer(PackMcCommand(coreResult, NetworkNumber, NetworkStationNumber)); if (!read.IsSuccess) { return(read); } // 错误码验证 ushort errorCode = Convert.ToUInt16(Encoding.ASCII.GetString(read.Content, 18, 4), 16); if (errorCode != 0) { return(new OperateResult <byte[]>(errorCode, StringResources.Language.MelsecPleaseReferToManulDocument)); } // 写入成功 return(OperateResult.CreateSuccessResult( )); }
/// <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 <byte[]> coreResult = MelsecHelper.BuildAsciiWriteWordCoreCommand(address, value); if (!coreResult.IsSuccess) { return(coreResult); } return(OperateResult.CreateSuccessResult(PackMcCommand(coreResult.Content, networkNumber, networkStationNumber))); }
/// <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 <byte[]> coreResult = MelsecHelper.BuildAsciiWriteWordCoreCommand(address, value); if (!coreResult.IsSuccess) { return(coreResult); } return(OperateResult.CreateSuccessResult(PackMcCommand(coreResult.Content, networkNumber, networkStationNumber))); OperateResult <MelsecMcDataType, int> 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)); }