using MECF.Framework.RT.Core.IoProviders.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MECF.Framework.RT.Core.IoProviders.Melsec
{
///
/// 所有三菱通讯类的通用辅助工具类,包含了一些通用的静态方法,可以使用本类来获取一些原始的报文信息。详细的操作参见例子
///
public class MelsecHelper
{
#region Melsec Mc
///
/// 解析A1E协议数据地址
///
/// 数据地址
///
public static OperateResult McA1EAnalysisAddress(string address)
{
var result = new OperateResult();
try
{
switch (address[0])
{
case 'X':
case 'x':
{
result.Content1 = MelsecA1EDataType.X;
result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.X.FromBase);
break;
}
case 'Y':
case 'y':
{
result.Content1 = MelsecA1EDataType.Y;
result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.Y.FromBase);
break;
}
case 'M':
case 'm':
{
result.Content1 = MelsecA1EDataType.M;
result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.M.FromBase);
break;
}
case 'S':
case 's':
{
result.Content1 = MelsecA1EDataType.S;
result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.S.FromBase);
break;
}
case 'D':
case 'd':
{
result.Content1 = MelsecA1EDataType.D;
result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.D.FromBase);
break;
}
case 'R':
case 'r':
{
result.Content1 = MelsecA1EDataType.R;
result.Content2 = Convert.ToUInt16(address.Substring(1), MelsecA1EDataType.R.FromBase);
break;
}
default: throw new Exception(StringResources.Language.NotSupportedDataType);
}
}
catch (Exception ex)
{
result.Message = ex.Message;
return result;
}
result.IsSuccess = true;
return result;
}
///
/// 解析数据地址
///
/// 数据地址
/// 解析值
public static OperateResult McAnalysisAddress( string address )
{
var result = new OperateResult( );
try
{
switch (address[0])
{
case 'M':
case 'm':
{
result.Content1 = MelsecMcDataType.M;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.M.FromBase );
break;
}
case 'X':
case 'x':
{
result.Content1 = MelsecMcDataType.X;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.X.FromBase );
break;
}
case 'Y':
case 'y':
{
result.Content1 = MelsecMcDataType.Y;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Y.FromBase );
break;
}
case 'D':
case 'd':
{
result.Content1 = MelsecMcDataType.D;
result.Content2 = Convert.ToInt32( address.Substring( 1 ), MelsecMcDataType.D.FromBase );
break;
}
case 'W':
case 'w':
{
result.Content1 = MelsecMcDataType.W;
result.Content2 = Convert.ToInt32( address.Substring( 1 ), MelsecMcDataType.W.FromBase );
break;
}
case 'L':
case 'l':
{
result.Content1 = MelsecMcDataType.L;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.L.FromBase );
break;
}
case 'F':
case 'f':
{
result.Content1 = MelsecMcDataType.F;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.F.FromBase );
break;
}
case 'V':
case 'v':
{
result.Content1 = MelsecMcDataType.V;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.V.FromBase );
break;
}
case 'B':
case 'b':
{
result.Content1 = MelsecMcDataType.B;
result.Content2 = Convert.ToInt32( address.Substring( 1 ), MelsecMcDataType.B.FromBase );
break;
}
case 'R':
case 'r':
{
result.Content1 = MelsecMcDataType.R;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.R.FromBase );
break;
}
case 'S':
case 's':
{
if (address[1] == 'N' || address[1] == 'n')
{
result.Content1 = MelsecMcDataType.SN;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.SN.FromBase );
break;
}
else if (address[1] == 'S' || address[1] == 's')
{
result.Content1 = MelsecMcDataType.SS;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.SS.FromBase );
break;
}
else if (address[1] == 'C' || address[1] == 'c')
{
result.Content1 = MelsecMcDataType.SC;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.SC.FromBase );
break;
}
else
{
result.Content1 = MelsecMcDataType.S;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.S.FromBase );
break;
}
}
case 'Z':
case 'z':
{
if (address.StartsWith( "ZR" ) || address.StartsWith( "zr" ))
{
result.Content1 = MelsecMcDataType.ZR;
result.Content2 = Convert.ToInt32( address.Substring( 2 ), MelsecMcDataType.ZR.FromBase );
break;
}
else
{
result.Content1 = MelsecMcDataType.Z;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Z.FromBase );
break;
}
}
case 'T':
case 't':
{
if (address[1] == 'N' || address[1] == 'n')
{
result.Content1 = MelsecMcDataType.TN;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.TN.FromBase );
break;
}
else if (address[1] == 'S' || address[1] == 's')
{
result.Content1 = MelsecMcDataType.TS;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.TS.FromBase );
break;
}
else if (address[1] == 'C' || address[1] == 'c')
{
result.Content1 = MelsecMcDataType.TC;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.TC.FromBase );
break;
}
else
{
throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
case 'C':
case 'c':
{
if (address[1] == 'N' || address[1] == 'n')
{
result.Content1 = MelsecMcDataType.CN;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.CN.FromBase );
break;
}
else if (address[1] == 'S' || address[1] == 's')
{
result.Content1 = MelsecMcDataType.CS;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.CS.FromBase );
break;
}
else if (address[1] == 'C' || address[1] == 'c')
{
result.Content1 = MelsecMcDataType.CC;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.CC.FromBase );
break;
}
else
{
throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
default: throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
catch (Exception ex)
{
result.Message = ex.Message;
return result;
}
result.IsSuccess = true;
result.Message = StringResources.Language.SuccessText;
return result;
}
///
/// 基恩士解析数据地址
///
/// 数据地址
/// 解析值
public static OperateResult KeyenceAnalysisAddress( string address )
{
var result = new OperateResult( );
try
{
switch (address[0])
{
case 'M':
case 'm':
{
result.Content1 = MelsecMcDataType.Keyence_M;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_M.FromBase );
break;
}
case 'X':
case 'x':
{
result.Content1 = MelsecMcDataType.Keyence_X;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_X.FromBase );
break;
}
case 'Y':
case 'y':
{
result.Content1 = MelsecMcDataType.Keyence_Y;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_Y.FromBase );
break;
}
case 'B':
case 'b':
{
result.Content1 = MelsecMcDataType.Keyence_B;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_B.FromBase );
break;
}
case 'L':
case 'l':
{
result.Content1 = MelsecMcDataType.Keyence_L;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_L.FromBase );
break;
}
case 'S':
case 's':
{
if (address[1] == 'M' || address[1] == 'm')
{
result.Content1 = MelsecMcDataType.Keyence_SM;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.Keyence_SM.FromBase );
break;
}
else if (address[1] == 'D' || address[1] == 'd')
{
result.Content1 = MelsecMcDataType.Keyence_SD;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.Keyence_SD.FromBase );
break;
}
else
{
throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
case 'D':
case 'd':
{
result.Content1 = MelsecMcDataType.Keyence_D;
result.Content2 = Convert.ToInt32( address.Substring( 1 ), MelsecMcDataType.Keyence_D.FromBase );
break;
}
case 'R':
case 'r':
{
result.Content1 = MelsecMcDataType.Keyence_R;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_R.FromBase );
break;
}
case 'Z':
case 'z':
{
if (address[1] == 'R' || address[1] == 'r')
{
result.Content1 = MelsecMcDataType.Keyence_ZR;
result.Content2 = Convert.ToInt32( address.Substring( 2 ), MelsecMcDataType.Keyence_ZR.FromBase );
break;
}
else
{
throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
case 'W':
case 'w':
{
result.Content1 = MelsecMcDataType.Keyence_W;
result.Content2 = Convert.ToUInt16( address.Substring( 1 ), MelsecMcDataType.Keyence_W.FromBase );
break;
}
case 'T':
case 't':
{
if (address[1] == 'N' || address[1] == 'n')
{
result.Content1 = MelsecMcDataType.Keyence_TN;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.Keyence_TN.FromBase );
break;
}
else if (address[1] == 'S' || address[1] == 's')
{
result.Content1 = MelsecMcDataType.Keyence_TS;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.Keyence_TS.FromBase );
break;
}
else
{
throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
case 'C':
case 'c':
{
if (address[1] == 'N' || address[1] == 'n')
{
result.Content1 = MelsecMcDataType.Keyence_CN;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.Keyence_CN.FromBase );
break;
}
else if (address[1] == 'S' || address[1] == 's')
{
result.Content1 = MelsecMcDataType.Keyence_CS;
result.Content2 = Convert.ToUInt16( address.Substring( 2 ), MelsecMcDataType.Keyence_CS.FromBase );
break;
}
else
{
throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
default: throw new Exception( StringResources.Language.NotSupportedDataType );
}
}
catch (Exception ex)
{
result.Message = ex.Message;
return result;
}
result.IsSuccess = true;
result.Message = StringResources.Language.SuccessText;
return result;
}
///
/// 从地址,长度,是否位读取进行创建读取的MC的核心报文
///
/// 三菱的地址信息,具体格式参照 的注释说明
/// 读取的长度信息
/// 是否进行了位读取操作
/// 对地址分析的委托方法
/// 带有成功标识的报文对象
public static OperateResult BuildReadMcCoreCommand(string address, ushort length, bool isBit, Func> analysisAddress)
{
OperateResult analysis = analysisAddress( address );
if (!analysis.IsSuccess) return OperateResult.CreateFailedResult( 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 );
}
///
/// 从地址,长度,是否位读取进行创建读取Ascii格式的MC的核心报文
///
/// 三菱的地址信息,具体格式参照 的注释说明
/// 读取的长度信息
/// 是否进行了位读取操作
/// 对地址分析的委托方法
/// 带有成功标识的报文对象
public static OperateResult BuildAsciiReadMcCoreCommand(string address, ushort length, bool isBit, Func> analysisAddress )
{
OperateResult analysis = analysisAddress( address );
if (!analysis.IsSuccess) return OperateResult.CreateFailedResult( 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 );
}
///
/// 以字为单位,创建数据写入的核心报文
///
/// 三菱的地址信息,具体格式参照 的注释说明
/// 实际的原始数据信息
/// 对地址分析的委托方法
/// 带有成功标识的报文对象
public static OperateResult BuildWriteWordCoreCommand(string address, byte[] value, Func> analysisAddress )
{
OperateResult analysis = analysisAddress( address );
if (!analysis.IsSuccess) return OperateResult.CreateFailedResult( analysis );
if (value == null) value = new byte[0];
byte[] command = new byte[10 + value.Length];
command[0] = 0x01; // 批量读取数据命令
command[1] = 0x14;
command[2] = 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)(value.Length / 2 % 256); // 软元件长度的地位
command[9] = (byte)(value.Length / 2 / 256);
value.CopyTo( command, 10 );
return OperateResult.CreateSuccessResult( command );
}
///
/// 以字为单位,创建ASCII数据写入的核心报文
///
/// 三菱的地址信息,具体格式参照 的注释说明
/// 实际的原始数据信息
/// 对地址分析的委托方法
/// 带有成功标识的报文对象
public static OperateResult BuildAsciiWriteWordCoreCommand(string address, byte[] value, Func> analysisAddress )
{
OperateResult analysis = analysisAddress( address );
if (!analysis.IsSuccess) return OperateResult.CreateFailedResult( 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 );
}
///
/// 以位为单位,创建数据写入的核心报文
///
/// 三菱的地址信息,具体格式参照 的注释说明
/// 原始的bool数组数据
/// 对地址分析的委托方法
/// 带有成功标识的报文对象
public static OperateResult BuildWriteBitCoreCommand( string address, bool[] value, Func> analysisAddress )
{
OperateResult analysis = analysisAddress( address );
if (!analysis.IsSuccess) return OperateResult.CreateFailedResult( 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 );
}
///
/// 以位为单位,创建ASCII数据写入的核心报文
///
/// 三菱的地址信息,具体格式参照 的注释说明
/// 原始的bool数组数据
/// 对地址分析的委托方法
/// 带有成功标识的报文对象
public static OperateResult BuildAsciiWriteBitCoreCommand( string address, bool[] value, Func> analysisAddress )
{
OperateResult analysis = analysisAddress( address );
if (!analysis.IsSuccess) return OperateResult.CreateFailedResult( 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];
buffer.CopyTo( command, 20 );
return OperateResult.CreateSuccessResult( command );
}
#endregion
#region Common Logic
///
/// 从字节构建一个ASCII格式的地址字节
///
/// 字节信息
/// ASCII格式的地址
internal static byte[] BuildBytesFromData( byte value )
{
return Encoding.ASCII.GetBytes( value.ToString( "X2" ) );
}
///
/// 从short数据构建一个ASCII格式地址字节
///
/// short值
/// ASCII格式的地址
internal static byte[] BuildBytesFromData( short value )
{
return Encoding.ASCII.GetBytes( value.ToString( "X4" ) );
}
///
/// 从ushort数据构建一个ASCII格式地址字节
///
/// ushort值
/// ASCII格式的地址
internal static byte[] BuildBytesFromData( ushort value )
{
return Encoding.ASCII.GetBytes( value.ToString( "X4" ) );
}
///
/// 从三菱的地址中构建MC协议的6字节的ASCII格式的地址
///
/// 三菱地址
/// 三菱的数据类型
/// 6字节的ASCII格式的地址
internal static byte[] BuildBytesFromAddress( int address, MelsecMcDataType type )
{
return Encoding.ASCII.GetBytes( address.ToString( type.FromBase == 10 ? "D6" : "X6" ) );
}
///
/// 从字节数组构建一个ASCII格式的地址字节
///
/// 字节信息
/// ASCII格式的地址
internal static byte[] BuildBytesFromData( byte[] value )
{
byte[] buffer = new byte[value.Length * 2];
for (int i = 0; i < value.Length; i++)
{
BuildBytesFromData( value[i] ).CopyTo( buffer, 2 * i );
}
return buffer;
}
///
/// 将0,1,0,1的字节数组压缩成三菱格式的字节数组来表示开关量的
///
/// 原始的数据字节
/// 压缩过后的数据字节
internal static byte[] TransBoolArrayToByteData( byte[] value )
{
int length = (value.Length + 1) / 2;
byte[] buffer = new byte[length];
for (int i = 0; i < length; 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;
}
}
return buffer;
}
///
/// 将bool的组压缩成三菱格式的字节数组来表示开关量的
///
/// 原始的数据字节
/// 压缩过后的数据字节
internal static byte[] TransBoolArrayToByteData( bool[] value )
{
int length = (value.Length + 1) / 2;
byte[] buffer = new byte[length];
for (int i = 0; i < length; i++)
{
if (value[i * 2 + 0]) buffer[i] += 0x10;
if ((i * 2 + 1) < value.Length)
{
if (value[i * 2 + 1]) buffer[i] += 0x01;
}
}
return buffer;
}
#endregion
#region CRC Check
///
/// 计算Fx协议指令的和校验信息
///
/// 字节数据
/// 校验之后的数据
internal static byte[] FxCalculateCRC( byte[] data )
{
int sum = 0;
for (int i = 1; i < data.Length - 2; i++)
{
sum += data[i];
}
return BuildBytesFromData( (byte)sum );
}
///
/// 检查指定的和校验是否是正确的
///
/// 字节数据
/// 是否成功
internal static bool CheckCRC( byte[] data )
{
byte[] crc = FxCalculateCRC( data );
if (crc[0] != data[data.Length - 2]) return false;
if (crc[1] != data[data.Length - 1]) return false;
return true;
}
#endregion
}
}