From 962f7a80d850af978ee99e21da7f76cf35ebdca8 Mon Sep 17 00:00:00 2001 From: parallelbgls Date: Sat, 25 Feb 2017 10:48:19 +0800 Subject: [PATCH] 2017-02-25 update 2 Endian Fix --- Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs | 4 +- Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs | 4 +- .../Modbus.Net.Siemens/SiemensPpiProtocal.cs | 4 +- .../Modbus.Net.Siemens/SiemensTcpProtocal.cs | 4 +- .../Modbus.Net.Siemens/SiemensUtility.cs | 4 +- Modbus.Net/Modbus.Net/BaseMachine.cs | 18 ++++--- Modbus.Net/Modbus.Net/BaseProtocal.cs | 4 +- Modbus.Net/Modbus.Net/BaseUtility.cs | 51 ++++++++++++++++--- Modbus.Net/Modbus.Net/ProtocalUnit.cs | 25 ++++++--- Modbus.Net/Modbus.Net/ValueHelper.cs | 15 +++++- 10 files changed, 100 insertions(+), 33 deletions(-) diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs index 53c4775..1f1634e 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs @@ -49,8 +49,8 @@ namespace Modbus.Net.Modbus AddressTranslator = new AddressTranslatorModbus(); } - public override bool GetLittleEndian => Wrapper[typeof (ReadDataModbusProtocal)].IsLittleEndian; - public override bool SetLittleEndian => Wrapper[typeof (WriteDataModbusProtocal)].IsLittleEndian; + public override Endian GetLittleEndian => Wrapper[typeof (ReadDataModbusProtocal)].IsLittleEndian; + public override Endian SetLittleEndian => Wrapper[typeof (WriteDataModbusProtocal)].IsLittleEndian; protected string ConnectionStringIp { diff --git a/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs b/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs index 116be3f..66286cd 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs @@ -15,8 +15,8 @@ namespace Modbus.Net.OPC Wrapper = new OpcDaProtocal(ConnectionString); } - public override bool GetLittleEndian => Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian; - public override bool SetLittleEndian => Wrapper[typeof (WriteRequestOpcProtocal)].IsLittleEndian; + public override Endian GetLittleEndian => Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian; + public override Endian SetLittleEndian => Wrapper[typeof (WriteRequestOpcProtocal)].IsLittleEndian; public override void SetConnectionType(int connectionType) { diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs index 1778dd3..8637e1a 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs @@ -20,12 +20,12 @@ namespace Modbus.Net.Siemens _com = com; } - public override byte[] SendReceive(bool isLittleEndian, params object[] content) + public override byte[] SendReceive(Endian isLittleEndian, params object[] content) { return AsyncHelper.RunSync(() => SendReceiveAsync(isLittleEndian, content)); } - public override async Task SendReceiveAsync(bool isLittleEndian, params object[] content) + public override async Task SendReceiveAsync(Endian isLittleEndian, params object[] content) { if (ProtocalLinker == null || !ProtocalLinker.IsConnected) { diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs index 7d042a2..c53e33f 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs @@ -41,12 +41,12 @@ namespace Modbus.Net.Siemens _connectTryCount = 0; } - public override byte[] SendReceive(bool isLittleEndian, params object[] content) + public override byte[] SendReceive(Endian isLittleEndian, params object[] content) { return AsyncHelper.RunSync(() => SendReceiveAsync(isLittleEndian, content)); } - public override async Task SendReceiveAsync(bool isLittleEndian, params object[] content) + public override async Task SendReceiveAsync(Endian isLittleEndian, params object[] content) { if (ProtocalLinker == null || !ProtocalLinker.IsConnected) { diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs index 97db5f0..588c298 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs @@ -91,8 +91,8 @@ namespace Modbus.Net.Siemens AddressTranslator = new AddressTranslatorSiemens(); } - public override bool GetLittleEndian => Wrapper[typeof (ReadRequestSiemensProtocal)].IsLittleEndian; - public override bool SetLittleEndian => Wrapper[typeof (WriteRequestSiemensProtocal)].IsLittleEndian; + public override Endian GetLittleEndian => Wrapper[typeof (ReadRequestSiemensProtocal)].IsLittleEndian; + public override Endian SetLittleEndian => Wrapper[typeof (WriteRequestSiemensProtocal)].IsLittleEndian; protected string ConnectionStringIp { diff --git a/Modbus.Net/Modbus.Net/BaseMachine.cs b/Modbus.Net/Modbus.Net/BaseMachine.cs index fc42fe4..b67a8f4 100644 --- a/Modbus.Net/Modbus.Net/BaseMachine.cs +++ b/Modbus.Net/Modbus.Net/BaseMachine.cs @@ -257,13 +257,17 @@ namespace Modbus.Net { PlcValue = Convert.ToDouble( - BaseUtility.GetLittleEndian + BaseUtility.GetLittleEndian == Endian.LittleEndianLsb ? ValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos, address.DataType) .ToString() - : BigEndianValueHelper.Instance.GetValue(datas, ref localMainPos, - ref localSubPos, - address.DataType))*address.Zoom, + : BaseUtility.GetLittleEndian == Endian.BigEndianLsb + ? BigEndianValueHelper.Instance.GetValue(datas, ref localMainPos, + ref localSubPos, + address.DataType) + : BigEndianMsbValueHelper.Instance.GetValue(datas, ref localMainPos, + ref localSubPos, + address.DataType))*address.Zoom, UnitExtend = address.UnitExtend }); } @@ -374,9 +378,11 @@ namespace Modbus.Net BigEndianValueHelper.Instance.ByteLength[ communicateAddress.DataType.FullName])); - var valueHelper = BaseUtility.SetLittleEndian + var valueHelper = BaseUtility.SetLittleEndian == Endian.LittleEndianLsb ? ValueHelper.Instance - : BigEndianValueHelper.Instance; + : BaseUtility.SetLittleEndian == Endian.BigEndianLsb + ? BigEndianValueHelper.Instance + : BigEndianMsbValueHelper.Instance; //如果设备本身能获取到数据但是没有数据 var datas = datasReturn; diff --git a/Modbus.Net/Modbus.Net/BaseProtocal.cs b/Modbus.Net/Modbus.Net/BaseProtocal.cs index f74b6d7..58f2b80 100644 --- a/Modbus.Net/Modbus.Net/BaseProtocal.cs +++ b/Modbus.Net/Modbus.Net/BaseProtocal.cs @@ -72,7 +72,7 @@ namespace Modbus.Net /// 是否是小端格式 /// 写入的内容,使用对象数组描述 /// 从设备获取的字节流 - public virtual byte[] SendReceive(bool isLittleEndian, params object[] content) + public virtual byte[] SendReceive(Endian isLittleEndian, params object[] content) { return AsyncHelper.RunSync(() => SendReceiveAsync(isLittleEndian, content)); } @@ -83,7 +83,7 @@ namespace Modbus.Net /// 是否是小端格式 /// 写入的内容,使用对象数组描述 /// 从设备获取的字节流 - public virtual async Task SendReceiveAsync(bool isLittleEndian, params object[] content) + public virtual async Task SendReceiveAsync(Endian isLittleEndian, params object[] content) { if (ProtocalLinker == null || !ProtocalLinker.IsConnected) { diff --git a/Modbus.Net/Modbus.Net/BaseUtility.cs b/Modbus.Net/Modbus.Net/BaseUtility.cs index f2b2a7b..77c7fa2 100644 --- a/Modbus.Net/Modbus.Net/BaseUtility.cs +++ b/Modbus.Net/Modbus.Net/BaseUtility.cs @@ -3,8 +3,17 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +public enum Endian +{ + LittleEndianLsb, + BigEndianLsb, + BigEndianMsb +} + namespace Modbus.Net { + + /// /// 基础Api入口 /// @@ -33,12 +42,12 @@ namespace Modbus.Net /// /// 获取协议是否遵循小端格式 /// - public abstract bool GetLittleEndian { get; } + public abstract Endian GetLittleEndian { get; } /// /// 设置协议是否遵循小端格式 /// - public abstract bool SetLittleEndian { get; } + public abstract Endian SetLittleEndian { get; } /// /// 设备是否已经连接 @@ -108,9 +117,22 @@ namespace Modbus.Net var getReturnValue = await GetDatasAsync(startAddress, (int) Math.Ceiling(bCount*getTypeAndCount.Value)); var getBytes = getReturnValue; - return GetLittleEndian - ? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount) - : BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount); + switch (GetLittleEndian) + { + case Endian.LittleEndianLsb: + { + return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount); + } + case Endian.BigEndianLsb: + { + return BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount); + } + case Endian.BigEndianMsb: + { + return BigEndianMsbValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount); + } + } + return null; } catch (Exception) { @@ -185,9 +207,22 @@ namespace Modbus.Net select (int) Math.Ceiling(bCount*getTypeAndCount.Value)).Sum(); var getReturnValue = await GetDatasAsync(startAddress, bAllCount); var getBytes = getReturnValue; - return GetLittleEndian - ? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount) - : BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount); + switch (GetLittleEndian) + { + case Endian.LittleEndianLsb: + { + return ValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount); + } + case Endian.BigEndianLsb: + { + return BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount); + } + case Endian.BigEndianMsb: + { + return BigEndianMsbValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount); + } + } + return null; } catch (Exception) { diff --git a/Modbus.Net/Modbus.Net/ProtocalUnit.cs b/Modbus.Net/Modbus.Net/ProtocalUnit.cs index 2c24d23..9ebf06f 100644 --- a/Modbus.Net/Modbus.Net/ProtocalUnit.cs +++ b/Modbus.Net/Modbus.Net/ProtocalUnit.cs @@ -10,11 +10,11 @@ namespace Modbus.Net /// /// 是否为小端格式 /// - public bool IsLittleEndian { get; protected set; } = false; + public Endian IsLittleEndian { get; protected set; } = Endian.BigEndianLsb; /// /// 从输入结构格式化 - /// + /// s /// 结构化的输入数据 /// 格式化后的字节流 public abstract byte[] Format(IInputStruct message); @@ -43,11 +43,24 @@ namespace Modbus.Net /// 是否是小端格式 /// 对象数组 /// 字节数组 - public static byte[] TranslateContent(bool isLittleEndian, params object[] contents) + public static byte[] TranslateContent(Endian isLittleEndian, params object[] contents) { - return isLittleEndian - ? ValueHelper.Instance.ObjectArrayToByteArray(contents) - : BigEndianValueHelper.Instance.ObjectArrayToByteArray(contents); + switch (isLittleEndian) + { + case Endian.LittleEndianLsb: + { + return ValueHelper.Instance.ObjectArrayToByteArray(contents); + } + case Endian.BigEndianLsb: + { + return BigEndianValueHelper.Instance.ObjectArrayToByteArray(contents); + } + case Endian.BigEndianMsb: + { + return BigEndianMsbValueHelper.Instance.ObjectArrayToByteArray(contents); + } + } + return null; } } diff --git a/Modbus.Net/Modbus.Net/ValueHelper.cs b/Modbus.Net/Modbus.Net/ValueHelper.cs index ff1d67d..ec45b50 100644 --- a/Modbus.Net/Modbus.Net/ValueHelper.cs +++ b/Modbus.Net/Modbus.Net/ValueHelper.cs @@ -822,7 +822,7 @@ namespace Modbus.Net /// 设置位置 /// 设置bit大小,true为1,false为0 /// - public byte SetBit(byte number, int subPos, bool setBit) + protected byte SetBit(byte number, int subPos, bool setBit) { var creation = 0; if (setBit) @@ -1013,6 +1013,19 @@ namespace Modbus.Net public class BigEndianMsbValueHelper : BigEndianValueHelper { + private static BigEndianValueHelper _bigEndianInstance; + + protected BigEndianMsbValueHelper() + { + } + + protected override ValueHelper _Instance => _bigEndianInstance; + + protected new bool LittleEndian => false; + + public new static BigEndianValueHelper Instance + => _bigEndianInstance ?? (_bigEndianInstance = new BigEndianMsbValueHelper()); + public override bool GetBit(byte[] number, ref int pos, ref int subPos) { if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException();