Пример #1
0
        /// <summary>
        /// 以位为单位,创建数据写入的核心报文
        /// </summary>
        /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param>
        /// <param name="value">原始的bool数组数据</param>
        /// <returns>带有成功标识的报文对象</returns>
        public static OperateResult <byte[]> BuildWriteBitCoreCommand(string address, bool[] value)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[]>(analysis));
            }

            if (value == null)
            {
                value = new bool[0];
            }
            byte[] buffer  = MelsecHelper.TransBoolArrayToByteData(value);
            byte[] command = new byte[10 + buffer.Length];
            command[0] = 0x01;                                                        // 批量写入数据命令
            command[1] = 0x14;
            command[2] = 0x01;                                                        // 以位为单位成批写入
            command[3] = 0x00;
            command[4] = BitConverter.GetBytes(analysis.Content2)[0];                 // 起始地址的地位
            command[5] = BitConverter.GetBytes(analysis.Content2)[1];
            command[6] = BitConverter.GetBytes(analysis.Content2)[2];
            command[7] = analysis.Content1.DataCode;                                  // 指明写入的数据
            command[8] = (byte)(value.Length % 256);                                  // 软元件长度的地位
            command[9] = (byte)(value.Length / 256);
            buffer.CopyTo(command, 10);

            return(OperateResult.CreateSuccessResult(command));
        }
Пример #2
0
        /// <summary>
        /// 读取指定地址的bool数据对象
        /// </summary>
        /// <param name="address">三菱的地址信息</param>
        /// <param name="length">数组的长度</param>
        /// <returns>带有成功标志的结果对象</returns>
        public OperateResult <bool[]> ReadBool(string address, ushort length)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <bool[]>(analysis));
            }

            if (analysis.Content1.DataType == 0)
            {
                return(new OperateResult <bool[]>(StringResources.Language.MelsecCurrentTypeNotSupportedWordOperate));
            }

            if (analysis.Content1.DataCode == MelsecMcDataType.M.DataCode)
            {
                return(OperateResult.CreateSuccessResult(mBuffer.GetBytes(analysis.Content2, length).Select(m => m != 0x00).ToArray( )));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.X.DataCode)
            {
                return(OperateResult.CreateSuccessResult(xBuffer.GetBytes(analysis.Content2, length).Select(m => m != 0x00).ToArray( )));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.Y.DataCode)
            {
                return(OperateResult.CreateSuccessResult(yBuffer.GetBytes(analysis.Content2, length).Select(m => m != 0x00).ToArray( )));
            }
            else
            {
                return(new OperateResult <bool[]>(StringResources.Language.NotSupportedDataType));
            }
        }
        /// <summary>
        /// 从三菱PLC中批量读取位软元件,返回读取结果
        /// </summary>
        /// <param name="address">起始地址</param>
        /// <param name="length">读取的长度</param>
        /// <returns>带成功标志的结果数据对象</returns>
        /// <remarks>
        /// 地址支持的列表如下:
        /// <list type="table">
        ///   <listheader>
        ///     <term>地址名称</term>
        ///     <term>示例</term>
        ///     <term>地址进制</term>
        ///   </listheader>
        ///   <item>
        ///     <term>内部继电器</term>
        ///     <term>M100,M200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>输入继电器</term>
        ///     <term>X100,X1A0</term>
        ///     <term>16</term>
        ///   </item>
        ///   <item>
        ///     <term>输出继电器</term>
        ///     <term>Y100,Y1A0</term>
        ///     <term>16</term>
        ///   </item>
        ///    <item>
        ///     <term>锁存继电器</term>
        ///     <term>L100,L200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>报警器</term>
        ///     <term>F100,F200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>边沿继电器</term>
        ///     <term>V100,V200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>链接继电器</term>
        ///     <term>B100,B1A0</term>
        ///     <term>16</term>
        ///   </item>
        ///    <item>
        ///     <term>步进继电器</term>
        ///     <term>S100,S200</term>
        ///     <term>10</term>
        ///   </item>
        /// </list>
        /// </remarks>
        /// <example>
        ///  <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\MelsecAscii.cs" region="ReadBool" title="Bool类型示例" />
        /// </example>
        public OperateResult <bool[]> ReadBool(string address, ushort length)
        {
            // 解析地址
            OperateResult <MelsecMcDataType, ushort> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <bool[]>(analysis));
            }

            // 位读取校验
            if (analysis.Content1.DataType == 0x00)
            {
                return(new OperateResult <bool[]>(StringResources.Language.MelsecReadBitInfo));
            }

            // 核心交互
            var read = Read(address, length);

            if (!read.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <bool[]>(read));
            }

            // 转化bool数组
            return(OperateResult.CreateSuccessResult(read.Content.Select(m => m == 0x01).ToArray( )));
        }
Пример #4
0
        /// <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[21];
            _PLCCommand[0]  = 0x50;                                   // 副标题
            _PLCCommand[1]  = 0x00;
            _PLCCommand[2]  = networkNumber;                          // 网络号
            _PLCCommand[3]  = 0xFF;                                   // PLC编号
            _PLCCommand[4]  = 0xFF;                                   // 目标模块IO编号
            _PLCCommand[5]  = 0x03;
            _PLCCommand[6]  = networkStationNumber;                   // 目标模块站号
            _PLCCommand[7]  = 0x0C;                                   // 请求数据长度
            _PLCCommand[8]  = 0x00;
            _PLCCommand[9]  = 0x0A;                                   // CPU监视定时器
            _PLCCommand[10] = 0x00;
            _PLCCommand[11] = 0x01;                                   // 批量读取数据命令
            _PLCCommand[12] = 0x04;
            _PLCCommand[13] = analysis.Content1.DataType;             // 以点为单位还是字为单位成批读取
            _PLCCommand[14] = 0x00;
            _PLCCommand[15] = (byte)(analysis.Content2 % 256);        // 起始地址的地位
            _PLCCommand[16] = (byte)(analysis.Content2 / 256);
            _PLCCommand[17] = 0x00;
            _PLCCommand[18] = analysis.Content1.DataCode;             // 指明读取的数据
            _PLCCommand[19] = (byte)(length % 256);                   // 软元件长度的地位
            _PLCCommand[20] = (byte)(length / 256);

            return(OperateResult.CreateSuccessResult(_PLCCommand));
        }
Пример #5
0
        /// <summary>
        /// 从地址,长度,是否位读取进行创建读取Ascii格式的MC的核心报文
        /// </summary>
        /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param>
        /// <param name="length">读取的长度信息</param>
        /// <param name="isBit">是否进行了位读取操作</param>
        /// <returns>带有成功标识的报文对象</returns>
        public static OperateResult <byte[]> BuildAsciiReadMcCoreCommand(string address, ushort length, bool isBit)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(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));
        }
Пример #6
0
        /// <summary>
        /// 从三菱PLC中批量读取位软元件,返回读取结果
        /// </summary>
        /// <param name="address">起始地址</param>
        /// <param name="length">读取的长度</param>
        /// <returns>带成功标志的结果数据对象</returns>
        /// <remarks>
        /// 地址支持的列表如下:
        /// <list type="table">
        ///   <listheader>
        ///     <term>地址名称</term>
        ///     <term>示例</term>
        ///     <term>地址进制</term>
        ///   </listheader>
        ///   <item>
        ///     <term>内部继电器</term>
        ///     <term>M100,M200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>输入继电器</term>
        ///     <term>X100,X1A0</term>
        ///     <term>16</term>
        ///   </item>
        ///   <item>
        ///     <term>输出继电器</term>
        ///     <term>Y100,Y1A0</term>
        ///     <term>16</term>
        ///   </item>
        ///    <item>
        ///     <term>锁存继电器</term>
        ///     <term>L100,L200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>报警器</term>
        ///     <term>F100,F200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>边沿继电器</term>
        ///     <term>V100,V200</term>
        ///     <term>10</term>
        ///   </item>
        ///   <item>
        ///     <term>链接继电器</term>
        ///     <term>B100,B1A0</term>
        ///     <term>16</term>
        ///   </item>
        ///    <item>
        ///     <term>步进继电器</term>
        ///     <term>S100,S200</term>
        ///     <term>10</term>
        ///   </item>
        /// </list>
        /// </remarks>
        /// <example>
        /// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\melsecTest.cs" region="ReadBool" title="Bool类型示例" />
        /// </example>
        public OperateResult <bool[]> ReadBool(string address, ushort length)
        {
            // 解析地址
            OperateResult <MelsecMcDataType, ushort> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <bool[]>(analysis));
            }

            // 位读取校验
            if (analysis.Content1.DataType == 0x00)
            {
                return new OperateResult <bool[]>( )
                       {
                           Message = "读取位变量数组只能针对位软元件,如果读取字软元件,请调用Read方法"
                       }
            }
            ;

            // 核心交互
            var read = Read(address, length);

            if (!read.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <bool[]>(read));
            }

            // 转化bool数组
            return(OperateResult.CreateSuccessResult(read.Content.Select(m => m == 0x01).ToArray()));
        }
Пример #7
0
        /// <summary>
        /// 往指定的地址里写入bool数组对象
        /// </summary>
        /// <param name="address">三菱的地址信息</param>
        /// <param name="value">值</param>
        /// <returns>是否成功的结果</returns>
        public OperateResult Write(string address, bool[] value)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <bool[]>(analysis));
            }

            if (analysis.Content1.DataType == 0)
            {
                return(new OperateResult <bool[]>(StringResources.Language.MelsecCurrentTypeNotSupportedWordOperate));
            }

            if (analysis.Content1.DataCode == MelsecMcDataType.M.DataCode)
            {
                mBuffer.SetBytes(value.Select(m => m ? (byte)1 : (byte)0).ToArray( ), analysis.Content2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.X.DataCode)
            {
                xBuffer.SetBytes(value.Select(m => m ? (byte)1 : (byte)0).ToArray( ), analysis.Content2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.Y.DataCode)
            {
                yBuffer.SetBytes(value.Select(m => m ? (byte)1 : (byte)0).ToArray( ), analysis.Content2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else
            {
                return(new OperateResult <bool[]>(StringResources.Language.NotSupportedDataType));
            }
        }
        /// <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));
        }
Пример #9
0
        /// <summary>
        /// 以字为单位,创建ASCII数据写入的核心报文
        /// </summary>
        /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param>
        /// <param name="value">实际的原始数据信息</param>
        /// <returns>带有成功标识的报文对象</returns>
        public static OperateResult <byte[]> BuildAsciiWriteWordCoreCommand(string address, byte[] value)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(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));
        }
Пример #10
0
        /// <summary>
        /// 写入自定义的数据到数据内存中去
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="value">数据值</param>
        /// <returns>是否写入成功的结果对象</returns>
        public override OperateResult Write(string address, byte[] value)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[]>(analysis));
            }

            if (analysis.Content1.DataCode == MelsecMcDataType.M.DataCode)
            {
                byte[] buffer = SoftBasic.ByteToBoolArray(value).Select(m => m ? (byte)1 : (byte)0).ToArray( );
                mBuffer.SetBytes(buffer, analysis.Content2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.X.DataCode)
            {
                byte[] buffer = SoftBasic.ByteToBoolArray(value).Select(m => m ? (byte)1 : (byte)0).ToArray( );
                xBuffer.SetBytes(buffer, analysis.Content2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.Y.DataCode)
            {
                byte[] buffer = SoftBasic.ByteToBoolArray(value).Select(m => m ? (byte)1 : (byte)0).ToArray( );
                yBuffer.SetBytes(buffer, analysis.Content2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.D.DataCode)
            {
                dBuffer.SetBytes(value, analysis.Content2 * 2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.W.DataCode)
            {
                wBuffer.SetBytes(value, analysis.Content2 * 2);
                return(OperateResult.CreateSuccessResult( ));
            }
            else
            {
                return(new OperateResult <byte[]>(StringResources.Language.NotSupportedDataType));
            }
        }
Пример #11
0
        /// <summary>
        /// 以位为单位,创建ASCII数据写入的核心报文
        /// </summary>
        /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param>
        /// <param name="value">原始的bool数组数据</param>
        /// <returns>带有成功标识的报文对象</returns>
        public static OperateResult <byte[]> BuildAsciiWriteBitCoreCommand(string address, bool[] value)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(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));
        }
Пример #12
0
        /// <summary>
        /// 从地址,长度,是否位读取进行创建读取的MC的核心报文
        /// </summary>
        /// <param name="address">三菱的地址信息,具体格式参照<seealso cref="MelsecMcNet"/> 的注释说明</param>
        /// <param name="length">读取的长度信息</param>
        /// <param name="isBit">是否进行了位读取操作</param>
        /// <returns>带有成功标识的报文对象</returns>
        public static OperateResult <byte[]> BuildReadMcCoreCommand(string address, ushort length, bool isBit)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[]>(analysis));
            }

            byte[] command = new byte[10];
            command[0] = 0x01;                                               // 批量读取数据命令
            command[1] = 0x04;
            command[2] = isBit ? (byte)0x01 : (byte)0x00;                    // 以点为单位还是字为单位成批读取
            command[3] = 0x00;
            command[4] = BitConverter.GetBytes(analysis.Content2)[0];        // 起始地址的地位
            command[5] = BitConverter.GetBytes(analysis.Content2)[1];
            command[6] = BitConverter.GetBytes(analysis.Content2)[2];
            command[7] = analysis.Content1.DataCode;                         // 指明读取的数据
            command[8] = (byte)(length % 256);                               // 软元件的长度
            command[9] = (byte)(length / 256);

            return(OperateResult.CreateSuccessResult(command));
        }
Пример #13
0
        /// <summary>
        /// 读取自定义的寄存器的值。按照字为单位
        /// </summary>
        /// <param name="address">起始地址,示例:"D100","M100"</param>
        /// <param name="length">数据长度</param>
        /// <exception cref="IndexOutOfRangeException"></exception>
        /// <returns>byte数组值</returns>
        public override OperateResult <byte[]> Read(string address, ushort length)
        {
            OperateResult <MelsecMcDataType, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[]>(analysis));
            }

            if (analysis.Content1.DataCode == MelsecMcDataType.M.DataCode)
            {
                bool[] buffer = mBuffer.GetBytes(analysis.Content2, length * 16).Select(m => m != 0x00).ToArray( );
                return(OperateResult.CreateSuccessResult(SoftBasic.BoolArrayToByte(buffer)));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.X.DataCode)
            {
                bool[] buffer = xBuffer.GetBytes(analysis.Content2, length * 16).Select(m => m != 0x00).ToArray( );
                return(OperateResult.CreateSuccessResult(SoftBasic.BoolArrayToByte(buffer)));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.Y.DataCode)
            {
                bool[] buffer = yBuffer.GetBytes(analysis.Content2, length * 16).Select(m => m != 0x00).ToArray( );
                return(OperateResult.CreateSuccessResult(SoftBasic.BoolArrayToByte(buffer)));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.D.DataCode)
            {
                return(OperateResult.CreateSuccessResult(dBuffer.GetBytes(analysis.Content2 * 2, length * 2)));
            }
            else if (analysis.Content1.DataCode == MelsecMcDataType.W.DataCode)
            {
                return(OperateResult.CreateSuccessResult(wBuffer.GetBytes(analysis.Content2 * 2, length * 2)));
            }
            else
            {
                return(new OperateResult <byte[]>(StringResources.Language.NotSupportedDataType));
            }
        }
Пример #14
0
 /// <summary>
 /// 分析地址的方法,允许派生类里进行重写操作
 /// </summary>
 /// <param name="address">地址信息</param>
 /// <returns>解析后的数据信息</returns>
 protected virtual OperateResult <MelsecMcDataType, int> McAnalysisAddress(string address)
 {
     return(MelsecHelper.McAnalysisAddress(address));
 }
Пример #15
0
        /// <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));
        }
Пример #16
0
        /// <summary>
        /// 根据类型地址以及需要写入的数据来生成指令头
        /// </summary>
        /// <param name="address">起始地址</param>
        /// <param name="value">数据值,对于写入位地址来说,应该传入{0x01,0x00,0x01} 通断通这样的数组</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));
            }

            int length = -1;

            if (analysis.Content1.DataType == 1)
            {
                // 按照位写入的操作,数据需要重新计算
                int    length2 = value.Length % 2 == 0 ? value.Length / 2 : value.Length / 2 + 1;
                byte[] buffer  = new byte[length2];

                for (int i = 0; i < length2; i++)
                {
                    if (value[i * 2 + 0] != 0x00)
                    {
                        buffer[i] += 0x10;
                    }
                    if ((i * 2 + 1) < value.Length)
                    {
                        if (value[i * 2 + 1] != 0x00)
                        {
                            buffer[i] += 0x01;
                        }
                    }
                }
                length = value.Length;
                value  = buffer;
            }


            byte[] _PLCCommand = new byte[21 + value.Length];
            _PLCCommand[0]  = 0x50;                                          // 副标题
            _PLCCommand[1]  = 0x00;
            _PLCCommand[2]  = networkNumber;                                 // 网络号
            _PLCCommand[3]  = 0xFF;                                          // PLC编号
            _PLCCommand[4]  = 0xFF;                                          // 目标模块IO编号
            _PLCCommand[5]  = 0x03;
            _PLCCommand[6]  = networkStationNumber;                          // 目标模块站号
            _PLCCommand[7]  = (byte)((_PLCCommand.Length - 9) % 256);        // 请求数据长度
            _PLCCommand[8]  = (byte)((_PLCCommand.Length - 9) / 256);
            _PLCCommand[9]  = 0x0A;                                          // CPU监视定时器
            _PLCCommand[10] = 0x00;
            _PLCCommand[11] = 0x01;                                          // 批量读取数据命令
            _PLCCommand[12] = 0x14;
            _PLCCommand[13] = analysis.Content1.DataType;                    // 以点为单位还是字为单位成批读取
            _PLCCommand[14] = 0x00;
            _PLCCommand[15] = (byte)(analysis.Content2 % 256);               // 起始地址的地位
            _PLCCommand[16] = (byte)(analysis.Content2 / 256);
            _PLCCommand[17] = 0x00;
            _PLCCommand[18] = analysis.Content1.DataCode;                    // 指明写入的数据

            // 判断是否进行位操作
            if (analysis.Content1.DataType == 1)
            {
                if (length > 0)
                {
                    _PLCCommand[19] = (byte)(length % 256);                  // 软元件长度的地位
                    _PLCCommand[20] = (byte)(length / 256);
                }
                else
                {
                    _PLCCommand[19] = (byte)(value.Length * 2 % 256);        // 软元件长度的地位
                    _PLCCommand[20] = (byte)(value.Length * 2 / 256);
                }
            }
            else
            {
                _PLCCommand[19] = (byte)(value.Length / 2 % 256);            // 软元件长度的地位
                _PLCCommand[20] = (byte)(value.Length / 2 / 256);
            }
            Array.Copy(value, 0, _PLCCommand, 21, value.Length);

            return(OperateResult.CreateSuccessResult(_PLCCommand));
        }
Пример #17
0
        /// <summary>
        /// 根据类型地址以及需要写入的数据来生成指令头
        /// </summary>
        /// <param name="address">起始地址</param>
        /// <param name="value">数据值,对于写入位地址来说,应该传入{0x01,0x00,0x01} 通断通这样的数组</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, int> analysis = MelsecHelper.McAnalysisAddress(address);

            if (!analysis.IsSuccess)
            {
                return(OperateResult.CreateFailedResult <byte[]>(analysis));
            }

            int length = -1;

            if (analysis.Content1.DataType == 1)
            {
                // 按照位写入的操作,数据需要重新计算
                length = value.Length;
                value  = MelsecHelper.TransBoolArrayToByteData(value);
            }

            byte[] _PLCCommand = new byte[21 + value.Length];
            _PLCCommand[0]  = 0x50;                                          // 副标题
            _PLCCommand[1]  = 0x00;
            _PLCCommand[2]  = networkNumber;                                 // 网络号
            _PLCCommand[3]  = 0xFF;                                          // PLC编号
            _PLCCommand[4]  = 0xFF;                                          // 目标模块IO编号
            _PLCCommand[5]  = 0x03;
            _PLCCommand[6]  = networkStationNumber;                          // 目标模块站号
            _PLCCommand[7]  = (byte)((_PLCCommand.Length - 9) % 256);        // 请求数据长度
            _PLCCommand[8]  = (byte)((_PLCCommand.Length - 9) / 256);
            _PLCCommand[9]  = 0x0A;                                          // CPU监视定时器
            _PLCCommand[10] = 0x00;
            _PLCCommand[11] = 0x01;                                          // 批量读取数据命令
            _PLCCommand[12] = 0x14;
            _PLCCommand[13] = analysis.Content1.DataType;                    // 以点为单位还是字为单位成批读取
            _PLCCommand[14] = 0x00;
            _PLCCommand[15] = BitConverter.GetBytes(analysis.Content2)[0];   // 起始地址的地位
            _PLCCommand[16] = BitConverter.GetBytes(analysis.Content2)[1];
            _PLCCommand[17] = BitConverter.GetBytes(analysis.Content2)[2];
            _PLCCommand[18] = analysis.Content1.DataCode;                    // 指明写入的数据

            // 判断是否进行位操作
            if (analysis.Content1.DataType == 1)
            {
                if (length > 0)
                {
                    _PLCCommand[19] = (byte)(length % 256);                  // 软元件长度的地位
                    _PLCCommand[20] = (byte)(length / 256);
                }
                else
                {
                    _PLCCommand[19] = (byte)(value.Length * 2 % 256);        // 软元件长度的地位
                    _PLCCommand[20] = (byte)(value.Length * 2 / 256);
                }
            }
            else
            {
                _PLCCommand[19] = (byte)(value.Length / 2 % 256);            // 软元件长度的地位
                _PLCCommand[20] = (byte)(value.Length / 2 / 256);
            }
            Array.Copy(value, 0, _PLCCommand, 21, value.Length);

            return(OperateResult.CreateSuccessResult(_PLCCommand));
        }