/// <summary> /// 向PLC中位软元件写入bool数组,返回值说明,比如你写入D100,values[0]对应D100.0 /// </summary> /// <param name="address">要写入的数据地址</param> /// <param name="values">要写入的实际数据,可以指定任意的长度</param> /// <returns>返回写入结果</returns> /// <example> /// <code lang="cs" source="YumpooDrive_Net45.Test\Documentation\Samples\Profinet\OmronFinsNet.cs" region="WriteBool" title="WriteBool示例" /> /// </example> public override OperateResult Write(string address, bool[] values) { // 获取指令 var command = BuildWriteCommand(address, values.Select(m => m ? (byte)0x01 : (byte)0x00).ToArray(), true); if (!command.IsSuccess) { return(command); } // 核心数据交互 OperateResult <byte[]> read = ReadFromCoreServer(command.Content); if (!read.IsSuccess) { return(read); } // 数据有效性分析 OperateResult <byte[]> valid = OmronFinsNetHelper.ResponseValidAnalysis(read.Content, false); if (!valid.IsSuccess) { return(valid); } // 写入成功 return(OperateResult.CreateSuccessResult()); }
/// <summary> /// 从欧姆龙PLC中读取想要的数据,返回读取结果,读取单位为字 /// </summary> /// <param name="address">读取地址,格式为"D100","C100","W100","H100","A100"</param> /// <param name="length">读取的数据长度</param> /// <returns>带成功标志的结果数据对象</returns> /// <remarks> /// 地址支持的列表如下: /// <list type="table"> /// <listheader> /// <term>地址名称</term> /// <term>示例</term> /// <term>地址进制</term> /// </listheader> /// <item> /// <term>DM Area</term> /// <term>D100,D200</term> /// <term>10</term> /// </item> /// <item> /// <term>CIO Area</term> /// <term>C100,C200</term> /// <term>10</term> /// </item> /// <item> /// <term>Work Area</term> /// <term>W100,W200</term> /// <term>10</term> /// </item> /// <item> /// <term>Holding Bit Area</term> /// <term>H100,H200</term> /// <term>10</term> /// </item> /// <item> /// <term>Auxiliary Bit Area</term> /// <term>A100,A200</term> /// <term>10</term> /// </item> /// </list> /// </remarks> /// <example> /// 假设起始地址为D100,D100存储了温度,100.6℃值为1006,D101存储了压力,1.23Mpa值为123,D102,D103存储了产量计数,读取如下: /// <code lang="cs" source="YumpooDrive_Net45.Test\Documentation\Samples\Profinet\OmronFinsNet.cs" region="ReadExample2" title="Read示例" /> /// 以下是读取不同类型数据的示例 /// <code lang="cs" source="YumpooDrive_Net45.Test\Documentation\Samples\Profinet\OmronFinsNet.cs" region="ReadExample1" title="Read示例" /> /// </example> public override OperateResult <byte[]> Read(string address, ushort length) { // 获取指令 var command = BuildReadCommand(address, length, false); if (!command.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(command)); } // 核心数据交互 OperateResult <byte[]> read = ReadFromCoreServer(command.Content); if (!read.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(read)); } // 数据有效性分析 OperateResult <byte[]> valid = OmronFinsNetHelper.ResponseValidAnalysis(read.Content, true); if (!valid.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(valid)); } // 读取到了正确的数据 return(OperateResult.CreateSuccessResult(valid.Content)); }
/// <summary> /// 从欧姆龙PLC中批量读取位软元件,返回读取结果 /// </summary> /// <param name="address">读取地址,格式为"D100","C100","W100","H100","A100"</param> /// <param name="length">读取的长度</param> /// <returns>带成功标志的结果数据对象</returns> /// <remarks> /// 地址支持的列表如下: /// <list type="table"> /// <listheader> /// <term>地址名称</term> /// <term>示例</term> /// <term>地址进制</term> /// </listheader> /// <item> /// <term>DM Area</term> /// <term>D100.0,D200.10</term> /// <term>10</term> /// </item> /// <item> /// <term>CIO Area</term> /// <term>C100.0,C200.10</term> /// <term>10</term> /// </item> /// <item> /// <term>Work Area</term> /// <term>W100.0,W200.10</term> /// <term>10</term> /// </item> /// <item> /// <term>Holding Bit Area</term> /// <term>H100.0,H200.10</term> /// <term>10</term> /// </item> /// <item> /// <term>Auxiliary Bit Area</term> /// <term>A100.0,A200.1</term> /// <term>10</term> /// </item> /// </list> /// </remarks> /// <example> /// <code lang="cs" source="YumpooDrive_Net45.Test\Documentation\Samples\Profinet\OmronFinsNet.cs" region="ReadBool" title="ReadBool示例" /> /// </example> public override OperateResult <bool[]> ReadBool(string address, ushort length) { // 获取指令 var command = BuildReadCommand(address, length, true); if (!command.IsSuccess) { return(OperateResult.CreateFailedResult <bool[]>(command)); } // 核心数据交互 OperateResult <byte[]> read = ReadFromCoreServer(command.Content); if (!read.IsSuccess) { return(OperateResult.CreateFailedResult <bool[]>(read)); } // 数据有效性分析 OperateResult <byte[]> valid = OmronFinsNetHelper.ResponseValidAnalysis(read.Content, true); if (!valid.IsSuccess) { return(OperateResult.CreateFailedResult <bool[]>(valid)); } // 返回正确的数据信息 return(OperateResult.CreateSuccessResult(valid.Content.Select(m => m != 0x00 ? true : false).ToArray())); }
/// <summary> /// 在连接上欧姆龙PLC后,需要进行一步握手协议 /// </summary> /// <param name="socket">连接的套接字</param> /// <returns>初始化成功与否</returns> protected override OperateResult InitializationOnConnect(Socket socket) { // 握手信号 OperateResult <byte[], byte[]> read = ReadFromCoreServerBase(socket, handSingle); if (!read.IsSuccess) { return(read); } // 检查返回的状态 byte[] buffer = new byte[4]; buffer[0] = read.Content2[7]; buffer[1] = read.Content2[6]; buffer[2] = read.Content2[5]; buffer[3] = read.Content2[4]; int status = BitConverter.ToInt32(buffer, 0); if (status != 0) { return(new OperateResult(status, OmronFinsNetHelper.GetStatusDescription(status))); } // 提取PLC的节点地址 if (read.Content2.Length >= 16) { DA1 = read.Content2[15]; } return(OperateResult.CreateSuccessResult()); }
/// <summary> /// 根据读取的地址,长度,是否位读取创建Fins协议的核心报文 /// </summary> /// <param name="address">地址,具体格式请参照示例说明</param> /// <param name="length">读取的数据长度</param> /// <param name="isBit">是否使用位读取</param> /// <returns>带有成功标识的Fins核心报文</returns> public static OperateResult <byte[]> BuildReadCommand(string address, ushort length, bool isBit) { var analysis = OmronFinsNetHelper.AnalysisAddress(address, isBit); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } byte[] _PLCCommand = new byte[8]; _PLCCommand[0] = 0x01; // 读取存储区数据 _PLCCommand[1] = 0x01; if (isBit) { _PLCCommand[2] = analysis.Content1.BitCode; } else { _PLCCommand[2] = analysis.Content1.WordCode; } analysis.Content2.CopyTo(_PLCCommand, 3); _PLCCommand[6] = (byte)(length / 256); // 长度 _PLCCommand[7] = (byte)(length % 256); return(OperateResult.CreateSuccessResult(_PLCCommand)); }
/// <summary> /// 根据类型地址以及需要写入的数据来生成指令头 /// </summary> /// <param name="address">起始地址</param> /// <param name="value">真实的数据值信息</param> /// <param name="isBit">是否是位操作</param> /// <returns>带有成功标志的报文数据</returns> public OperateResult <byte[]> BuildWriteCommand(string address, byte[] value, bool isBit) { var command = OmronFinsNetHelper.BuildWriteWordCommand(address, value, isBit); if (!command.IsSuccess) { return(command); } return(OperateResult.CreateSuccessResult(PackCommand(command.Content))); }
/// <summary> /// 根据类型地址长度确认需要读取的指令头 /// </summary> /// <param name="address">起始地址</param> /// <param name="length">长度</param> /// <param name="isBit">是否是位读取</param> /// <returns>带有成功标志的报文数据</returns> public OperateResult <byte[]> BuildReadCommand(string address, ushort length, bool isBit) { var command = OmronFinsNetHelper.BuildReadCommand(address, length, isBit); if (!command.IsSuccess) { return(command); } return(OperateResult.CreateSuccessResult(PackCommand(command.Content))); }
/// <summary> /// 根据写入的地址,数据,是否位写入生成Fins协议的核心报文 /// </summary> /// <param name="address">地址内容,具体格式请参照示例说明</param> /// <param name="value">实际的数据</param> /// <param name="isBit">是否位数据</param> /// <returns>带有成功标识的Fins核心报文</returns> public static OperateResult <byte[]> BuildWriteWordCommand(string address, byte[] value, bool isBit) { var analysis = OmronFinsNetHelper.AnalysisAddress(address, isBit); if (!analysis.IsSuccess) { return(OperateResult.CreateFailedResult <byte[]>(analysis)); } byte[] _PLCCommand = new byte[8 + value.Length]; _PLCCommand[0] = 0x01; _PLCCommand[1] = 0x02; if (isBit) { _PLCCommand[2] = analysis.Content1.BitCode; } else { _PLCCommand[2] = analysis.Content1.WordCode; } analysis.Content2.CopyTo(_PLCCommand, 3); if (isBit) { _PLCCommand[6] = (byte)(value.Length / 256); _PLCCommand[7] = (byte)(value.Length % 256); } else { _PLCCommand[6] = (byte)(value.Length / 2 / 256); _PLCCommand[7] = (byte)(value.Length / 2 % 256); } value.CopyTo(_PLCCommand, 8); return(OperateResult.CreateSuccessResult(_PLCCommand)); }