From 0d19567038891e28c03af15b33bc8eef5c5f0499 Mon Sep 17 00:00:00 2001 From: parallelbgls Date: Mon, 6 Feb 2017 17:15:54 +0800 Subject: [PATCH] 2017-02-06 update 1 Add AddressHelper and comments, reformat code. --- .../AddressFormaterModbus.cs | 12 +- .../AddressTranslatorModbus.cs | 219 ++++++-- .../Modbus.Net.Modbus/ModbusAsciiProtocal.cs | 18 +- .../ModbusAsciiProtocalLinker.cs | 18 +- Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs | 2 +- .../Modbus.Net.Modbus/ModbusProtocal.cs | 243 +++++---- .../ModbusProtocalLinkerBytesExtend.cs | 28 +- .../Modbus.Net.Modbus/ModbusRtuProtocal.cs | 10 +- .../ModbusRtuProtocalLinker.cs | 13 +- .../Modbus.Net.Modbus/ModbusTcpProtocal.cs | 10 +- .../ModbusTcpProtocalLinker.cs | 20 +- Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs | 82 +-- .../Modbus.Net.OPC/AddressFormaterOpc.cs | 22 +- .../Modbus.Net.OPC/AddressTranslatorOpc.cs | 6 +- Modbus.Net/Modbus.Net.OPC/DaClientExtend.cs | 33 +- Modbus.Net/Modbus.Net.OPC/OpcDaConnector.cs | 45 +- Modbus.Net/Modbus.Net.OPC/OpcDaMachine.cs | 10 +- Modbus.Net/Modbus.Net.OPC/OpcDaProtocal.cs | 11 +- .../Modbus.Net.OPC/OpcDaProtocalLinker.cs | 11 +- Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs | 23 +- Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs | 27 +- .../AddressFormaterSiemens.cs | 10 +- .../AddressTranslatorSiemens.cs | 25 +- .../Modbus.Net.Siemens/SiemensMachine.cs | 2 +- .../Modbus.Net.Siemens/SiemensPpiProtocal.cs | 46 +- .../SiemensPpiProtocalLinker.cs | 25 +- .../Modbus.Net.Siemens/SiemensProtocal.cs | 250 ++++----- .../SiemensProtocalLinkerBytesExtend.cs | 19 +- .../SiemensStructDefinition.cs | 3 +- .../Modbus.Net.Siemens/SiemensTcpProtocal.cs | 17 +- .../SiemensTcpProtocalLinker.cs | 26 +- .../Modbus.Net.Siemens/SiemensUtility.cs | 141 ++--- Modbus.Net/Modbus.Net/AddressCombiner.cs | 167 ++++-- Modbus.Net/Modbus.Net/AddressFormater.cs | 13 +- Modbus.Net/Modbus.Net/AddressHelper.cs | 98 ++++ Modbus.Net/Modbus.Net/AddressTranslator.cs | 31 +- Modbus.Net/Modbus.Net/AsyncHelper.cs | 62 ++- Modbus.Net/Modbus.Net/BaseConnector.cs | 34 +- Modbus.Net/Modbus.Net/BaseMachine.cs | 336 +++++++----- Modbus.Net/Modbus.Net/BaseMachineExtend.cs | 18 +- Modbus.Net/Modbus.Net/BaseProtocal.cs | 55 +- Modbus.Net/Modbus.Net/BaseUtility.cs | 119 ++-- Modbus.Net/Modbus.Net/CRC16.cs | 104 ++-- Modbus.Net/Modbus.Net/ComConnector.cs | 505 +++++++++-------- Modbus.Net/Modbus.Net/ComProtocalLinker.cs | 13 +- Modbus.Net/Modbus.Net/IProtocalFormatting.cs | 8 +- Modbus.Net/Modbus.Net/Modbus.Net.csproj | 1 + Modbus.Net/Modbus.Net/ProtocalLinker.cs | 53 +- .../Modbus.Net/ProtocalLinkerBytesExtend.cs | 12 +- Modbus.Net/Modbus.Net/ProtocalUnit.cs | 24 +- Modbus.Net/Modbus.Net/README.md | 18 +- Modbus.Net/Modbus.Net/TaskManager.cs | 287 +++++----- Modbus.Net/Modbus.Net/TcpConnector.cs | 101 ++-- Modbus.Net/Modbus.Net/TcpProtocalLinker.cs | 13 +- Modbus.Net/Modbus.Net/ValueHelper.cs | 512 +++++++++--------- 55 files changed, 2190 insertions(+), 1821 deletions(-) create mode 100644 Modbus.Net/Modbus.Net/AddressHelper.cs diff --git a/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs b/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs index 52efd63..06a832e 100644 --- a/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs +++ b/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Modbus.Net.Modbus +namespace Modbus.Net.Modbus { public class AddressFormaterNA200H : AddressFormater { @@ -28,7 +22,7 @@ namespace Modbus.Net.Modbus public override string FormatAddress(string area, int address, int subAddress) { - return area + " " + address + "." + subAddress; + return area + " " + address + "." + subAddress; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs b/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs index 8ba91f1..29a8b00 100644 --- a/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs +++ b/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs @@ -1,18 +1,15 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Modbus.Net.Modbus { /// - /// NA200H数据单元翻译器 + /// NA200H数据单元翻译器 /// public class AddressTranslatorNA200H : AddressTranslator { - protected Dictionary TransDictionary; protected Dictionary ReadFunctionCodeDictionary; + protected Dictionary TransDictionary; protected Dictionary WriteFunctionCodeDictionary; public AddressTranslatorNA200H() @@ -26,44 +23,136 @@ namespace Modbus.Net.Modbus {"S", 10000}, {"IW", 0}, {"SW", 5000}, - {"MW", 0}, + {"MW", 0}, {"QW", 20000}, - {"NW", 21000}, + {"NW", 21000} }; ReadFunctionCodeDictionary = new Dictionary { - {"Q", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}}, - {"M", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}}, - {"N", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}}, - {"I", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus, AreaWidth = 0.125}}, - {"S", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus, AreaWidth = 0.125}}, - {"IW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2}}, - {"SW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2}}, - {"MW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}}, - {"NW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}}, - {"QW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}}, + { + "Q", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadCoilStatus, + AreaWidth = 0.125 + } + }, + { + "M", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadCoilStatus, + AreaWidth = 0.125 + } + }, + { + "N", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadCoilStatus, + AreaWidth = 0.125 + } + }, + { + "I", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadInputStatus, + AreaWidth = 0.125 + } + }, + { + "S", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadInputStatus, + AreaWidth = 0.125 + } + }, + { + "IW", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2} + }, + { + "SW", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2} + }, + { + "MW", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2} + }, + { + "NW", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2} + }, + { + "QW", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2} + } }; WriteFunctionCodeDictionary = new Dictionary { - {"Q", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}}, - {"M", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}}, - {"N", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}}, - {"MW", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}}, - {"NW", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}}, - {"QW", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}}, + { + "Q", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, + AreaWidth = 0.125 + } + }, + { + "M", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, + AreaWidth = 0.125 + } + }, + { + "N", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, + AreaWidth = 0.125 + } + }, + { + "MW", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, + AreaWidth = 2 + } + }, + { + "NW", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, + AreaWidth = 2 + } + }, + { + "QW", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, + AreaWidth = 2 + } + } }; } public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); - string[] splitString = address.Split(' '); - string head = splitString[0]; - string tail = splitString[1]; + var splitString = address.Split(' '); + var head = splitString[0]; + var tail = splitString[1]; string sub; if (tail.Contains('.')) { - string[] splitString2 = tail.Split('.'); + var splitString2 = tail.Split('.'); sub = splitString2[1]; tail = splitString2[0]; } @@ -72,19 +161,19 @@ namespace Modbus.Net.Modbus sub = "0"; } return isRead - ? new AddressDef() + ? new AddressDef { AreaString = head, Area = ReadFunctionCodeDictionary[head].Code, Address = TransDictionary[head] + int.Parse(tail) - 1, - SubAddress = int.Parse(sub), + SubAddress = int.Parse(sub) } - : new AddressDef() + : new AddressDef { AreaString = head, Area = WriteFunctionCodeDictionary[head].Code, Address = TransDictionary[head] + int.Parse(tail) - 1, - SubAddress = int.Parse(sub), + SubAddress = int.Parse(sub) }; } @@ -95,7 +184,7 @@ namespace Modbus.Net.Modbus } /// - /// Modbus数据单元翻译器 + /// Modbus数据单元翻译器 /// public class AddressTranslatorModbus : AddressTranslator { @@ -106,28 +195,62 @@ namespace Modbus.Net.Modbus { ReadFunctionCodeDictionary = new Dictionary { - {"0X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}}, - {"1X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus, AreaWidth = 0.125}}, - {"3X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2}}, - {"4X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}}, + { + "0X", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadCoilStatus, + AreaWidth = 0.125 + } + }, + { + "1X", + new AreaOutputDef + { + Code = (int) ModbusProtocalReadDataFunctionCode.ReadInputStatus, + AreaWidth = 0.125 + } + }, + { + "3X", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2} + }, + { + "4X", + new AreaOutputDef {Code = (int) ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2} + } }; WriteFunctionCodeDictionary = new Dictionary { - {"0X", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}}, - {"4X", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}}, + { + "0X", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, + AreaWidth = 0.125 + } + }, + { + "4X", + new AreaOutputDef + { + Code = (int) ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, + AreaWidth = 2 + } + } }; } public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); - string[] splitString = address.Split(' '); - string head = splitString[0]; - string tail = splitString[1]; + var splitString = address.Split(' '); + var head = splitString[0]; + var tail = splitString[1]; string sub; if (tail.Contains('.')) { - string[] splitString2 = tail.Split('.'); + var splitString2 = tail.Split('.'); sub = splitString2[1]; tail = splitString2[0]; } @@ -136,19 +259,19 @@ namespace Modbus.Net.Modbus sub = "0"; } return isRead - ? new AddressDef() + ? new AddressDef { AreaString = head, Area = ReadFunctionCodeDictionary[head].Code, Address = int.Parse(tail) - 1, - SubAddress = int.Parse(sub), + SubAddress = int.Parse(sub) } - : new AddressDef() + : new AddressDef { AreaString = head, Area = WriteFunctionCodeDictionary[head].Code, Address = int.Parse(tail) - 1, - SubAddress = int.Parse(sub), + SubAddress = int.Parse(sub) }; } @@ -157,4 +280,4 @@ namespace Modbus.Net.Modbus return ReadFunctionCodeDictionary[area].AreaWidth; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs index cc1224f..43f93fd 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocal.cs @@ -1,23 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Modbus.Net.Modbus +namespace Modbus.Net.Modbus { /// - /// Modbus/Rtu协议 + /// Modbus/Rtu协议 /// public class ModbusAsciiProtocal : ModbusProtocal { - public ModbusAsciiProtocal(byte belongAddress, byte masterAddress) : this(ConfigurationManager.COM, belongAddress, masterAddress) + public ModbusAsciiProtocal(byte slaveAddress, byte masterAddress) + : this(ConfigurationManager.COM, slaveAddress, masterAddress) { } - public ModbusAsciiProtocal(string com, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + public ModbusAsciiProtocal(string com, byte slaveAddress, byte masterAddress) + : base(slaveAddress, masterAddress) { ProtocalLinker = new ModbusAsciiProtocalLinker(com); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs index 36c9068..5609f8f 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusAsciiProtocalLinker.cs @@ -1,19 +1,19 @@ -using System; -using System.Collections.Generic; -using System.IO.Ports; -using System.Linq; +using System.IO.Ports; using System.Text; -using System.Threading.Tasks; namespace Modbus.Net.Modbus { public class ModbusAsciiProtocalLinker : ComProtocalLinker { + public ModbusAsciiProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8) + { + } + public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; //CRC校验失败 - string contentString = Encoding.ASCII.GetString(content); + var contentString = Encoding.ASCII.GetString(content); if (!Crc16.GetInstance().LrcEfficacy(contentString)) { throw new ModbusProtocalErrorException(501); @@ -25,9 +25,5 @@ namespace Modbus.Net.Modbus } return true; } - - public ModbusAsciiProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8) - { - } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs index 4511a79..9b41863 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusMachine.cs @@ -20,4 +20,4 @@ namespace Modbus.Net.Modbus { } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs index 9357966..71e2456 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocal.cs @@ -7,40 +7,44 @@ namespace Modbus.Net.Modbus internal enum ModbusProtocalVariableFunctionCode : byte { ReadVariable = 20, - WriteVariable = 21, + WriteVariable = 21 } /// - /// 跟时间有关的功能码 + /// 跟时间有关的功能码 /// public enum ModbusProtocalTimeFunctionCode : byte { GetSystemTime = 3, - SetSystemTime = 16, + SetSystemTime = 16 } /// - /// 跟读数据有关的功能码 + /// 跟读数据有关的功能码 /// public enum ModbusProtocalReadDataFunctionCode : byte { ReadCoilStatus = 1, ReadInputStatus = 2, ReadHoldRegister = 3, - ReadInputRegister = 4, + ReadInputRegister = 4 } /// - /// 跟写数据有关的功能码 + /// 跟写数据有关的功能码 /// internal enum ModbusProtocalWriteDataFunctionCode : byte { WriteMultiCoil = 15, - WriteMultiRegister = 16, + WriteMultiRegister = 16 } public abstract class ModbusProtocal : BaseProtocal { + protected ModbusProtocal(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) + { + } + public override bool Connect() { return ProtocalLinker.Connect(); @@ -50,45 +54,43 @@ namespace Modbus.Net.Modbus { return await ProtocalLinker.ConnectAsync(); } - - protected ModbusProtocal(byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) - { - } } #region 读PLC数据 + public class ReadDataModbusInputStruct : InputStruct { - public ReadDataModbusInputStruct(byte belongAddress, string startAddress, ushort getCount, AddressTranslator addressTranslator) + public ReadDataModbusInputStruct(byte slaveAddress, string startAddress, ushort getCount, + AddressTranslator addressTranslator) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; var translateAddress = addressTranslator.AddressTranslate(startAddress, true); - FunctionCode = (byte)translateAddress.Area; - StartAddress = (ushort)translateAddress.Address; - GetCount = (ushort)Math.Ceiling(getCount / addressTranslator.GetAreaByteLength(translateAddress.AreaString)); + FunctionCode = (byte) translateAddress.Area; + StartAddress = (ushort) translateAddress.Address; + GetCount = (ushort) Math.Ceiling(getCount/addressTranslator.GetAreaByteLength(translateAddress.AreaString)); } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; } - public byte FunctionCode { get; private set; } + public byte FunctionCode { get; } - public ushort StartAddress { get; private set; } + public ushort StartAddress { get; } - public ushort GetCount { get; private set; } + public ushort GetCount { get; } } public class ReadDataModbusOutputStruct : OutputStruct { - public ReadDataModbusOutputStruct(byte belongAddress, byte functionCode, + public ReadDataModbusOutputStruct(byte slaveAddress, byte functionCode, int dataCount, byte[] dataValue) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; FunctionCode = functionCode; DataCount = dataCount; DataValue = dataValue.Clone() as byte[]; } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; private set; } public byte FunctionCode { get; private set; } @@ -101,71 +103,74 @@ namespace Modbus.Net.Modbus { public override byte[] Format(InputStruct message) { - var r_message = (ReadDataModbusInputStruct)message; - return Format(r_message.BelongAddress, r_message.FunctionCode, + var r_message = (ReadDataModbusInputStruct) message; + return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount); } public override OutputStruct Unformat(byte[] messageBytes, ref int pos) { - byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - byte dataCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - byte[] dataValue = new byte[dataCount]; + var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + var dataCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + var dataValue = new byte[dataCount]; Array.Copy(messageBytes, 3, dataValue, 0, dataCount); if (functionCode == 1 || functionCode == 2) { - for (int i = 0; i < dataValue.Length; i++) + for (var i = 0; i < dataValue.Length; i++) { dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]); } } - return new ReadDataModbusOutputStruct(belongAddress, functionCode, dataCount, dataValue); + return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue); } } #endregion #region 写PLC数据 + public class WriteDataModbusInputStruct : InputStruct { - public WriteDataModbusInputStruct(byte belongAddress, string startAddress, object[] writeValue, AddressTranslator addressTranslator) + public WriteDataModbusInputStruct(byte slaveAddress, string startAddress, object[] writeValue, + AddressTranslator addressTranslator) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; var translateAddress = addressTranslator.AddressTranslate(startAddress, false); - FunctionCode = (byte)translateAddress.Area; - StartAddress = (ushort)translateAddress.Address; + FunctionCode = (byte) translateAddress.Area; + StartAddress = (ushort) translateAddress.Address; var writeByteValue = BigEndianValueHelper.Instance.ObjectArrayToByteArray(writeValue); - WriteCount = (ushort)(writeByteValue.Length / addressTranslator.GetAreaByteLength(translateAddress.AreaString)); - WriteByteCount = (byte)writeByteValue.Length; + WriteCount = + (ushort) (writeByteValue.Length/addressTranslator.GetAreaByteLength(translateAddress.AreaString)); + WriteByteCount = (byte) writeByteValue.Length; WriteValue = writeByteValue; } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; } - public byte FunctionCode { get; private set; } + public byte FunctionCode { get; } - public ushort StartAddress { get; private set; } + public ushort StartAddress { get; } - public ushort WriteCount { get; private set; } + public ushort WriteCount { get; } - public byte WriteByteCount { get; private set; } + public byte WriteByteCount { get; } - public byte[] WriteValue { get; private set; } + public byte[] WriteValue { get; } } public class WriteDataModbusOutputStruct : OutputStruct { - public WriteDataModbusOutputStruct(byte belongAddress, byte functionCode, + public WriteDataModbusOutputStruct(byte slaveAddress, byte functionCode, ushort startAddress, ushort writeCount) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; FunctionCode = functionCode; StartAddress = startAddress; WriteCount = writeCount; } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; private set; } public byte FunctionCode { get; private set; } @@ -175,34 +180,34 @@ namespace Modbus.Net.Modbus } /// - /// 写多个寄存器状态 + /// 写多个寄存器状态 /// public class WriteDataModbusProtocal : ProtocalUnit { public override byte[] Format(InputStruct message) { - var r_message = (WriteDataModbusInputStruct)message; + var r_message = (WriteDataModbusInputStruct) message; var functionCode = r_message.FunctionCode; - byte[] dataValue = Format(r_message.WriteValue); + var dataValue = Format(r_message.WriteValue); if (functionCode == 5 || functionCode == 15) { - for (int i = 0; i < dataValue.Length; i++) + for (var i = 0; i < dataValue.Length; i++) { dataValue[i] = BigEndianValueHelper.Instance.ReverseByte(dataValue[i]); } } - byte[] formattingBytes = Format(r_message.BelongAddress, r_message.FunctionCode, + var formattingBytes = Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, dataValue); return formattingBytes; } public override OutputStruct Unformat(byte[] messageBytes, ref int flag) { - byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - ushort startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - ushort writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - return new WriteDataModbusOutputStruct(belongAddress, functionCode, startAddress, + var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + var writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + return new WriteDataModbusOutputStruct(slaveAddress, functionCode, startAddress, writeCount); } } @@ -210,38 +215,39 @@ namespace Modbus.Net.Modbus #endregion #region 读PLC时间 + public class GetSystemTimeModbusInputStruct : InputStruct { - public GetSystemTimeModbusInputStruct(byte belongAddress) + public GetSystemTimeModbusInputStruct(byte slaveAddress) { - BelongAddress = belongAddress; - FunctionCode = (byte)ModbusProtocalTimeFunctionCode.GetSystemTime; + SlaveAddress = slaveAddress; + FunctionCode = (byte) ModbusProtocalTimeFunctionCode.GetSystemTime; StartAddress = 30000; GetCount = 5; } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; } - public byte FunctionCode { get; private set; } + public byte FunctionCode { get; } - public ushort StartAddress { get; private set; } + public ushort StartAddress { get; } - public ushort GetCount { get; private set; } + public ushort GetCount { get; } } public class GetSystemTimeModbusOutputStruct : OutputStruct { - public GetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode, + public GetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode, byte writeByteCount, ushort year, byte day, byte month, ushort hour, byte second, byte minute, ushort millisecond) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; FunctionCode = functionCode; WriteByteCount = writeByteCount; Time = new DateTime(year, month, day, hour, minute, second, millisecond); } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; private set; } public byte FunctionCode { get; private set; } @@ -251,30 +257,30 @@ namespace Modbus.Net.Modbus } /// - /// 读系统时间 + /// 读系统时间 /// public class GetSystemTimeModbusProtocal : ProtocalUnit { public override byte[] Format(InputStruct message) { - var r_message = (GetSystemTimeModbusInputStruct)message; - return Format(r_message.BelongAddress, r_message.FunctionCode, + var r_message = (GetSystemTimeModbusInputStruct) message; + return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount); } public override OutputStruct Unformat(byte[] messageBytes, ref int flag) { - byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - byte writeByteCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - ushort year = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - byte day = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - byte month = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - ushort hour = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - byte second = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - byte minute = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - ushort millisecond = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - return new GetSystemTimeModbusOutputStruct(belongAddress, functionCode, writeByteCount, year, day, + var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var writeByteCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var year = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + var day = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var month = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var hour = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + var second = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var minute = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var millisecond = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + return new GetSystemTimeModbusOutputStruct(slaveAddress, functionCode, writeByteCount, year, day, month, hour, second, minute, millisecond); } } @@ -282,61 +288,62 @@ namespace Modbus.Net.Modbus #endregion #region 写PLC时间 + public class SetSystemTimeModbusInputStruct : InputStruct { - public SetSystemTimeModbusInputStruct(byte belongAddress, DateTime time) + public SetSystemTimeModbusInputStruct(byte slaveAddress, DateTime time) { - BelongAddress = belongAddress; - FunctionCode = (byte)ModbusProtocalTimeFunctionCode.SetSystemTime; + SlaveAddress = slaveAddress; + FunctionCode = (byte) ModbusProtocalTimeFunctionCode.SetSystemTime; StartAddress = 30000; WriteCount = 5; WriteByteCount = 10; - Year = (ushort)time.Year; - Day = (byte)time.Day; - Month = (byte)time.Month; - Hour = (ushort)time.Hour; - Second = (byte)time.Second; - Minute = (byte)time.Minute; - Millisecond = (ushort)time.Millisecond; + Year = (ushort) time.Year; + Day = (byte) time.Day; + Month = (byte) time.Month; + Hour = (ushort) time.Hour; + Second = (byte) time.Second; + Minute = (byte) time.Minute; + Millisecond = (ushort) time.Millisecond; } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; } - public byte FunctionCode { get; private set; } + public byte FunctionCode { get; } - public ushort StartAddress { get; private set; } + public ushort StartAddress { get; } - public ushort WriteCount { get; private set; } + public ushort WriteCount { get; } - public byte WriteByteCount { get; private set; } + public byte WriteByteCount { get; } - public ushort Year { get; private set; } + public ushort Year { get; } - public byte Day { get; private set; } + public byte Day { get; } - public byte Month { get; private set; } + public byte Month { get; } - public ushort Hour { get; private set; } + public ushort Hour { get; } - public byte Second { get; private set; } + public byte Second { get; } - public byte Minute { get; private set; } + public byte Minute { get; } - public ushort Millisecond { get; private set; } + public ushort Millisecond { get; } } public class SetSystemTimeModbusOutputStruct : OutputStruct { - public SetSystemTimeModbusOutputStruct(byte belongAddress, byte functionCode, + public SetSystemTimeModbusOutputStruct(byte slaveAddress, byte functionCode, ushort startAddress, ushort writeCount) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; FunctionCode = functionCode; StartAddress = startAddress; WriteCount = writeCount; } - public byte BelongAddress { get; private set; } + public byte SlaveAddress { get; private set; } public byte FunctionCode { get; private set; } @@ -346,14 +353,14 @@ namespace Modbus.Net.Modbus } /// - /// 写系统时间 + /// 写系统时间 /// public class SetSystemTimeModbusProtocal : ProtocalUnit { public override byte[] Format(InputStruct message) { - var r_message = (SetSystemTimeModbusInputStruct)message; - return Format(r_message.BelongAddress, r_message.FunctionCode, + var r_message = (SetSystemTimeModbusInputStruct) message; + return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.WriteCount, r_message.WriteByteCount, r_message.Year, r_message.Day, r_message.Month, r_message.Hour, r_message.Second, r_message.Minute, r_message.Millisecond); @@ -361,22 +368,22 @@ namespace Modbus.Net.Modbus public override OutputStruct Unformat(byte[] messageBytes, ref int flag) { - byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); - ushort startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - ushort writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); - return new SetSystemTimeModbusOutputStruct(belongAddress, functionCode, startAddress, writeCount); + var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref flag); + var startAddress = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + var writeCount = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref flag); + return new SetSystemTimeModbusOutputStruct(slaveAddress, functionCode, startAddress, writeCount); } } + #endregion /// - /// Modbus协议错误表 + /// Modbus协议错误表 /// public class ModbusProtocalErrorException : ProtocalErrorException { - public int ErrorMessageNumber { get; private set; } - private static readonly Dictionary ProtocalErrorDictionary = new Dictionary() + private static readonly Dictionary ProtocalErrorDictionary = new Dictionary { {1, "ILLEGAL_FUNCTION"}, {2, "ILLEGAL_DATA_ACCESS"}, @@ -385,7 +392,7 @@ namespace Modbus.Net.Modbus {5, "ACKNOWLWDGE"}, {6, "SLAVE_DEVICE_BUSY"}, {500, "TCP_ILLEGAL_LENGTH"}, - {501, "RTU_ILLEGAL_CRC"}, + {501, "RTU_ILLEGAL_CRC"} }; public ModbusProtocalErrorException(int messageNumber) @@ -393,5 +400,7 @@ namespace Modbus.Net.Modbus { ErrorMessageNumber = messageNumber; } + + public int ErrorMessageNumber { get; private set; } } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs index 44388bd..b3c375d 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocalLinkerBytesExtend.cs @@ -6,16 +6,16 @@ using System.Text; namespace Modbus.Net.Modbus { /// - /// Tcp协议字节伸缩 + /// Tcp协议字节伸缩 /// public class ModbusTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend { public override byte[] BytesExtend(byte[] content) { //Modbus/Tcp协议扩张,前面加6个字节,前面4个为0,后面两个为协议整体内容的长度 - byte[] newFormat = new byte[6 + content.Length]; - int tag = 0; - ushort leng = (ushort)content.Length; + var newFormat = new byte[6 + content.Length]; + var tag = 0; + var leng = (ushort) content.Length; Array.Copy(BigEndianValueHelper.Instance.GetBytes(tag), 0, newFormat, 0, 4); Array.Copy(BigEndianValueHelper.Instance.GetBytes(leng), 0, newFormat, 4, 2); Array.Copy(content, 0, newFormat, 6, content.Length); @@ -25,7 +25,7 @@ namespace Modbus.Net.Modbus public override byte[] BytesDecact(byte[] content) { //Modbus/Tcp协议收缩,抛弃前面6个字节的内容 - byte[] newContent = new byte[content.Length - 6]; + var newContent = new byte[content.Length - 6]; Array.Copy(content, 6, newContent, 0, newContent.Length); return newContent; } @@ -35,9 +35,9 @@ namespace Modbus.Net.Modbus { public override byte[] BytesExtend(byte[] content) { - byte[] crc = new byte[2]; + var crc = new byte[2]; //Modbus/Rtu协议扩张,增加CRC校验 - byte[] newFormat = new byte[content.Length + 2]; + var newFormat = new byte[content.Length + 2]; Crc16.GetInstance().GetCRC(content, ref crc); Array.Copy(content, 0, newFormat, 0, content.Length); Array.Copy(crc, 0, newFormat, newFormat.Length - 2, crc.Length); @@ -47,7 +47,7 @@ namespace Modbus.Net.Modbus public override byte[] BytesDecact(byte[] content) { //Modbus/Rtu协议收缩,抛弃后面2个字节的内容 - byte[] newContent = new byte[content.Length - 2]; + var newContent = new byte[content.Length - 2]; Array.Copy(content, 0, newContent, 0, newContent.Length); return newContent; } @@ -57,7 +57,7 @@ namespace Modbus.Net.Modbus { public override byte[] BytesExtend(byte[] content) { - List newContent = new List(); + var newContent = new List(); newContent.AddRange(Encoding.ASCII.GetBytes(":")); foreach (var number in content) { @@ -71,17 +71,17 @@ namespace Modbus.Net.Modbus public override byte[] BytesDecact(byte[] content) { - List newContent = new List(); - string ans = Encoding.ASCII.GetString(content); + var newContent = new List(); + var ans = Encoding.ASCII.GetString(content); var index = ans.IndexOf(Environment.NewLine); ans = ans.Substring(1, index - 1); - for (int i = 0; i < ans.Length; i += 2) + for (var i = 0; i < ans.Length; i += 2) { var number = byte.Parse(ans.Substring(i, 2), NumberStyles.HexNumber); newContent.Add(number); } - newContent.RemoveAt(newContent.Count-1); + newContent.RemoveAt(newContent.Count - 1); return newContent.ToArray(); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs index 9c846d5..2a97d60 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocal.cs @@ -1,17 +1,19 @@ namespace Modbus.Net.Modbus { /// - /// Modbus/Rtu协议 + /// Modbus/Rtu协议 /// public class ModbusRtuProtocal : ModbusProtocal { - public ModbusRtuProtocal(byte belongAddress, byte masterAddress) : this(ConfigurationManager.COM, belongAddress, masterAddress) + public ModbusRtuProtocal(byte slaveAddress, byte masterAddress) + : this(ConfigurationManager.COM, slaveAddress, masterAddress) { } - public ModbusRtuProtocal(string com, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + public ModbusRtuProtocal(string com, byte slaveAddress, byte masterAddress) + : base(slaveAddress, masterAddress) { ProtocalLinker = new ModbusRtuProtocalLinker(com); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs index be5353f..3fcbdfb 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusRtuProtocalLinker.cs @@ -2,8 +2,12 @@ namespace Modbus.Net.Modbus { - class ModbusRtuProtocalLinker : ComProtocalLinker + public class ModbusRtuProtocalLinker : ComProtocalLinker { + public ModbusRtuProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8) + { + } + public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; @@ -19,10 +23,5 @@ namespace Modbus.Net.Modbus } return true; } - - public ModbusRtuProtocalLinker(string com) : base(com, 9600, Parity.None, StopBits.One, 8) - { - - } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs index 3230d18..37d729c 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocal.cs @@ -1,20 +1,22 @@ namespace Modbus.Net.Modbus { /// - /// Modbus/Tcp协议 + /// Modbus/Tcp协议 /// public class ModbusTcpProtocal : ModbusProtocal { - public ModbusTcpProtocal(byte belongAddress, byte masterAddress) : this(ConfigurationManager.IP, belongAddress, masterAddress) + public ModbusTcpProtocal(byte slaveAddress, byte masterAddress) + : this(ConfigurationManager.IP, slaveAddress, masterAddress) { } - public ModbusTcpProtocal(string ip, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + public ModbusTcpProtocal(string ip, byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) { ProtocalLinker = new ModbusTcpProtocalLinker(ip); } - public ModbusTcpProtocal(string ip, int port, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + public ModbusTcpProtocal(string ip, int port, byte slaveAddress, byte masterAddress) + : base(slaveAddress, masterAddress) { ProtocalLinker = new ModbusTcpProtocalLinker(ip, port); } diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs index e54db16..9e1154d 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusTcpProtocalLinker.cs @@ -2,6 +2,14 @@ { public class ModbusTcpProtocalLinker : TcpProtocalLinker { + public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.ModbusPort)) + { + } + + public ModbusTcpProtocalLinker(string ip, int port) : base(ip, port) + { + } + public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; @@ -17,15 +25,5 @@ } return true; } - - public ModbusTcpProtocalLinker(string ip) : base(ip, int.Parse(ConfigurationManager.ModbusPort)) - { - - } - - public ModbusTcpProtocalLinker(string ip, int port) : base(ip, port) - { - - } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs index 4d0a3f6..65580f4 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusUtility.cs @@ -1,31 +1,48 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace Modbus.Net.Modbus { /// - /// Modbus连接类型 + /// Modbus连接类型 /// public enum ModbusType { /// - /// Rtu连接 + /// Rtu连接 /// Rtu = 0, + /// - /// Tcp连接 + /// Tcp连接 /// Tcp = 1, + /// - /// Ascii连接 + /// Ascii连接 /// - Ascii = 2, + Ascii = 2 } public class ModbusUtility : BaseUtility { private ModbusType _modbusType; + public ModbusUtility(int connectionType, byte slaveAddress, byte masterAddress) + : base(slaveAddress, masterAddress) + { + ConnectionString = null; + ModbusType = (ModbusType) connectionType; + AddressTranslator = new AddressTranslatorModbus(); + } + + public ModbusUtility(ModbusType connectionType, string connectionString, byte slaveAddress, byte masterAddress) + : base(slaveAddress, masterAddress) + { + ConnectionString = connectionString; + ModbusType = connectionType; + AddressTranslator = new AddressTranslatorModbus(); + } + public override bool GetLittleEndian => Wrapper[typeof (ReadDataModbusProtocal)].IsLittleEndian; public override bool SetLittleEndian => Wrapper[typeof (WriteDataModbusProtocal)].IsLittleEndian; @@ -47,22 +64,18 @@ namespace Modbus.Net.Modbus var connectionStringSplit = ConnectionString.Split(':'); try { - return connectionStringSplit.Length < 2 ? (int?)null : int.Parse(connectionStringSplit[1]); + return connectionStringSplit.Length < 2 ? (int?) null : int.Parse(connectionStringSplit[1]); } catch { return null; } - } } public ModbusType ModbusType { - get - { - return _modbusType; - } + get { return _modbusType; } set { _modbusType = value; @@ -70,37 +83,32 @@ namespace Modbus.Net.Modbus { case ModbusType.Rtu: { - Wrapper = ConnectionString == null ? new ModbusRtuProtocal(BelongAddress, MasterAddress) : new ModbusRtuProtocal(ConnectionString, BelongAddress, MasterAddress); + Wrapper = ConnectionString == null + ? new ModbusRtuProtocal(SlaveAddress, MasterAddress) + : new ModbusRtuProtocal(ConnectionString, SlaveAddress, MasterAddress); break; } case ModbusType.Tcp: { - Wrapper = ConnectionString == null ? new ModbusTcpProtocal(BelongAddress, MasterAddress) : (ConnectionStringPort == null ? new ModbusTcpProtocal(ConnectionString, BelongAddress, MasterAddress) : new ModbusTcpProtocal(ConnectionStringIp,ConnectionStringPort.Value, BelongAddress, MasterAddress)); + Wrapper = ConnectionString == null + ? new ModbusTcpProtocal(SlaveAddress, MasterAddress) + : (ConnectionStringPort == null + ? new ModbusTcpProtocal(ConnectionString, SlaveAddress, MasterAddress) + : new ModbusTcpProtocal(ConnectionStringIp, ConnectionStringPort.Value, SlaveAddress, + MasterAddress)); break; } case ModbusType.Ascii: { - Wrapper = ConnectionString == null ? new ModbusAsciiProtocal(BelongAddress, MasterAddress) : new ModbusAsciiProtocal(ConnectionString, BelongAddress, MasterAddress); + Wrapper = ConnectionString == null + ? new ModbusAsciiProtocal(SlaveAddress, MasterAddress) + : new ModbusAsciiProtocal(ConnectionString, SlaveAddress, MasterAddress); break; } } } } - public ModbusUtility(int connectionType, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) - { - ConnectionString = null; - ModbusType = (ModbusType)connectionType; - AddressTranslator = new AddressTranslatorModbus(); - } - - public ModbusUtility(ModbusType connectionType, string connectionString, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) - { - ConnectionString = connectionString; - ModbusType = connectionType; - AddressTranslator = new AddressTranslatorModbus(); - } - public override void SetConnectionType(int connectionType) { ModbusType = (ModbusType) connectionType; @@ -110,12 +118,12 @@ namespace Modbus.Net.Modbus { try { - var inputStruct = new ReadDataModbusInputStruct(BelongAddress, startAddress, - (ushort)getByteCount, AddressTranslator); + var inputStruct = new ReadDataModbusInputStruct(SlaveAddress, startAddress, + (ushort) getByteCount, AddressTranslator); var outputStruct = await Wrapper.SendReceiveAsync(Wrapper[typeof (ReadDataModbusProtocal)], inputStruct) as ReadDataModbusOutputStruct; - return outputStruct?.DataValue; + return outputStruct?.DataValue; } catch { @@ -127,7 +135,7 @@ namespace Modbus.Net.Modbus { try { - var inputStruct = new WriteDataModbusInputStruct(BelongAddress, startAddress, setContents, + var inputStruct = new WriteDataModbusInputStruct(SlaveAddress, startAddress, setContents, AddressTranslator); var outputStruct = await Wrapper.SendReceiveAsync(Wrapper[typeof (WriteDataModbusProtocal)], inputStruct) as @@ -145,7 +153,7 @@ namespace Modbus.Net.Modbus { try { - var inputStruct = new GetSystemTimeModbusInputStruct(BelongAddress); + var inputStruct = new GetSystemTimeModbusInputStruct(SlaveAddress); var outputStruct = Wrapper.SendReceive(Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct) as GetSystemTimeModbusOutputStruct; @@ -161,7 +169,7 @@ namespace Modbus.Net.Modbus { try { - var inputStruct = new SetSystemTimeModbusInputStruct(BelongAddress, setTime); + var inputStruct = new SetSystemTimeModbusInputStruct(SlaveAddress, setTime); var outputStruct = Wrapper.SendReceive(Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct) as SetSystemTimeModbusOutputStruct; @@ -174,4 +182,4 @@ namespace Modbus.Net.Modbus } */ } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs b/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs index 011db96..9bc6d1d 100644 --- a/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs +++ b/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs @@ -1,33 +1,31 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Modbus.Net.OPC { public class AddressFormaterOpc : AddressFormater { - public BaseMachine Machine { get; set; } - - protected Func TagGeter { get; set; } - - protected char Seperator { get; set; } - - public AddressFormaterOpc(Func tagGeter, BaseMachine machine, char seperator = '/') + public AddressFormaterOpc(Func tagGeter, BaseMachine machine, + char seperator = '/') { Machine = machine; TagGeter = tagGeter; Seperator = seperator; } + public BaseMachine Machine { get; set; } + + protected Func TagGeter { get; set; } + + protected char Seperator { get; set; } + public override string FormatAddress(string area, int address) { var findAddress = Machine?.GetAddresses.FirstOrDefault(p => p.Area == area && p.Address == address); if (findAddress == null) return null; var strings = TagGeter(Machine, findAddress); var ans = ""; - for (int i = 0; i < strings.Length; i++) + for (var i = 0; i < strings.Length; i++) { ans += strings[i].Trim().Replace(" ", "") + Seperator; } @@ -40,4 +38,4 @@ namespace Modbus.Net.OPC return FormatAddress(area, address); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/AddressTranslatorOpc.cs b/Modbus.Net/Modbus.Net.OPC/AddressTranslatorOpc.cs index 733d772..31d8f37 100644 --- a/Modbus.Net/Modbus.Net.OPC/AddressTranslatorOpc.cs +++ b/Modbus.Net/Modbus.Net.OPC/AddressTranslatorOpc.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Modbus.Net.OPC { @@ -18,4 +14,4 @@ namespace Modbus.Net.OPC return 1; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/DaClientExtend.cs b/Modbus.Net/Modbus.Net.OPC/DaClientExtend.cs index 793e36c..f5c196a 100644 --- a/Modbus.Net/Modbus.Net.OPC/DaClientExtend.cs +++ b/Modbus.Net/Modbus.Net.OPC/DaClientExtend.cs @@ -7,9 +7,8 @@ using Opc.Da; namespace Modbus.Net.OPC { - /// - /// Read value full result + /// Read value full result /// public class OpcValueResult { @@ -20,17 +19,23 @@ namespace Modbus.Net.OPC public class MyDaClient : DaClient { + public MyDaClient(Uri serverUrl) : base(serverUrl) + { + } + /// - /// Write a value on the specified opc tag + /// Write a value on the specified opc tag /// - /// The fully-qualified identifier of the tag. You can specify a subfolder by using a comma delimited name. - /// E.g: the tag `foo.bar` writes on the tag `bar` on the folder `foo` + /// + /// The fully-qualified identifier of the tag. You can specify a subfolder by using a comma delimited name. + /// E.g: the tag `foo.bar` writes on the tag `bar` on the folder `foo` + /// public OpcValueResult Read(string tag) { - var item = new Item { ItemName = tag }; - var result = Server.Read(new[] { item })[0]; + var item = new Item {ItemName = tag}; + var result = Server.Read(new[] {item})[0]; CheckResult(result, tag); - return new OpcValueResult() + return new OpcValueResult { Value = result.Value, Timestamp = result.Timestamp, @@ -39,23 +44,21 @@ namespace Modbus.Net.OPC } /// - /// Read a tag asynchronusly + /// Read a tag asynchronusly /// public Task ReadAsync(string tag) { return Task.Run(() => Read(tag)); } - public MyDaClient(Uri serverUrl) : base(serverUrl) - { - } - private static void CheckResult(IResult result, string tag) { if (result == null) throw new OpcException("The server replied with an empty response"); if (result.ResultID.ToString() != "S_OK") - throw new OpcException(string.Format("Invalid response from the server. (Response Status: {0}, Opc Tag: {1})", result.ResultID, tag)); + throw new OpcException( + string.Format("Invalid response from the server. (Response Status: {0}, Opc Tag: {1})", + result.ResultID, tag)); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/OpcDaConnector.cs b/Modbus.Net/Modbus.Net.OPC/OpcDaConnector.cs index 61c75a4..6cd6428 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcDaConnector.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcDaConnector.cs @@ -1,22 +1,15 @@ using System; using System.Collections.Generic; -using System.Diagnostics.Eventing.Reader; -using System.Linq; using System.Text; using System.Threading.Tasks; -using Hylasoft.Opc.Common; -using Hylasoft.Opc.Da; namespace Modbus.Net.OPC { public class OpcDaConnector : BaseConnector { - public override string ConnectionToken { get; } + protected static Dictionary _instances = new Dictionary(); protected bool _connect; - public override bool IsConnected => _connect; - - protected static Dictionary _instances = new Dictionary(); protected MyDaClient _daClient; protected OpcDaConnector(string host) @@ -24,6 +17,9 @@ namespace Modbus.Net.OPC ConnectionToken = host; } + public override string ConnectionToken { get; } + public override bool IsConnected => _connect; + public static OpcDaConnector Instance(string host) { if (!_instances.ContainsKey(host)) @@ -99,23 +95,20 @@ namespace Modbus.Net.OPC var protocal = BigEndianValueHelper.Instance.GetByte(message, ref pos); if (protocal == 0) { - byte[] tagBytes = new byte[message.Length - 1]; + var tagBytes = new byte[message.Length - 1]; Array.Copy(message, 1, tagBytes, 0, tagBytes.Length); - string tag = Encoding.UTF8.GetString(tagBytes); + var tag = Encoding.UTF8.GetString(tagBytes); var result = await _daClient.ReadAsync(tag); if (result.QualityGood) { return BigEndianValueHelper.Instance.GetBytes(result.Value, result.Value.GetType()); } - else - { - return Encoding.ASCII.GetBytes("NoData"); - } + return Encoding.ASCII.GetBytes("NoData"); } else { - int index = 0; - for (int i = 1; i < message.Length - 3; i++) + var index = 0; + for (var i = 1; i < message.Length - 3; i++) { if (message[i] == 0x00 && message[i + 1] == 0xff && message[i + 2] == 0xff && message[i + 3] == 0x00) @@ -125,8 +118,8 @@ namespace Modbus.Net.OPC } } - int index2 = 0; - for (int i = index + 4; i < message.Length - 3; i++) + var index2 = 0; + for (var i = index + 4; i < message.Length - 3; i++) { if (message[i] == 0x00 && message[i + 1] == 0xff && message[i + 2] == 0xff && message[i + 3] == 0x00) @@ -135,16 +128,16 @@ namespace Modbus.Net.OPC break; } } - byte[] tagBytes = new byte[index - 1]; + var tagBytes = new byte[index - 1]; Array.Copy(message, 1, tagBytes, 0, tagBytes.Length); - string tag = Encoding.UTF8.GetString(tagBytes); - byte[] typeBytes = new byte[index2 - index - 4]; + var tag = Encoding.UTF8.GetString(tagBytes); + var typeBytes = new byte[index2 - index - 4]; Array.Copy(message, index + 4, typeBytes, 0, typeBytes.Length); - Type type = Type.GetType(Encoding.UTF8.GetString(typeBytes)); - byte[] valueBytes = new byte[message.Length - index2 - 4]; + var type = Type.GetType(Encoding.UTF8.GetString(typeBytes)); + var valueBytes = new byte[message.Length - index2 - 4]; Array.Copy(message, index2 + 4, valueBytes, 0, valueBytes.Length); int mainpos = 0, subpos = 0; - object value = BigEndianValueHelper.Instance.GetValue(valueBytes, ref mainpos, ref subpos, type); + var value = BigEndianValueHelper.Instance.GetValue(valueBytes, ref mainpos, ref subpos, type); await _daClient.WriteAsync(tag, value); return new byte[] {1}; } @@ -154,7 +147,7 @@ namespace Modbus.Net.OPC //AddInfo("opc client exception:" + e); return Encoding.ASCII.GetBytes("NoData"); //return null; - } + } } private void AddInfo(string message) @@ -162,4 +155,4 @@ namespace Modbus.Net.OPC Console.WriteLine(message); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/OpcDaMachine.cs b/Modbus.Net/Modbus.Net.OPC/OpcDaMachine.cs index e6d8b6e..312cf89 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcDaMachine.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcDaMachine.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; namespace Modbus.Net.OPC { @@ -10,7 +6,7 @@ namespace Modbus.Net.OPC { public OpcDaMachine(string connectionString, IEnumerable getAddresses, bool keepConnect) : base(getAddresses, keepConnect) - { + { BaseUtility = new OpcDaUtility(connectionString); AddressCombiner = new AddressCombinerSingle(); AddressCombinerSet = new AddressCombinerSingle(); @@ -21,4 +17,4 @@ namespace Modbus.Net.OPC { } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/OpcDaProtocal.cs b/Modbus.Net/Modbus.Net.OPC/OpcDaProtocal.cs index f7bec31..d73bffa 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcDaProtocal.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcDaProtocal.cs @@ -1,16 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace Modbus.Net.OPC { public class OpcDaProtocal : OpcProtocal { - private int _connectTryCount; - private readonly string _host; + private int _connectTryCount; public OpcDaProtocal(string host) { @@ -31,4 +26,4 @@ namespace Modbus.Net.OPC return true; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/OpcDaProtocalLinker.cs b/Modbus.Net/Modbus.Net.OPC/OpcDaProtocalLinker.cs index c3933b0..f94f735 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcDaProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcDaProtocalLinker.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Text; namespace Modbus.Net.OPC { @@ -10,12 +6,11 @@ namespace Modbus.Net.OPC { public OpcDaProtocalLinker() : this(ConfigurationManager.OpcDaHost) { - } public OpcDaProtocalLinker(string host) { - _baseConnector = OpcDaConnector.Instance(host); + BaseConnector = OpcDaConnector.Instance(host); } public override bool? CheckRight(byte[] content) @@ -27,4 +22,4 @@ namespace Modbus.Net.OPC return base.CheckRight(content); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs b/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs index f618e2b..b7d4e82 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcDaUtility.cs @@ -1,23 +1,20 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; namespace Modbus.Net.OPC { public class OpcDaUtility : BaseUtility { - public override bool GetLittleEndian => Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian; - public override bool SetLittleEndian => Wrapper[typeof (WriteRequestOpcProtocal)].IsLittleEndian; - - public OpcDaUtility(string connectionString) : base(0,0) + public OpcDaUtility(string connectionString) : base(0, 0) { ConnectionString = connectionString; AddressTranslator = new AddressTranslatorOpc(); Wrapper = new OpcDaProtocal(ConnectionString); } + public override bool GetLittleEndian => Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian; + public override bool SetLittleEndian => Wrapper[typeof (WriteRequestOpcProtocal)].IsLittleEndian; + public override void SetConnectionType(int connectionType) { } @@ -28,8 +25,9 @@ namespace Modbus.Net.OPC { var readRequestOpcInputStruct = new ReadRequestOpcInputStruct(startAddress); var readRequestOpcOutputStruct = - await - Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestOpcProtocal)], readRequestOpcInputStruct) as ReadRequestOpcOutputStruct; + await + Wrapper.SendReceiveAsync(Wrapper[typeof (ReadRequestOpcProtocal)], readRequestOpcInputStruct) as + ReadRequestOpcOutputStruct; return readRequestOpcOutputStruct?.GetValue; } catch (Exception) @@ -44,8 +42,9 @@ namespace Modbus.Net.OPC { var writeRequestOpcInputStruct = new WriteRequestOpcInputStruct(startAddress, setContents[0]); var writeRequestOpcOutputStruct = - await - Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestOpcProtocal)], writeRequestOpcInputStruct) as WriteRequestOpcOutputStruct; + await + Wrapper.SendReceiveAsync(Wrapper[typeof (WriteRequestOpcProtocal)], writeRequestOpcInputStruct) + as WriteRequestOpcOutputStruct; return writeRequestOpcOutputStruct?.WriteResult == true; } catch (Exception e) @@ -54,4 +53,4 @@ namespace Modbus.Net.OPC } } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs b/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs index 9e42702..14c92c9 100644 --- a/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs +++ b/Modbus.Net/Modbus.Net.OPC/OpcProtocal.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Text; namespace Modbus.Net.OPC { @@ -20,7 +16,7 @@ namespace Modbus.Net.OPC Tag = tag; } - public string Tag { get; private set; } + public string Tag { get; } } public class ReadRequestOpcOutputStruct : OutputStruct @@ -38,11 +34,11 @@ namespace Modbus.Net.OPC public override byte[] Format(InputStruct message) { var r_message = (ReadRequestOpcInputStruct) message; - return Format((byte)0x00, Encoding.UTF8.GetBytes(r_message.Tag)); + return Format((byte) 0x00, Encoding.UTF8.GetBytes(r_message.Tag)); } public override OutputStruct Unformat(byte[] messageBytes, ref int pos) - { + { return new ReadRequestOpcOutputStruct(messageBytes); } } @@ -55,8 +51,8 @@ namespace Modbus.Net.OPC SetValue = setValue; } - public string Tag { get; private set; } - public object SetValue { get; private set; } + public string Tag { get; } + public object SetValue { get; } } public class WriteRequestOpcOutputStruct : OutputStruct @@ -67,17 +63,16 @@ namespace Modbus.Net.OPC } public bool WriteResult { get; private set; } - } public class WriteRequestOpcProtocal : SpecialProtocalUnit { public override byte[] Format(InputStruct message) { - var r_message = (WriteRequestOpcInputStruct)message; - byte[] tag = Encoding.UTF8.GetBytes(r_message.Tag); - byte[] fullName = Encoding.UTF8.GetBytes(r_message.SetValue.GetType().FullName); - return Format((byte)0x01, tag, (int)0x00ffff00, fullName, (int)0x00ffff00, r_message.SetValue); + var r_message = (WriteRequestOpcInputStruct) message; + var tag = Encoding.UTF8.GetBytes(r_message.Tag); + var fullName = Encoding.UTF8.GetBytes(r_message.SetValue.GetType().FullName); + return Format((byte) 0x01, tag, 0x00ffff00, fullName, 0x00ffff00, r_message.SetValue); } public override OutputStruct Unformat(byte[] messageBytes, ref int pos) @@ -87,4 +82,4 @@ namespace Modbus.Net.OPC return new WriteRequestOpcOutputStruct(ans); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs b/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs index 1ea429e..b4ff1bb 100644 --- a/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs +++ b/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Modbus.Net.Siemens +namespace Modbus.Net.Siemens { public class AddressFormaterSiemens : AddressFormater { @@ -18,4 +12,4 @@ namespace Modbus.Net.Siemens return area + " " + address + "." + subAddress; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs b/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs index 972dca9..5de74aa 100644 --- a/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs +++ b/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace Modbus.Net.Siemens @@ -23,20 +22,20 @@ namespace Modbus.Net.Siemens {"Q", 0x82}, {"M", 0x83}, {"DB", 0x84}, - {"V", 0x184}, + {"V", 0x184} }; } public override AddressDef AddressTranslate(string address, bool isRead) { address = address.ToUpper(); - string[] splitString = address.Split(' '); - string head = splitString[0]; - string tail = splitString[1]; + var splitString = address.Split(' '); + var head = splitString[0]; + var tail = splitString[1]; string sub; if (tail.Contains('.')) { - string[] splitString2 = tail.Split('.'); + var splitString2 = tail.Split('.'); sub = splitString2[1]; tail = splitString2[0]; } @@ -47,21 +46,21 @@ namespace Modbus.Net.Siemens if (head.Length > 1 && head.Substring(0, 2) == "DB") { head = head.Substring(2); - return new AddressDef() + return new AddressDef { - AreaString = "DB"+head, + AreaString = "DB" + head, Area = int.Parse(head)*256 + AreaCodeDictionary["DB"], Address = int.Parse(tail), - SubAddress = int.Parse(sub), + SubAddress = int.Parse(sub) }; } - return - new AddressDef() + return + new AddressDef { AreaString = head, Area = AreaCodeDictionary[head], Address = int.Parse(tail), - SubAddress = int.Parse(sub), + SubAddress = int.Parse(sub) }; } diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs index f8e5a40..b742095 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensMachine.cs @@ -20,4 +20,4 @@ namespace Modbus.Net.Siemens { } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs index 5079a53..4710f45 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocal.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace Modbus.Net.Siemens { @@ -10,11 +6,13 @@ namespace Modbus.Net.Siemens { private readonly string _com; - public SiemensPpiProtocal(byte belongAddress, byte masterAddress) : this( ConfigurationManager.COM, belongAddress, masterAddress) + public SiemensPpiProtocal(byte slaveAddress, byte masterAddress) + : this(ConfigurationManager.COM, slaveAddress, masterAddress) { } - public SiemensPpiProtocal(string com, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + public SiemensPpiProtocal(string com, byte slaveAddress, byte masterAddress) + : base(slaveAddress, masterAddress) { _com = com; } @@ -40,29 +38,29 @@ namespace Modbus.Net.Siemens public override bool Connect() { - return AsyncHelper.RunSync(()=>ConnectAsync()); + return AsyncHelper.RunSync(() => ConnectAsync()); } public override async Task ConnectAsync() { ProtocalLinker = new SiemensPpiProtocalLinker(_com); - var inputStruct = new ComCreateReferenceSiemensInputStruct(BelongAddress, MasterAddress); + var inputStruct = new ComCreateReferenceSiemensInputStruct(SlaveAddress, MasterAddress); var outputStruct = await await - ForceSendReceiveAsync(this[typeof (ComCreateReferenceSiemensProtocal)], - inputStruct). - ContinueWith(async answer => - { - if (!ProtocalLinker.IsConnected) return false; - var inputStruct2 = new ComConfirmMessageSiemensInputStruct(BelongAddress, MasterAddress); - var outputStruct2 = - (ComConfirmMessageSiemensOutputStruct) - await - ForceSendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocal)], - inputStruct2); - return outputStruct2 != null; - }); - return outputStruct != null; + ForceSendReceiveAsync(this[typeof (ComCreateReferenceSiemensProtocal)], + inputStruct). + ContinueWith(async answer => + { + if (!ProtocalLinker.IsConnected) return false; + var inputStruct2 = new ComConfirmMessageSiemensInputStruct(SlaveAddress, MasterAddress); + var outputStruct2 = + (ComConfirmMessageSiemensOutputStruct) + await + ForceSendReceiveAsync(this[typeof (ComConfirmMessageSiemensProtocal)], + inputStruct2); + return outputStruct2 != null; + }); + return outputStruct; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs index 490aa5c..06b4ada 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensPpiProtocalLinker.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO.Ports; -using System.Linq; -using System.Linq.Expressions; -using System.Text; +using System.IO.Ports; using System.Threading; using System.Threading.Tasks; @@ -11,9 +6,14 @@ namespace Modbus.Net.Siemens { public class SiemensPpiProtocalLinker : ComProtocalLinker { + public SiemensPpiProtocalLinker(string com) + : base(com, 9600, Parity.Even, StopBits.One, 8) + { + } + public override async Task SendReceiveAsync(byte[] content) { - byte[] extBytes = BytesExtend(content); + var extBytes = BytesExtend(content); if (extBytes[6] == 0x7c) { var inputStruct2 = new ComConfirmMessageSiemensInputStruct(content[4], content[5]); @@ -60,13 +60,13 @@ namespace Modbus.Net.Siemens public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; - int fcsCheck = 0; + var fcsCheck = 0; if (content.Length == 1 && content[0] == 0xe5) { return true; } if (content.Length == 6 && content[3] == 0) return true; - for (int i = 4; i < content.Length - 2; i++) + for (var i = 4; i < content.Length - 2; i++) { fcsCheck += content[i]; } @@ -76,10 +76,5 @@ namespace Modbus.Net.Siemens if (content[1] != content.Length - 6) return false; return true; } - - public SiemensPpiProtocalLinker(string com) - : base(com, 9600, Parity.Even, StopBits.One, 8) - { - } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs index 6675049..ca118a5 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocal.cs @@ -12,8 +12,8 @@ namespace Modbus.Net.Siemens DWord = 0x04, C = 0x1E, T = 0x1F, - HC = 0x20, - }; + HC = 0x20 + } public enum SiemensAccessResult : byte { @@ -22,47 +22,47 @@ namespace Modbus.Net.Siemens IllegalObjectAccess = 0x03, InvalidAddress = 0x05, DataTypeNotSupport = 0x06, - ObjNotExistOrLengthError = 0x0A, - }; + ObjNotExistOrLengthError = 0x0A + } public enum SiemensDataType : byte { Error = 0x00, BitAccess = 0x03, OtherAccess = 0x04 - }; + } public abstract class SiemensProtocal : BaseProtocal { - protected SiemensProtocal(byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + protected SiemensProtocal(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) { } } internal class ComCreateReferenceSiemensInputStruct : InputStruct { - public byte BelongAddress { get; set; } - public byte MasterAddress { get; set; } - - public ComCreateReferenceSiemensInputStruct(byte belongAddress, byte masterAddress) + public ComCreateReferenceSiemensInputStruct(byte slaveAddress, byte masterAddress) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; MasterAddress = masterAddress; } + + public byte SlaveAddress { get; set; } + public byte MasterAddress { get; set; } } internal class ComCreateReferenceSiemensOutputStruct : OutputStruct { - public byte BelongAddress { get; set; } - public byte MasterAddress { get; set; } - public byte ConfirmMessage { get; set; } - - public ComCreateReferenceSiemensOutputStruct(byte belongAddress, byte masterAddress, byte confirmMessage) + public ComCreateReferenceSiemensOutputStruct(byte slaveAddress, byte masterAddress, byte confirmMessage) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; MasterAddress = masterAddress; ConfirmMessage = confirmMessage; } + + public byte SlaveAddress { get; set; } + public byte MasterAddress { get; set; } + public byte ConfirmMessage { get; set; } } internal class ComCreateReferenceSiemensProtocal : SpecialProtocalUnit @@ -70,34 +70,35 @@ namespace Modbus.Net.Siemens public override byte[] Format(InputStruct message) { var r_message = (ComCreateReferenceSiemensInputStruct) message; - var crc = (r_message.BelongAddress + r_message.MasterAddress + 0x49)%256; - return Format((byte)0x10, r_message.BelongAddress, r_message.MasterAddress, (byte)0x49, (byte)crc, (byte)0x16); + var crc = (r_message.SlaveAddress + r_message.MasterAddress + 0x49)%256; + return Format((byte) 0x10, r_message.SlaveAddress, r_message.MasterAddress, (byte) 0x49, (byte) crc, + (byte) 0x16); } public override OutputStruct Unformat(byte[] messageBytes, ref int pos) { pos = 1; var masterAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - var belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + var slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); var confirmMessage = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - return new ComCreateReferenceSiemensOutputStruct(belongAddress, masterAddress, confirmMessage); + return new ComCreateReferenceSiemensOutputStruct(slaveAddress, masterAddress, confirmMessage); } } internal class CreateReferenceSiemensInputStruct : InputStruct { + public byte TdpuSize; + + public ushort TsapDst; + + public ushort TsapSrc; + public CreateReferenceSiemensInputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap) { TdpuSize = tdpuSize; TsapSrc = srcTsap; TsapDst = dstTsap; } - - public byte TdpuSize; - - public ushort TsapSrc; - - public ushort TsapDst; } internal class CreateReferenceSiemensOutputStruct : OutputStruct @@ -118,7 +119,7 @@ namespace Modbus.Net.Siemens { public override byte[] Format(InputStruct message) { - var r_message = (CreateReferenceSiemensInputStruct)message; + var r_message = (CreateReferenceSiemensInputStruct) message; const ushort head = 0x0300; const ushort len = 0x0016; const byte contentLen = 0x11; @@ -127,11 +128,11 @@ namespace Modbus.Net.Siemens const ushort srcRef = 0x000c; const byte reserved = 0x00; const ushort tdpuSizeCode = 0xc001; - byte tdpuSizeContent = r_message.TdpuSize; + var tdpuSizeContent = r_message.TdpuSize; const ushort srcTsapCode = 0xc102; - ushort srcTsapContent = r_message.TsapSrc; + var srcTsapContent = r_message.TsapSrc; const ushort dstTsapCode = 0xc202; - ushort dstTsapContent = r_message.TsapDst; + var dstTsapContent = r_message.TsapDst; return Format(head, len, contentLen, typeCode, dstRef, srcRef, reserved, tdpuSizeCode, tdpuSizeContent, srcTsapCode, srcTsapContent, dstTsapCode, dstTsapContent); } @@ -168,14 +169,14 @@ namespace Modbus.Net.Siemens public class ComConfirmMessageSiemensInputStruct : InputStruct { - public byte BelongAddress { get; set; } - public byte MasterAddress { get; set; } - - public ComConfirmMessageSiemensInputStruct(byte belongAddress, byte masterAddress) + public ComConfirmMessageSiemensInputStruct(byte slaveAddress, byte masterAddress) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; MasterAddress = masterAddress; } + + public byte SlaveAddress { get; set; } + public byte MasterAddress { get; set; } } public class ComConfirmMessageSiemensOutputStruct : OutputStruct @@ -192,9 +193,10 @@ namespace Modbus.Net.Siemens { public override byte[] Format(InputStruct message) { - var r_message = (ComConfirmMessageSiemensInputStruct)message; - var crc = r_message.BelongAddress + r_message.MasterAddress + 0x5c%256; - return Format((byte)0x10, r_message.BelongAddress, r_message.MasterAddress, (byte)0x5c, (byte)crc, (byte)0x16); + var r_message = (ComConfirmMessageSiemensInputStruct) message; + var crc = r_message.SlaveAddress + r_message.MasterAddress + 0x5c%256; + return Format((byte) 0x10, r_message.SlaveAddress, r_message.MasterAddress, (byte) 0x5c, (byte) crc, + (byte) 0x16); } public override OutputStruct Unformat(byte[] messageBytes, ref int pos) @@ -214,10 +216,10 @@ namespace Modbus.Net.Siemens MaxPdu = maxPdu; } - public ushort PduRef { get; private set; } - public ushort MaxCalling { get; private set; } - public ushort MaxCalled { get; private set; } - public ushort MaxPdu { get; private set; } + public ushort PduRef { get; } + public ushort MaxCalling { get; } + public ushort MaxCalled { get; } + public ushort MaxPdu { get; } } internal class EstablishAssociationSiemensOutputStruct : OutputStruct @@ -244,14 +246,14 @@ namespace Modbus.Net.Siemens const byte protoId = 0x32; const byte rosctr = 0x01; const ushort redId = 0x0000; - ushort pduRef = r_message.PduRef; + var pduRef = r_message.PduRef; const ushort parLg = 0x0008; const ushort datLg = 0x0000; const byte serviceId = 0xf0; const byte reserved = 0x00; - ushort maxCalling = r_message.MaxCalling; - ushort maxCalled = r_message.MaxCalled; - ushort maxPdu = r_message.MaxPdu; + var maxCalling = r_message.MaxCalling; + var maxCalled = r_message.MaxCalled; + var maxPdu = r_message.MaxPdu; return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, reserved, maxCalling, maxCalled, maxPdu); } @@ -259,44 +261,46 @@ namespace Modbus.Net.Siemens public override OutputStruct Unformat(byte[] messageBytes, ref int pos) { pos = 4; - ushort pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + var pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); pos = 14; - ushort maxCalling = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); - ushort maxCalled = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); - ushort maxPdu = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); - return new EstablishAssociationSiemensOutputStruct(pduRef,maxCalling,maxCalled,maxPdu); + var maxCalling = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + var maxCalled = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + var maxPdu = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + return new EstablishAssociationSiemensOutputStruct(pduRef, maxCalling, maxCalled, maxPdu); } } public class ReadRequestSiemensInputStruct : InputStruct { - public ReadRequestSiemensInputStruct(byte belongAddress, byte masterAddress, ushort pduRef, SiemensTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator) + public ReadRequestSiemensInputStruct(byte slaveAddress, byte masterAddress, ushort pduRef, + SiemensTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; MasterAddress = masterAddress; PduRef = pduRef; TypeCode = (byte) getType; var address = addressTranslator.AddressTranslate(startAddress, true); Offset = address.Address; - int area = address.Area; - Area = (byte)(area%256); - DbBlock = Area == 0x84 ? (ushort)(area/256) : (ushort)0; - NumberOfElements = getCount; + var area = address.Area; + Area = (byte) (area%256); + DbBlock = Area == 0x84 ? (ushort) (area/256) : (ushort) 0; + NumberOfElements = getCount; } - public byte BelongAddress { get; set; } + public byte SlaveAddress { get; set; } public byte MasterAddress { get; set; } - public ushort PduRef { get; private set; } - public byte TypeCode { get; private set; } - public ushort NumberOfElements { get; private set; } - public ushort DbBlock { get; private set; } - public byte Area { get; private set; } - public int Offset { get; private set; } + public ushort PduRef { get; } + public byte TypeCode { get; } + public ushort NumberOfElements { get; } + public ushort DbBlock { get; } + public byte Area { get; } + public int Offset { get; } } - + public class ReadRequestSiemensOutputStruct : OutputStruct { - public ReadRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult, SiemensDataType dataType, ushort getLength, byte[] value) + public ReadRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult, SiemensDataType dataType, + ushort getLength, byte[] value) { PduRef = pduRef; AccessResult = accessResult; @@ -317,12 +321,12 @@ namespace Modbus.Net.Siemens public override byte[] Format(InputStruct message) { var r_message = (ReadRequestSiemensInputStruct) message; - byte belongAddress = r_message.BelongAddress; - byte masterAddress = r_message.MasterAddress; + var slaveAddress = r_message.SlaveAddress; + var masterAddress = r_message.MasterAddress; const byte protoId = 0x32; const byte rosctr = 0x01; const ushort redId = 0x0000; - ushort pduRef = r_message.PduRef; + var pduRef = r_message.PduRef; const ushort parLg = 14; // 参数字节数(2+12的倍数),目前仅为14 const ushort datLg = 0; // 数据字节数 const byte serviceId = 0x04; @@ -330,13 +334,14 @@ namespace Modbus.Net.Siemens const byte variableSpec = 0x12; const byte vAddrLg = 0x0A; const byte syntaxId = 0x10; - byte type = r_message.TypeCode; - ushort numberOfElements = r_message.NumberOfElements; - ushort dbBlock = r_message.DbBlock; - byte area = r_message.Area; - int offsetBit = r_message.Offset*8; - byte[] offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit); - return Format(new byte[4], belongAddress, masterAddress, (byte)0x6c, protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables + var type = r_message.TypeCode; + var numberOfElements = r_message.NumberOfElements; + var dbBlock = r_message.DbBlock; + var area = r_message.Area; + var offsetBit = r_message.Offset*8; + var offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit); + return Format(new byte[4], slaveAddress, masterAddress, (byte) 0x6c, protoId, rosctr, redId, pduRef, parLg, + datLg, serviceId, numberOfVariables , variableSpec, vAddrLg, syntaxId, type, numberOfElements, dbBlock, area, offsetBitBytes.Skip(1).ToArray()); } @@ -344,13 +349,13 @@ namespace Modbus.Net.Siemens public override OutputStruct Unformat(byte[] messageBytes, ref int pos) { pos = 4; - ushort pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + var pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); pos = 14; - byte accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - byte dataType = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - ushort length = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); - int byteLength = length/8; - var values = new Byte[byteLength]; + var accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + var dataType = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + var length = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + var byteLength = length/8; + var values = new byte[byteLength]; Array.Copy(messageBytes, pos, values, 0, byteLength); return new ReadRequestSiemensOutputStruct(pduRef, (SiemensAccessResult) accessResult, (SiemensDataType) dataType, length, values); @@ -359,26 +364,27 @@ namespace Modbus.Net.Siemens public class WriteRequestSiemensInputStruct : InputStruct { - public WriteRequestSiemensInputStruct(byte belongAddress, byte masterAddress, ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator) + public WriteRequestSiemensInputStruct(byte slaveAddress, byte masterAddress, ushort pduRef, string startAddress, + object[] writeValue, AddressTranslator addressTranslator) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; MasterAddress = masterAddress; PduRef = pduRef; var address = addressTranslator.AddressTranslate(startAddress, true); Offset = address.Address; - int area = address.Area; - Area = (byte)(area % 256); - DbBlock = Area == 0x84 ? (ushort)(area / 256) : (ushort)0; + var area = address.Area; + Area = (byte) (area%256); + DbBlock = Area == 0x84 ? (ushort) (area/256) : (ushort) 0; WriteValue = writeValue; } - public byte BelongAddress { get; set; } + public byte SlaveAddress { get; set; } public byte MasterAddress { get; set; } - public ushort PduRef { get; private set; } - public ushort DbBlock { get; private set; } - public byte Area { get; private set; } - public int Offset { get; private set; } - public object[] WriteValue { get; private set; } + public ushort PduRef { get; } + public ushort DbBlock { get; } + public byte Area { get; } + public int Offset { get; } + public object[] WriteValue { get; } } public class WriteRequestSiemensOutputStruct : OutputStruct @@ -390,8 +396,7 @@ namespace Modbus.Net.Siemens } public ushort PduRef { get; private set; } - public SiemensAccessResult AccessResult {get; private set; } - + public SiemensAccessResult AccessResult { get; private set; } } public class WriteRequestSiemensProtocal : ProtocalUnit @@ -399,30 +404,31 @@ namespace Modbus.Net.Siemens public override byte[] Format(InputStruct message) { var r_message = (WriteRequestSiemensInputStruct) message; - byte[] valueBytes = BigEndianValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue); - byte belongAddress = r_message.BelongAddress; - byte masterAddress = r_message.MasterAddress; + var valueBytes = BigEndianValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue); + var slaveAddress = r_message.SlaveAddress; + var masterAddress = r_message.MasterAddress; const byte protoId = 0x32; const byte rosctr = 0x01; const ushort redId = 0x0000; - ushort pduRef = r_message.PduRef; + var pduRef = r_message.PduRef; const ushort parLg = 14; // 参数字节数(2+12的倍数),目前仅为14 - ushort datLg = (ushort)(4+valueBytes.Length); // 数据字节数 + var datLg = (ushort) (4 + valueBytes.Length); // 数据字节数 const byte serviceId = 0x05; const byte numberOfVariables = 1; const byte variableSpec = 0x12; const byte vAddrLg = 0x0A; const byte syntaxId = 0x10; - const byte typeR = (byte)SiemensTypeCode.Byte; - ushort numberOfElements = (ushort)valueBytes.Length; - ushort dbBlock = r_message.DbBlock; - byte area = r_message.Area; - int offsetBit = r_message.Offset * 8; - byte[] offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit); + const byte typeR = (byte) SiemensTypeCode.Byte; + var numberOfElements = (ushort) valueBytes.Length; + var dbBlock = r_message.DbBlock; + var area = r_message.Area; + var offsetBit = r_message.Offset*8; + var offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit); const byte reserved = 0x00; - const byte type = (byte)SiemensDataType.OtherAccess; - ushort numberOfWriteBits = (ushort)(valueBytes.Length*8); - return Format(new byte[4], belongAddress, masterAddress, (byte)0x7c, protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables + const byte type = (byte) SiemensDataType.OtherAccess; + var numberOfWriteBits = (ushort) (valueBytes.Length*8); + return Format(new byte[4], slaveAddress, masterAddress, (byte) 0x7c, protoId, rosctr, redId, pduRef, parLg, + datLg, serviceId, numberOfVariables , variableSpec, vAddrLg, syntaxId, typeR, numberOfElements, dbBlock, area, offsetBitBytes.Skip(1).ToArray(), reserved, type, numberOfWriteBits, valueBytes); } @@ -431,17 +437,18 @@ namespace Modbus.Net.Siemens { if (messageBytes.Length == 1) { - byte accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - return new WriteRequestSiemensOutputStruct(0, accessResult == 0xe5 ? SiemensAccessResult.NoError : SiemensAccessResult.InvalidAddress); + var accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + return new WriteRequestSiemensOutputStruct(0, + accessResult == 0xe5 ? SiemensAccessResult.NoError : SiemensAccessResult.InvalidAddress); } else { pos = 4; - ushort pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); + var pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos); pos = 14; - byte accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); - return new WriteRequestSiemensOutputStruct(pduRef, (SiemensAccessResult)accessResult); - } + var accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + return new WriteRequestSiemensOutputStruct(pduRef, (SiemensAccessResult) accessResult); + } } } @@ -525,9 +532,7 @@ namespace Modbus.Net.Siemens public class SiemensProtocalErrorException : ProtocalErrorException { - public int ErrorClass { get; private set; } - public int ErrorCode { get; private set; } - private static readonly Dictionary ProtocalErrorDictionary = new Dictionary() + private static readonly Dictionary ProtocalErrorDictionary = new Dictionary { {0x00, "No Error"}, {0x81, "Error in the application Id of the request"}, @@ -540,7 +545,7 @@ namespace Modbus.Net.Siemens {0xD4, "Diagnostic error"}, {0xD6, "Protection system error"}, {0xD8, "BuB error"}, - {0xEF, "Layer 2 specific error"}, + {0xEF, "Layer 2 specific error"} }; public SiemensProtocalErrorException(int errCls, int errCod) @@ -549,5 +554,8 @@ namespace Modbus.Net.Siemens ErrorClass = errCls; ErrorCode = errCod; } + + public int ErrorClass { get; private set; } + public int ErrorCode { get; private set; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs index 3f6e6d1..71643d6 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensProtocalLinkerBytesExtend.cs @@ -6,14 +6,14 @@ namespace Modbus.Net.Siemens { public override byte[] BytesExtend(byte[] content) { - Array.Copy(new byte[]{0x03,0x00,0x00,0x00,0x02,0xf0,0x80}, 0, content, 0, 7); - Array.Copy(BigEndianValueHelper.Instance.GetBytes((ushort)content.Length), 0, content, 2, 2); + Array.Copy(new byte[] {0x03, 0x00, 0x00, 0x00, 0x02, 0xf0, 0x80}, 0, content, 0, 7); + Array.Copy(BigEndianValueHelper.Instance.GetBytes((ushort) content.Length), 0, content, 2, 2); return content; } public override byte[] BytesDecact(byte[] content) { - byte[] newContent = new byte[content.Length - 7]; + var newContent = new byte[content.Length - 7]; Array.Copy(content, 7, newContent, 0, newContent.Length); return newContent; } @@ -23,11 +23,12 @@ namespace Modbus.Net.Siemens { public override byte[] BytesExtend(byte[] content) { - byte[] newContent = new byte[content.Length + 2]; + var newContent = new byte[content.Length + 2]; Array.Copy(content, 0, newContent, 0, content.Length); - Array.Copy(new byte[] { 0x68, (byte)(content.Length - 4), (byte)(content.Length - 4), 0x68 }, 0, newContent, 0, 4); - int check = 0; - for (int i = 4; i < newContent.Length - 2; i++) + Array.Copy(new byte[] {0x68, (byte) (content.Length - 4), (byte) (content.Length - 4), 0x68}, 0, newContent, + 0, 4); + var check = 0; + for (var i = 4; i < newContent.Length - 2; i++) { check += newContent[i]; } @@ -39,9 +40,9 @@ namespace Modbus.Net.Siemens public override byte[] BytesDecact(byte[] content) { - byte[] newContent = new byte[content.Length - 9]; + var newContent = new byte[content.Length - 9]; Array.Copy(content, 7, newContent, 0, newContent.Length); return newContent; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensStructDefinition.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensStructDefinition.cs index ecb45cb..f6f7c86 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensStructDefinition.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensStructDefinition.cs @@ -88,4 +88,5 @@ public ushort TodValue { get; set; } } } -*/ \ No newline at end of file +*/ + diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs index 40cd03a..5cf6798 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocal.cs @@ -15,17 +15,18 @@ namespace Modbus.Net.Siemens private readonly int _port; private int _connectTryCount; - public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.IP) + public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, + ushort maxPdu) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.IP) { } public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, - ushort maxPdu, string ip) : this (tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ip, 0) + ushort maxPdu, string ip) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ip, 0) { - } - public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip, int port) : base (0, 0) + public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, + ushort maxPdu, string ip, int port) : base(0, 0) { _taspSrc = tsapSrc; _tsapDst = tsapDst; @@ -61,7 +62,11 @@ namespace Modbus.Net.Siemens { if (ProtocalLinker != null && ProtocalLinker.IsConnected) return await base.SendReceiveAsync(unit, content); if (_connectTryCount > 10) return null; - return await await ConnectAsync().ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null); + return + await + await + ConnectAsync() + .ContinueWith(answer => answer.Result ? base.SendReceiveAsync(unit, content) : null); } private async Task ForceSendReceiveAsync(ProtocalUnit unit, InputStruct content) @@ -99,4 +104,4 @@ namespace Modbus.Net.Siemens }); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs index 8d5dbfa..a41105b 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensTcpProtocalLinker.cs @@ -4,6 +4,16 @@ namespace Modbus.Net.Siemens { public class SiemensTcpProtocalLinker : TcpProtocalLinker { + public SiemensTcpProtocalLinker(string ip) + : base(ip, int.Parse(ConfigurationManager.SiemensPort)) + { + } + + public SiemensTcpProtocalLinker(string ip, int port) + : base(ip, port) + { + } + public override bool? CheckRight(byte[] content) { if (!base.CheckRight(content).Value) return false; @@ -17,27 +27,15 @@ namespace Modbus.Net.Siemens { case 0x03: if (content[17] == 0x00 && content[18] == 0x00) return true; - throw new SiemensProtocalErrorException(content[17],content[18]); + throw new SiemensProtocalErrorException(content[17], content[18]); case 0x07: if (content[27] == 0x00 && content[28] == 0x00) return true; - throw new SiemensProtocalErrorException(content[27],content[28]); + throw new SiemensProtocalErrorException(content[27], content[28]); } return true; default: throw new FormatException(); } } - - public SiemensTcpProtocalLinker(string ip) - : base(ip, int.Parse(ConfigurationManager.SiemensPort)) - { - - } - - public SiemensTcpProtocalLinker(string ip, int port) - : base(ip, port) - { - - } } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs b/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs index b1977e7..5237157 100644 --- a/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs +++ b/Modbus.Net/Modbus.Net.Siemens/SiemensUtility.cs @@ -8,7 +8,7 @@ namespace Modbus.Net.Siemens Ppi = 0, Mpi = 1, Tcp = 2 - }; + } public enum SiemensMachineModel { @@ -18,7 +18,7 @@ namespace Modbus.Net.Siemens S7_400 = 3, S7_1200 = 4, S7_1500 = 5 - }; + } public class SiemensUtility : BaseUtility @@ -30,69 +30,10 @@ namespace Modbus.Net.Siemens private readonly ushort _maxCalled; private readonly ushort _maxPdu; - public override bool GetLittleEndian => Wrapper[typeof (ReadRequestSiemensProtocal)].IsLittleEndian; - public override bool SetLittleEndian => Wrapper[typeof (WriteRequestSiemensProtocal)].IsLittleEndian; - - protected string ConnectionStringIp - { - get - { - if (ConnectionString == null) return null; - return ConnectionString.Contains(":") ? ConnectionString.Split(':')[0] : ConnectionString; - } - } - - protected int? ConnectionStringPort - { - get - { - if (ConnectionString == null) return null; - if (!ConnectionString.Contains(":")) return null; - var connectionStringSplit = ConnectionString.Split(':'); - try - { - return connectionStringSplit.Length < 2 ? (int?)null : int.Parse(connectionStringSplit[1]); - } - catch - { - return null; - } - } - } - private SiemensType _siemensType; - public SiemensType ConnectionType - { - get - { - return _siemensType; - } - set - { - _siemensType = value; - switch (_siemensType) - { - case SiemensType.Ppi: - { - Wrapper = ConnectionString == null ? new SiemensPpiProtocal(BelongAddress, MasterAddress) : new SiemensPpiProtocal(ConnectionString, BelongAddress, MasterAddress); - break; - } - //case SiemensType.Mpi: - // { - // throw new NotImplementedException(); - // } - case SiemensType.Tcp: - { - Wrapper = ConnectionString == null ? new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu) : (ConnectionStringPort == null ? new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, ConnectionString) : new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, ConnectionStringIp, ConnectionStringPort.Value)); - break; - } - } - } - } - public SiemensUtility(SiemensType connectionType, string connectionString, SiemensMachineModel model, - byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) + byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) { ConnectionString = connectionString; switch (model) @@ -148,6 +89,70 @@ namespace Modbus.Net.Siemens AddressTranslator = new AddressTranslatorSiemens(); } + public override bool GetLittleEndian => Wrapper[typeof (ReadRequestSiemensProtocal)].IsLittleEndian; + public override bool SetLittleEndian => Wrapper[typeof (WriteRequestSiemensProtocal)].IsLittleEndian; + + protected string ConnectionStringIp + { + get + { + if (ConnectionString == null) return null; + return ConnectionString.Contains(":") ? ConnectionString.Split(':')[0] : ConnectionString; + } + } + + protected int? ConnectionStringPort + { + get + { + if (ConnectionString == null) return null; + if (!ConnectionString.Contains(":")) return null; + var connectionStringSplit = ConnectionString.Split(':'); + try + { + return connectionStringSplit.Length < 2 ? (int?) null : int.Parse(connectionStringSplit[1]); + } + catch + { + return null; + } + } + } + + public SiemensType ConnectionType + { + get { return _siemensType; } + set + { + _siemensType = value; + switch (_siemensType) + { + case SiemensType.Ppi: + { + Wrapper = ConnectionString == null + ? new SiemensPpiProtocal(SlaveAddress, MasterAddress) + : new SiemensPpiProtocal(ConnectionString, SlaveAddress, MasterAddress); + break; + } + //case SiemensType.Mpi: + // { + // throw new NotImplementedException(); + // } + case SiemensType.Tcp: + { + Wrapper = ConnectionString == null + ? new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu) + : (ConnectionStringPort == null + ? new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, + ConnectionString) + : new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, + ConnectionStringIp, ConnectionStringPort.Value)); + break; + } + } + } + } + public override void SetConnectionType(int connectionType) { ConnectionType = (SiemensType) connectionType; @@ -157,7 +162,8 @@ namespace Modbus.Net.Siemens { try { - var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(BelongAddress, MasterAddress, 0xd3c7, SiemensTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator); + var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(SlaveAddress, MasterAddress, + 0xd3c7, SiemensTypeCode.Byte, startAddress, (ushort) getByteCount, AddressTranslator); var readRequestSiemensOutputStruct = await Wrapper.SendReceiveAsync(Wrapper[typeof (ReadRequestSiemensProtocal)], @@ -174,7 +180,8 @@ namespace Modbus.Net.Siemens { try { - var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(BelongAddress, MasterAddress, 0xd3c8, startAddress, setContents, AddressTranslator); + var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(SlaveAddress, MasterAddress, + 0xd3c8, startAddress, setContents, AddressTranslator); var writeRequestSiemensOutputStruct = await Wrapper.SendReceiveAsync(Wrapper[typeof (WriteRequestSiemensProtocal)], @@ -188,15 +195,15 @@ namespace Modbus.Net.Siemens } /* - public override DateTime GetTime(byte belongAddress) + public override DateTime GetTime(byte slaveAddress) { throw new NotImplementedException(); } - public override bool SetTime(byte belongAddress, DateTime setTime) + public override bool SetTime(byte slaveAddress, DateTime setTime) { throw new NotImplementedException(); } */ } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/AddressCombiner.cs b/Modbus.Net/Modbus.Net/AddressCombiner.cs index c4ddb5b..9c389c7 100644 --- a/Modbus.Net/Modbus.Net/AddressCombiner.cs +++ b/Modbus.Net/Modbus.Net/AddressCombiner.cs @@ -5,12 +5,12 @@ using System.Linq; namespace Modbus.Net { /// - /// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯 + /// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯 /// public abstract class AddressCombiner { /// - /// 组合地址 + /// 组合地址 /// /// 需要进行组合的地址 /// 组合完成后与设备通讯的地址 @@ -18,72 +18,98 @@ namespace Modbus.Net } /// - /// 连续的地址将组合成一组,向设备进行通讯 + /// 连续的地址将组合成一组,向设备进行通讯 /// public class AddressCombinerContinus : AddressCombiner { + public AddressCombinerContinus(AddressTranslator addressTranslator) + { + AddressTranslator = addressTranslator; + } + protected AddressTranslator AddressTranslator { get; set; } public override IEnumerable Combine(IEnumerable addresses) { + //按从小到大的顺序对地址进行排序 var groupedAddresses = from address in addresses - orderby address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)) + orderby + AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area)) group address by address.Area into grouped select grouped; var ans = new List(); foreach (var groupedAddress in groupedAddresses) { - string area = groupedAddress.Key; + var area = groupedAddress.Key; + //初始地址 double initNum = -1; + //上一个地址 double preNum = -1; + //上一个地址类型 Type preType = null; - List originalAddresses = new List(); + //记录一个地址组合当中的所有原始地址 + var originalAddresses = new List(); + //对组合内地址从小到大进行排序 var orderedAddresses = groupedAddress.OrderBy( address => - address.Address + - address.SubAddress*(0.125/AddressTranslator.GetAreaByteLength(address.Area))); + AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area))); foreach (var address in orderedAddresses) { + //第一次进入时直接压入地址 if (initNum < 0) { - initNum = address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)); + initNum = AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area)); originalAddresses.Add(address); } else { - if (address.Address + - address.SubAddress*(0.125/AddressTranslator.GetAreaByteLength(address.Area)) < - preNum + - BigEndianValueHelper.Instance.ByteLength[preType.FullName]/ - AddressTranslator.GetAreaByteLength(address.Area)) + //如果当前地址小于已经记录的地址域,表示这个地址的开始已经记录过了 + if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area)) < + AddressHelper.GetProtocalCoordinateNextPosition(preNum, + preType, + AddressTranslator.GetAreaByteLength(address.Area))) { originalAddresses.Add(address); - if (address.Address + - address.SubAddress*(0.125/AddressTranslator.GetAreaByteLength(address.Area)) + - BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]/ - AddressTranslator.GetAreaByteLength(address.Area) <= - preNum + - BigEndianValueHelper.Instance.ByteLength[preType.FullName]/ - AddressTranslator.GetAreaByteLength(address.Area)) - { + //如果当前地址的末尾被记录,表示地址被记录的地址域覆盖,这个地址没有记录的必要 + if (AddressHelper.GetProtocalCoordinateNextPosition( + AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area)), + address.DataType, + AddressTranslator.GetAreaByteLength(address.Area)) <= + AddressHelper.GetProtocalCoordinateNextPosition(preNum, + preType, + AddressTranslator.GetAreaByteLength(address.Area))) + { continue; } } - else if (address.Address + - address.SubAddress*(0.125/AddressTranslator.GetAreaByteLength(address.Area)) > - preNum + - BigEndianValueHelper.Instance.ByteLength[preType.FullName]/ - AddressTranslator.GetAreaByteLength(address.Area)) + //如果当前地址大于记录的地址域的开头,则表示地址已经不连续了 + else if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area)) > + AddressHelper.GetProtocalCoordinateNextPosition(preNum, + preType, + AddressTranslator.GetAreaByteLength(address.Area))) { - ans.Add(new CommunicationUnit() + //上一个地址域压入返回结果,并把当前记录的结果清空。 + ans.Add(new CommunicationUnit { Area = area, Address = (int) Math.Floor(initNum), - GetCount = (int)Math.Ceiling((preNum - (int)Math.Floor(initNum)) * AddressTranslator.GetAreaByteLength(address.Area) + BigEndianValueHelper.Instance.ByteLength[preType.FullName]), + GetCount = + (int) + Math.Ceiling( + AddressHelper.MapProtocalGetCountToAbstractByteCount( + preNum - (int) Math.Floor(initNum), + AddressTranslator.GetAreaByteLength(address.Area), + BigEndianValueHelper.Instance.ByteLength[preType.FullName])), DataType = typeof (byte), - OriginalAddresses = originalAddresses.ToList(), + OriginalAddresses = originalAddresses.ToList() }); initNum = address.Address; originalAddresses.Clear(); @@ -91,30 +117,37 @@ namespace Modbus.Net } else { + //地址连续,压入当前记录的结果 originalAddresses.Add(address); } } - preNum = address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)); + //把当前地址变为上一个地址 + preNum = AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress, + AddressTranslator.GetAreaByteLength(address.Area)); preType = address.DataType; } - ans.Add(new CommunicationUnit() + //最后一个地址域压入返回结果 + ans.Add(new CommunicationUnit { Area = area, - Address = (int)Math.Floor(initNum), - GetCount = (int)Math.Ceiling((preNum - (int)Math.Floor(initNum)) * AddressTranslator.GetAreaByteLength(area) + BigEndianValueHelper.Instance.ByteLength[preType.FullName]), + Address = (int) Math.Floor(initNum), + GetCount = + (int) + Math.Ceiling( + AddressHelper.MapProtocalGetCountToAbstractByteCount( + preNum - (int) Math.Floor(initNum), AddressTranslator.GetAreaByteLength(area), + BigEndianValueHelper.Instance.ByteLength[preType.FullName])), DataType = typeof (byte), OriginalAddresses = originalAddresses.ToList() }); } return ans; } - - public AddressCombinerContinus(AddressTranslator addressTranslator) - { - AddressTranslator = addressTranslator; - } } + /// + /// 单个地址变为一组,每一个地址都进行一次查询 + /// public class AddressCombinerSingle : AddressCombiner { public override IEnumerable Combine(IEnumerable addresses) @@ -122,37 +155,44 @@ namespace Modbus.Net return addresses.Select( address => - new CommunicationUnit() + new CommunicationUnit { Area = address.Area, Address = address.Address, SubAddress = address.SubAddress, DataType = address.DataType, GetCount = 1, - OriginalAddresses = new List() {address} + OriginalAddresses = new List {address} }).ToList(); } } - class CommunicationUnitGap + /// + /// 两个CommunicationUnit之间的间隔 + /// + internal class CommunicationUnitGap { public CommunicationUnit EndUnit { get; set; } public int GapNumber { get; set; } } + /// + /// 可以调过多少数量的地址,把两个地址段变为一组通讯 + /// public class AddressCombinerNumericJump : AddressCombinerContinus { - private int JumpNumber { get; } - - public AddressCombinerNumericJump(int jumpByteCount, AddressTranslator addressTranslator) : base(addressTranslator) + public AddressCombinerNumericJump(int jumpByteCount, AddressTranslator addressTranslator) + : base(addressTranslator) { JumpNumber = jumpByteCount; } + private int JumpNumber { get; } + public override IEnumerable Combine(IEnumerable addresses) { var continusAddresses = base.Combine(addresses).ToList(); - List addressesGaps = new List(); + var addressesGaps = new List(); CommunicationUnit preCommunicationUnit = null; foreach (var continusAddress in continusAddresses) { @@ -163,17 +203,26 @@ namespace Modbus.Net } if (continusAddress.Area == preCommunicationUnit.Area) { - var gap = new CommunicationUnitGap() + //计算间隔 + var gap = new CommunicationUnitGap { EndUnit = continusAddress, - GapNumber = (int)Math.Ceiling((continusAddress.Address - preCommunicationUnit.Address) * AddressTranslator.GetAreaByteLength(continusAddress.Area) - preCommunicationUnit.GetCount * BigEndianValueHelper.Instance.ByteLength[preCommunicationUnit.DataType.FullName]) + GapNumber = + (int) + Math.Ceiling(AddressHelper.MapProtocalCoordinateToAbstractCoordinate( + continusAddress.Address, preCommunicationUnit.Address, + AddressTranslator.GetAreaByteLength(continusAddress.Area)) - + preCommunicationUnit.GetCount* + BigEndianValueHelper.Instance.ByteLength[ + preCommunicationUnit.DataType.FullName]) }; addressesGaps.Add(gap); } preCommunicationUnit = continusAddress; } + //减去间隔 var orderedGaps = addressesGaps.OrderBy(p => p.GapNumber); - int jumpNumberInner = JumpNumber; + var jumpNumberInner = JumpNumber; foreach (var orderedGap in orderedGaps) { jumpNumberInner -= orderedGap.GapNumber; @@ -184,7 +233,8 @@ namespace Modbus.Net var preAddress = continusAddresses[index]; continusAddresses.RemoveAt(index); continusAddresses.RemoveAt(index); - var newAddress = new CommunicationUnit() + //变为新的地址段 + var newAddress = new CommunicationUnit { Area = nowAddress.Area, Address = preAddress.Address, @@ -203,21 +253,26 @@ namespace Modbus.Net } } + /// + /// 可以调过多少百分比的地址,把两个地址段变为一个 + /// public class AddressCombinerPercentageJump : AddressCombinerContinus { - private double Percentage { get; } - - public AddressCombinerPercentageJump(double percentage, AddressTranslator addressTranslator) :base (addressTranslator) + public AddressCombinerPercentageJump(double percentage, AddressTranslator addressTranslator) + : base(addressTranslator) { if (percentage < 0) percentage = 0; Percentage = percentage; } + private double Percentage { get; } + public override IEnumerable Combine(IEnumerable addresses) { var addressUnits = addresses as IList ?? addresses.ToList(); - double count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]); - return new AddressCombinerNumericJump((int)(count * Percentage / 100.0), AddressTranslator).Combine(addressUnits); + var count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]); + return + new AddressCombinerNumericJump((int) (count*Percentage/100.0), AddressTranslator).Combine(addressUnits); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/AddressFormater.cs b/Modbus.Net/Modbus.Net/AddressFormater.cs index 18cef1c..c24307f 100644 --- a/Modbus.Net/Modbus.Net/AddressFormater.cs +++ b/Modbus.Net/Modbus.Net/AddressFormater.cs @@ -1,15 +1,14 @@ -using System; - -namespace Modbus.Net +namespace Modbus.Net { /// - /// 地址编码器 + /// 地址编码器 /// public abstract class AddressFormater { public abstract string FormatAddress(string area, int address); + /// - /// 编码地址 + /// 编码地址 /// /// 地址所在的数据区域 /// 地址 @@ -19,7 +18,7 @@ namespace Modbus.Net } /// - /// 基本的地址编码器 + /// 基本的地址编码器 /// public class AddressFormaterBase : AddressFormater { @@ -33,4 +32,4 @@ namespace Modbus.Net return area + ":" + address + ":" + subAddress; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/AddressHelper.cs b/Modbus.Net/Modbus.Net/AddressHelper.cs new file mode 100644 index 0000000..cb8dcf9 --- /dev/null +++ b/Modbus.Net/Modbus.Net/AddressHelper.cs @@ -0,0 +1,98 @@ +using System; + +namespace Modbus.Net +{ + /// + /// 地址辅助类 + /// + public static class AddressHelper + { + /// + /// 将字节坐标变为协议坐标 + /// + /// 字节坐标地址 + /// 起始地址 + /// 协议坐标单个地址的字节长度 + /// + public static double MapAbstractCoordinateToProtocalCoordinate(double abstractAddress, int startAddress, + double byteLength) + { + return abstractAddress/byteLength + startAddress; + } + + /// + /// 将协议坐标变为字节坐标 + /// + /// 协议坐标地址 + /// 起始地址 + /// 协议坐标单个地址的字节长度 + /// + public static double MapProtocalCoordinateToAbstractCoordinate(double protocalAddress, int startAddress, + double byteLength) + { + return (protocalAddress - startAddress)*byteLength; + } + + /// + /// 将协议获取数变为字节获取数 + /// + /// 协议坐标获取个数 + /// 协议坐标区域与字节之间的防缩倍数 + /// 协议坐标单个地址的字节长度 + /// + public static double MapProtocalGetCountToAbstractByteCount(double protocalGetCount, double areaLength, + double byteLength) + { + return protocalGetCount*areaLength + byteLength; + } + + /// + /// 获取协议坐标 + /// + /// 主地址 + /// 子地址 + /// 协议坐标单个地址的字节长度 + /// + public static double GetProtocalCoordinate(int address, int subAddress, double byteLength) + { + return address + subAddress*(0.125/byteLength); + } + + /// + /// 获取字节坐标 + /// + /// 主地址 + /// 子地址 + /// + public static double GetAbstractCoordinate(int address, int subAddress) + { + return address + subAddress*0.125; + } + + /// + /// 获取协议坐标下一个数据的位置 + /// + /// 协议坐标地址 + /// 间隔的数据类型 + /// 协议坐标单个地址的字节长度 + /// + public static double GetProtocalCoordinateNextPosition(double protocalAddress, Type nextPositionBetweenType, + double byteLength) + { + return protocalAddress + + BigEndianValueHelper.Instance.ByteLength[nextPositionBetweenType.FullName]/byteLength; + } + + /// + /// 获取字节坐标下一个数据的位置 + /// + /// 字节坐标地址 + /// 间隔的数据类型 + /// + public static double GetAbstractCoordinateNextPosition(double abstractAddress, Type nextPositionBetweenType) + { + return abstractAddress + + BigEndianValueHelper.Instance.ByteLength[nextPositionBetweenType.FullName]; + } + } +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/AddressTranslator.cs b/Modbus.Net/Modbus.Net/AddressTranslator.cs index e1f1853..cc09a15 100644 --- a/Modbus.Net/Modbus.Net/AddressTranslator.cs +++ b/Modbus.Net/Modbus.Net/AddressTranslator.cs @@ -1,8 +1,10 @@ using System; -using System.Collections.Generic; namespace Modbus.Net { + /// + /// 地址定义类 + /// public class AddressDef { public string AreaString { get; set; } @@ -11,6 +13,9 @@ namespace Modbus.Net public int SubAddress { get; set; } } + /// + /// 区域数据定义类 + /// public class AreaOutputDef { public int Code { get; set; } @@ -18,35 +23,40 @@ namespace Modbus.Net } /// - /// 地址翻译器 + /// 地址翻译器 /// public abstract class AddressTranslator { /// - /// 地址转换 + /// 地址转换 /// /// 地址前地址 /// 是否为读取,是为读取,否为写入 /// Key为转换后的地址,Value为辅助码 public abstract AddressDef AddressTranslate(string address, bool isRead); + /// + /// 获取区域中的单个地址占用的字节长度 + /// + /// 区域名称 + /// 字节长度 public abstract double GetAreaByteLength(string area); } /// - /// 基本的地址翻译器 + /// 基本的地址翻译器 /// public class AddressTranslatorBase : AddressTranslator { public override AddressDef AddressTranslate(string address, bool isRead) { - int num1,num2,num3; - string[] split = address.Split(':'); + int num1, num2, num3; + var split = address.Split(':'); if (split.Length == 2) { if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2)) { - return new AddressDef() + return new AddressDef { Area = num1, Address = num2 @@ -55,13 +65,14 @@ namespace Modbus.Net } else if (split.Length == 3) { - if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2) && int.TryParse(split[3], out num3)) + if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2) && + int.TryParse(split[3], out num3)) { - return new AddressDef() + return new AddressDef { Area = num1, Address = num2, - SubAddress = num3, + SubAddress = num3 }; } } diff --git a/Modbus.Net/Modbus.Net/AsyncHelper.cs b/Modbus.Net/Modbus.Net/AsyncHelper.cs index dfc804e..332d636 100644 --- a/Modbus.Net/Modbus.Net/AsyncHelper.cs +++ b/Modbus.Net/Modbus.Net/AsyncHelper.cs @@ -1,4 +1,9 @@ -using System; +/* AsyncHelper 注释 + * -- AsyncHelper来自于AsyncEx,为了引用方便直接拷贝了代码。Modbus.Net的作者不保留对AsyncHeloper类的版权。 + * -- AsyncHelper copied from AsyncEx. The author of "Modbus.Net" donnot obtain the copyright of AsyncHelper(Only). + */ + +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -8,41 +13,41 @@ namespace Modbus.Net public static class AsyncHelper { private static readonly TaskFactory _myTaskFactory = new - TaskFactory(CancellationToken.None, - TaskCreationOptions.None, - TaskContinuationOptions.None, - TaskScheduler.Default); + TaskFactory(CancellationToken.None, + TaskCreationOptions.None, + TaskContinuationOptions.None, + TaskScheduler.Default); /// - /// Run async method syncronized + /// Run async method syncronized /// /// Return type /// Async method with return /// Return value public static TResult RunSync(Func> func) { - return AsyncHelper._myTaskFactory - .StartNew>(func) - .Unwrap() - .GetAwaiter() - .GetResult(); + return _myTaskFactory + .StartNew(func) + .Unwrap() + .GetAwaiter() + .GetResult(); } /// - /// Run async method syncronized. + /// Run async method syncronized. /// /// Async method public static void RunSync(Func func) { - AsyncHelper._myTaskFactory - .StartNew(func) - .Unwrap() - .GetAwaiter() - .GetResult(); + _myTaskFactory + .StartNew(func) + .Unwrap() + .GetAwaiter() + .GetResult(); } /// - /// Change async task to async task with cancellation token + /// Change async task to async task with cancellation token /// /// Async task /// Cancellation Token @@ -61,12 +66,12 @@ namespace Modbus.Net } /// - /// AsyncLock locks across one or several await calls. + /// AsyncLock locks across one or several await calls. /// public class AsyncLock { - private readonly AsyncSemaphore _semaphore; private readonly Task _releaser; + private readonly AsyncSemaphore _semaphore; public AsyncLock() { @@ -75,7 +80,7 @@ namespace Modbus.Net } /// - /// Lock the async method. Call like: using (await asynclock.LockAsync()) + /// Lock the async method. Call like: using (await asynclock.LockAsync()) /// /// public Task LockAsync() @@ -109,11 +114,11 @@ namespace Modbus.Net } /// - /// AsyncSemaphore semaphore the multi run tasks. + /// AsyncSemaphore semaphore the multi run tasks. /// public class AsyncSemaphore { - private readonly static Task _completed = Task.FromResult(true); + private static readonly Task _completed = Task.FromResult(true); private readonly Queue> _waiters = new Queue>(); private int _currentCount; @@ -135,12 +140,9 @@ namespace Modbus.Net _currentCount--; return _completed; } - else - { - var waiter = new TaskCompletionSource(); - _waiters.Enqueue(waiter); - return waiter.Task; - } + var waiter = new TaskCompletionSource(); + _waiters.Enqueue(waiter); + return waiter.Task; } } @@ -164,4 +166,4 @@ namespace Modbus.Net } } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/BaseConnector.cs b/Modbus.Net/Modbus.Net/BaseConnector.cs index 8fe4164..a237210 100644 --- a/Modbus.Net/Modbus.Net/BaseConnector.cs +++ b/Modbus.Net/Modbus.Net/BaseConnector.cs @@ -1,56 +1,66 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace Modbus.Net { + /// + /// 基础的协议连接类 + /// public abstract class BaseConnector { /// - /// 标识Connector的连接关键字 + /// 标识Connector的连接关键字 /// public abstract string ConnectionToken { get; } + /// - /// 是否处于连接状态 + /// 是否处于连接状态 /// public abstract bool IsConnected { get; } + /// - /// 连接PLC + /// 连接PLC /// /// 是否连接成功 public abstract bool Connect(); + /// - /// 连接PLC,异步 + /// 连接PLC,异步 /// /// 是否连接成功 public abstract Task ConnectAsync(); + /// - /// 断开PLC + /// 断开PLC /// /// 是否断开成功 public abstract bool Disconnect(); + /// - /// 无返回发送数据 + /// 无返回发送数据 /// /// 需要发送的数据 /// 是否发送成功 public abstract bool SendMsgWithoutReturn(byte[] message); + /// - /// 无返回发送数据 + /// 无返回发送数据 /// /// 需要发送的数据 /// 是否发送成功 public abstract Task SendMsgWithoutReturnAsync(byte[] message); + /// - /// 带返回发送数据 + /// 带返回发送数据 /// /// 需要发送的数据 /// 是否发送成功 public abstract byte[] SendMsg(byte[] message); + /// - /// 带返回发送数据 + /// 带返回发送数据 /// /// 需要发送的数据 /// 是否发送成功 public abstract Task SendMsgAsync(byte[] message); } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/BaseMachine.cs b/Modbus.Net/Modbus.Net/BaseMachine.cs index bd017be..fc42fe4 100644 --- a/Modbus.Net/Modbus.Net/BaseMachine.cs +++ b/Modbus.Net/Modbus.Net/BaseMachine.cs @@ -6,121 +6,43 @@ using System.Threading.Tasks; namespace Modbus.Net { /// - /// 获取设备值的方式 + /// 获取设备值的方式 /// public enum MachineGetDataType { /// - /// 地址 + /// 地址 /// Address, + /// - /// 通讯标识 + /// 通讯标识 /// CommunicationTag } /// - /// 向设备设置值的方式 + /// 向设备设置值的方式 /// public enum MachineSetDataType { /// - /// 地址 + /// 地址 /// Address, + /// - /// 通讯标识 + /// 通讯标识 /// CommunicationTag } public abstract class BaseMachine : IMachineProperty { - private int ErrorCount { get; set; } = 0; - private int _maxErrorCount = 3; + private readonly int _maxErrorCount = 3; /// - /// 设备的Id - /// - public string Id { get; set; } - - /// - /// 设备所在工程的名称 - /// - public string ProjectName { get; set; } - - /// - /// 设备的名称 - /// - public string MachineName { get; set; } - - /// - /// 是否处于连接状态 - /// - public bool IsConnected => BaseUtility.IsConnected; - - /// - /// 标识设备的连接关键字 - /// - public string ConnectionToken => BaseUtility.ConnectionToken; - - /// - /// 地址编码器 - /// - public AddressFormater AddressFormater { get; set; } - - /// - /// 获取地址组合器 - /// - public AddressCombiner AddressCombiner { get; set; } - - /// - /// 写入地址组合器 - /// - public AddressCombiner AddressCombinerSet { get; set; } - - /// - /// 地址转换器 - /// - public AddressTranslator AddressTranslator - { - get { return BaseUtility.AddressTranslator; } - set { BaseUtility.AddressTranslator = value; } - } - - /// - /// 与设备实际通讯的连续地址 - /// - protected IEnumerable CommunicateAddresses => GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null; - - /// - /// 描述需要与设备通讯的地址 - /// - public IEnumerable GetAddresses { get; set; } - - /// - /// 是否保持连接 - /// - public bool KeepConnect { get; set; } - - /// - /// 从站号 - /// - public byte SlaveAddress { get; set; } = 2; - - /// - /// 主站号 - /// - public byte MasterAddress { get; set; } = 0; - - /// - /// 设备的连接器 - /// - protected BaseUtility BaseUtility { get; set; } - - /// - /// 构造器 + /// 构造器 /// /// 需要与设备通讯的地址 protected BaseMachine(IEnumerable getAddresses) @@ -129,7 +51,7 @@ namespace Modbus.Net } /// - /// 构造器 + /// 构造器 /// /// 需要与设备通讯的地址 /// 是否保持连接 @@ -140,38 +62,120 @@ namespace Modbus.Net } /// - /// 构造器 + /// 构造器 /// /// 需要与设备通讯的地址 /// 是否保持连接 /// 从站地址 /// 主站地址 - protected BaseMachine(IEnumerable getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress) : this(getAddresses, keepConnect) + protected BaseMachine(IEnumerable getAddresses, bool keepConnect, byte slaveAddress, + byte masterAddress) : this(getAddresses, keepConnect) { SlaveAddress = slaveAddress; MasterAddress = masterAddress; } + private int ErrorCount { get; set; } + /// - /// 读取数据 + /// 是否处于连接状态 + /// + public bool IsConnected => BaseUtility.IsConnected; + + /// + /// 地址编码器 + /// + public AddressFormater AddressFormater { get; set; } + + /// + /// 获取地址组合器 + /// + public AddressCombiner AddressCombiner { get; set; } + + /// + /// 写入地址组合器 + /// + public AddressCombiner AddressCombinerSet { get; set; } + + /// + /// 地址转换器 + /// + public AddressTranslator AddressTranslator + { + get { return BaseUtility.AddressTranslator; } + set { BaseUtility.AddressTranslator = value; } + } + + /// + /// 与设备实际通讯的连续地址 + /// + protected IEnumerable CommunicateAddresses + => GetAddresses != null ? AddressCombiner.Combine(GetAddresses) : null; + + /// + /// 描述需要与设备通讯的地址 + /// + public IEnumerable GetAddresses { get; set; } + + /// + /// 是否保持连接 + /// + public bool KeepConnect { get; set; } + + /// + /// 从站号 + /// + public byte SlaveAddress { get; set; } = 2; + + /// + /// 主站号 + /// + public byte MasterAddress { get; set; } + + /// + /// 设备的连接器 + /// + protected BaseUtility BaseUtility { get; set; } + + /// + /// 设备的Id + /// + public string Id { get; set; } + + /// + /// 设备所在工程的名称 + /// + public string ProjectName { get; set; } + + /// + /// 设备的名称 + /// + public string MachineName { get; set; } + + /// + /// 标识设备的连接关键字 + /// + public string ConnectionToken => BaseUtility.ConnectionToken; + + /// + /// 读取数据 /// /// 从设备读取的数据 public Dictionary GetDatas(MachineGetDataType getDataType) { - return AsyncHelper.RunSync(()=>GetDatasAsync(getDataType)); + return AsyncHelper.RunSync(() => GetDatasAsync(getDataType)); } - /// - /// 读取数据 + /// 读取数据 /// /// 从设备读取的数据 public async Task> GetDatasAsync(MachineGetDataType getDataType) { try { - Dictionary ans = new Dictionary(); + var ans = new Dictionary(); //检测并连接设备 if (!BaseUtility.IsConnected) { @@ -186,7 +190,8 @@ namespace Modbus.Net var datas = await BaseUtility.GetDatasAsync( - AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, communicateAddress.SubAddress), + AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, + communicateAddress.SubAddress), (int) Math.Ceiling(communicateAddress.GetCount* BigEndianValueHelper.Instance.ByteLength[ @@ -195,21 +200,26 @@ namespace Modbus.Net //如果没有数据,终止 if (datas == null || (datas.Length != 0 && datas.Length < - (int) - Math.Ceiling(communicateAddress.GetCount* - BigEndianValueHelper.Instance.ByteLength[ - communicateAddress.DataType.FullName]))) + (int) + Math.Ceiling(communicateAddress.GetCount* + BigEndianValueHelper.Instance.ByteLength[ + communicateAddress.DataType.FullName]))) return null; foreach (var address in communicateAddress.OriginalAddresses) { - var localPos = (address.Address - communicateAddress.Address)* - AddressTranslator.GetAreaByteLength(communicateAddress.Area) + - address.SubAddress/8.0; + //字节坐标的位置 + var localPos = AddressHelper.MapProtocalCoordinateToAbstractCoordinate(address.Address, + communicateAddress.Address, + AddressTranslator.GetAreaByteLength(communicateAddress.Area)) + + address.SubAddress*0.125; + //字节坐标的主地址位置 var localMainPos = (int) localPos; + //字节坐标的子地址位置 var localSubPos = (int) ((localPos - localMainPos)*8); + //根据类型选择返回结果的键是通讯标识还是地址 string key; switch (getDataType) { @@ -230,6 +240,7 @@ namespace Modbus.Net } } + //如果没有数据返回空 if (datas.Length == 0) { ans.Add(key, new ReturnUnit @@ -281,7 +292,7 @@ namespace Modbus.Net } /// - /// 写入数据 + /// 写入数据 /// /// 写入类型 /// 需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述 @@ -292,7 +303,7 @@ namespace Modbus.Net } /// - /// 写入数据 + /// 写入数据 /// /// 写入类型 /// 需要写入的数据字典,当写入类型为Address时,键为需要写入的地址,当写入类型为CommunicationTag时,键为需要写入的单元的描述 @@ -308,7 +319,7 @@ namespace Modbus.Net } //如果设备无法连接,终止 if (!BaseUtility.IsConnected) return false; - List addresses = new List(); + var addresses = new List(); //遍历每个要设置的值 foreach (var value in values) { @@ -333,14 +344,17 @@ namespace Modbus.Net break; } } + //地址为空报错 if (address == null) { Console.WriteLine($"Machine {ConnectionToken} Address {value.Key} doesn't exist."); continue; } + //不能写报错 if (!address.CanWrite) { Console.WriteLine($"Machine {ConnectionToken} Address {value.Key} cannot write."); + continue; } addresses.Add(address); } @@ -376,27 +390,35 @@ namespace Modbus.Net foreach (var addressUnit in communicateAddress.OriginalAddresses) { - var byteCount = (addressUnit.Address - communicateAddress.Address + - addressUnit.SubAddress*0.125/ - AddressTranslator.GetAreaByteLength(communicateAddress.Area)) * - AddressTranslator.GetAreaByteLength(communicateAddress.Area); + //字节坐标地址 + var byteCount = + AddressHelper.MapProtocalGetCountToAbstractByteCount( + addressUnit.Address - communicateAddress.Address + + addressUnit.SubAddress*0.125/ + AddressTranslator.GetAreaByteLength(communicateAddress.Area), + AddressTranslator.GetAreaByteLength(communicateAddress.Area), 0); + //字节坐标主地址 var mainByteCount = (int) byteCount; + //字节坐标自地址 var localByteCount = (int) ((byteCount - (int) byteCount)*8); + //协议坐标地址 var localPos = byteCount/AddressTranslator.GetAreaByteLength(communicateAddress.Area); - //编码当前地址 + //协议坐标子地址 var subPos = (int) ((localPos - (int) localPos)/ (0.125/AddressTranslator.GetAreaByteLength(communicateAddress.Area))); + //协议主地址字符串 var address = AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address + (int) localPos, subPos); + //协议完整地址字符串 var address2 = subPos != 0 ? null : AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address + (int) localPos); //获取写入类型 - Type dataType = addressUnit.DataType; + var dataType = addressUnit.DataType; switch (setDataType) { case MachineSetDataType.Address: @@ -443,7 +465,7 @@ namespace Modbus.Net } /// - /// 连接设备 + /// 连接设备 /// /// 是否连接成功 public bool Connect() @@ -452,7 +474,7 @@ namespace Modbus.Net } /// - /// 连接设备 + /// 连接设备 /// /// 是否连接成功 public async Task ConnectAsync() @@ -461,7 +483,7 @@ namespace Modbus.Net } /// - /// 断开设备 + /// 断开设备 /// /// 是否断开成功 public bool Disconnect() @@ -484,55 +506,60 @@ namespace Modbus.Net } /// - /// 通讯单元 + /// 通讯单元 /// public class CommunicationUnit { /// - /// 区域 + /// 区域 /// public string Area { get; set; } + /// - /// 地址 + /// 地址 /// public int Address { get; set; } + /// - /// 子地址 + /// 子地址 /// public int SubAddress { get; set; } = 0; + /// - /// 获取个数 + /// 获取个数 /// public int GetCount { get; set; } + /// - /// 数据类型 + /// 数据类型 /// public Type DataType { get; set; } + /// - /// 原始的地址 + /// 原始的地址 /// public IEnumerable OriginalAddresses { get; set; } } /// - /// 数据单元扩展,返回数据时会同时将其返回 + /// 数据单元扩展,返回数据时会同时将其返回 /// public class UnitExtend { - } /// - /// 返回的数据单元 + /// 返回的数据单元 /// public class ReturnUnit { /// - /// 返回的数据 + /// 返回的数据 /// public double? PlcValue { get; set; } + /// - /// 数据的扩展 + /// 数据的扩展 /// public UnitExtend UnitExtend { get; set; } } @@ -540,55 +567,69 @@ namespace Modbus.Net public class AddressUnit { /// - /// 数据单元Id + /// 数据单元Id /// public string Id { get; set; } + /// - /// 数据所属的区域 + /// 数据所属的区域 /// public string Area { get; set; } + /// - /// 地址 + /// 地址 /// public int Address { get; set; } + /// - /// bit位地址 + /// bit位地址 /// public int SubAddress { get; set; } = 0; + /// - /// 数据类型 + /// 数据类型 /// public Type DataType { get; set; } + /// - /// 放缩比例 + /// 放缩比例 /// public double Zoom { get; set; } = 1; + /// - /// 小数位数 + /// 小数位数 /// public int DecimalPos { get; set; } + /// - /// 通讯标识名称 + /// 通讯标识名称 /// public string CommunicationTag { get; set; } + /// - /// 名称 + /// 名称 /// public string Name { get; set; } + /// - /// 单位 + /// 单位 /// public string Unit { get; set; } + /// - /// 是否可写,默认可写 + /// 是否可写,默认可写 /// public bool CanWrite { get; set; } = true; + /// - /// 扩展 + /// 扩展 /// public UnitExtend UnitExtend { get; set; } } + /// + /// AddressUnit大小比较 + /// public struct AddressUnitEqualityComparer : IEqualityComparer { public bool Equals(AddressUnit x, AddressUnit y) @@ -603,25 +644,28 @@ namespace Modbus.Net } /// - /// 设备的抽象 + /// 设备的抽象 /// public interface IMachineProperty { /// - /// Id + /// Id /// string Id { get; set; } + /// - /// 工程名 + /// 工程名 /// string ProjectName { get; set; } + /// - /// 设备名 + /// 设备名 /// string MachineName { get; set; } + /// - /// 标识设备的连接关键字 + /// 标识设备的连接关键字 /// string ConnectionToken { get; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/BaseMachineExtend.cs b/Modbus.Net/Modbus.Net/BaseMachineExtend.cs index 68c49e9..019bbb2 100644 --- a/Modbus.Net/Modbus.Net/BaseMachineExtend.cs +++ b/Modbus.Net/Modbus.Net/BaseMachineExtend.cs @@ -1,24 +1,26 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Modbus.Net { + /// + /// BaseMachine扩展类 + /// public static class BaseMachineExtend { /// - /// 将获取的数据转换成可以向设备写入的数据格式 + /// 将获取的数据转换成可以向设备写入的数据格式 + /// 注意转换无法变更读写类型 /// /// 获取的数据 - /// 写入的数据 + /// 应该写入的数据 public static Dictionary MapGetValuesToSetValues(this Dictionary getValues) { if (getValues == null) return null; return (from getValue in getValues where getValue.Value.PlcValue != null - select new KeyValuePair(getValue.Key, getValue.Value.PlcValue.Value)).ToDictionary(p => p.Key, p => p.Value); + select new KeyValuePair(getValue.Key, getValue.Value.PlcValue.Value)).ToDictionary( + p => p.Key, p => p.Value); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/BaseProtocal.cs b/Modbus.Net/Modbus.Net/BaseProtocal.cs index 984b024..471a6b5 100644 --- a/Modbus.Net/Modbus.Net/BaseProtocal.cs +++ b/Modbus.Net/Modbus.Net/BaseProtocal.cs @@ -6,30 +6,30 @@ using System.Threading.Tasks; namespace Modbus.Net { /// - /// 基本协议 + /// 基本协议 /// public abstract class BaseProtocal { - public byte BelongAddress { get; set; } + /// + /// 构造器 + /// + protected BaseProtocal(byte slaveAddress, byte masterAddress) + { + Protocals = new Dictionary(); + SlaveAddress = slaveAddress; + MasterAddress = masterAddress; + } + + public byte SlaveAddress { get; set; } public byte MasterAddress { get; set; } /// - /// 协议的连接器 + /// 协议的连接器 /// public ProtocalLinker ProtocalLinker { get; protected set; } /// - /// 构造器 - /// - protected BaseProtocal(byte belongAddress, byte masterAddress) - { - Protocals = new Dictionary(); - BelongAddress = belongAddress; - MasterAddress = masterAddress; - } - - /// - /// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议 + /// 协议索引器,这是一个懒加载协议,当字典中不存在协议时自动加载协议,否则调用已经加载的协议 /// /// 协议的类的GetType /// 协议的实例 @@ -37,7 +37,7 @@ namespace Modbus.Net { get { - string protocalName = type.FullName; + var protocalName = type.FullName; if (Protocals.ContainsKey(protocalName)) { return Protocals[protocalName]; @@ -52,12 +52,12 @@ namespace Modbus.Net } /// - /// 协议集合 + /// 协议集合 /// protected Dictionary Protocals { get; } /// - /// 注册一个协议 + /// 注册一个协议 /// /// 需要注册的协议 protected void Register(ProtocalUnit linkProtocal) @@ -67,7 +67,7 @@ namespace Modbus.Net } /// - /// 发送协议内容并接收,一般方法 + /// 发送协议内容并接收,一般方法 /// /// 是否是小端格式 /// 写入的内容,使用对象数组描述 @@ -78,7 +78,7 @@ namespace Modbus.Net } /// - /// 发送协议内容并接收,一般方法 + /// 发送协议内容并接收,一般方法 /// /// 是否是小端格式 /// 写入的内容,使用对象数组描述 @@ -93,14 +93,11 @@ namespace Modbus.Net { return await ProtocalLinker.SendReceiveAsync(ProtocalUnit.TranslateContent(isLittleEndian, content)); } - else - { - return null; - } + return null; } /// - /// 发送协议,通过传入需要使用的协议内容和输入结构 + /// 发送协议,通过传入需要使用的协议内容和输入结构 /// /// 协议的实例 /// 输入信息的结构化描述 @@ -111,14 +108,14 @@ namespace Modbus.Net } /// - /// 发送协议,通过传入需要使用的协议内容和输入结构 + /// 发送协议,通过传入需要使用的协议内容和输入结构 /// /// 协议的实例 /// 输入信息的结构化描述 /// 输出信息的结构化描述 public virtual async Task SendReceiveAsync(ProtocalUnit unit, InputStruct content) { - int t = 0; + var t = 0; var formatContent = unit.Format(content); if (formatContent != null) { @@ -141,19 +138,19 @@ namespace Modbus.Net } /// - /// 协议连接开始 + /// 协议连接开始 /// /// public abstract bool Connect(); /// - /// 协议连接开始(异步) + /// 协议连接开始(异步) /// /// public abstract Task ConnectAsync(); /// - /// 协议连接断开 + /// 协议连接断开 /// /// public virtual bool Disconnect() diff --git a/Modbus.Net/Modbus.Net/BaseUtility.cs b/Modbus.Net/Modbus.Net/BaseUtility.cs index 007cbad..9b6fb2c 100644 --- a/Modbus.Net/Modbus.Net/BaseUtility.cs +++ b/Modbus.Net/Modbus.Net/BaseUtility.cs @@ -8,56 +8,58 @@ namespace Modbus.Net public abstract class BaseUtility { /// - /// 协议收发主体 + /// 协议收发主体 /// protected BaseProtocal Wrapper; - protected string ConnectionString { get; set; } - - public byte BelongAddress { get; set; } - public byte MasterAddress { get; set; } /// - /// 获取协议是否遵循小端格式 + /// 构造器 /// - public abstract bool GetLittleEndian { get; } - /// - /// 设置协议是否遵循小端格式 - /// - public abstract bool SetLittleEndian { get; } - - /// - /// 设备是否已经连接 - /// - public bool IsConnected => Wrapper?.ProtocalLinker != null && Wrapper.ProtocalLinker.IsConnected; - - /// - /// 标识设备的连接关键字 - /// - public string ConnectionToken => Wrapper.ProtocalLinker.ConnectionToken; - - /// - /// 地址翻译器 - /// - public AddressTranslator AddressTranslator { get; set; } - - /// - /// 构造器 - /// - protected BaseUtility(byte belongAddress, byte masterAddress) + protected BaseUtility(byte slaveAddress, byte masterAddress) { - BelongAddress = belongAddress; + SlaveAddress = slaveAddress; MasterAddress = masterAddress; AddressTranslator = new AddressTranslatorBase(); } + protected string ConnectionString { get; set; } + + public byte SlaveAddress { get; set; } + public byte MasterAddress { get; set; } + /// - /// 设置连接类型 + /// 获取协议是否遵循小端格式 + /// + public abstract bool GetLittleEndian { get; } + + /// + /// 设置协议是否遵循小端格式 + /// + public abstract bool SetLittleEndian { get; } + + /// + /// 设备是否已经连接 + /// + public bool IsConnected => Wrapper?.ProtocalLinker != null && Wrapper.ProtocalLinker.IsConnected; + + /// + /// 标识设备的连接关键字 + /// + public string ConnectionToken => Wrapper.ProtocalLinker.ConnectionToken; + + /// + /// 地址翻译器 + /// + public AddressTranslator AddressTranslator { get; set; } + + /// + /// 设置连接类型 /// /// 连接类型 public abstract void SetConnectionType(int connectionType); /// - /// 获取数据 + /// 获取数据 /// /// 开始地址 /// 获取字节数个数 @@ -68,7 +70,7 @@ namespace Modbus.Net } /// - /// 获取数据 + /// 获取数据 /// /// 开始地址 /// 获取字节数个数 @@ -76,10 +78,8 @@ namespace Modbus.Net public abstract Task GetDatasAsync(string startAddress, int getByteCount); /// - /// 获取数据 + /// 获取数据 /// - /// 从站地址 - /// 主站地址 /// 开始地址 /// 获取类型和个数 /// 接收到的对应的类型和数据 @@ -90,10 +90,8 @@ namespace Modbus.Net } /// - /// 获取数据 + /// 获取数据 /// - /// 从站地址 - /// 主站地址 /// 开始地址 /// 获取类型和个数 /// 接收到的对应的类型和数据 @@ -102,10 +100,10 @@ namespace Modbus.Net { try { - string typeName = getTypeAndCount.Key.FullName; - double bCount = BigEndianValueHelper.Instance.ByteLength[typeName]; + var typeName = getTypeAndCount.Key.FullName; + var bCount = BigEndianValueHelper.Instance.ByteLength[typeName]; var getReturnValue = await GetDatasAsync(startAddress, - (int)Math.Ceiling(bCount * getTypeAndCount.Value)); + (int) Math.Ceiling(bCount*getTypeAndCount.Value)); var getBytes = getReturnValue; return GetLittleEndian ? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount) @@ -118,11 +116,9 @@ namespace Modbus.Net } /// - /// 获取数据 + /// 获取数据 /// /// 需要接收的类型 - /// 从站地址 - /// 主站地址 /// 开始地址 /// 获取字节数个数 /// 接收到的对应的类型和数据 @@ -133,11 +129,9 @@ namespace Modbus.Net } /// - /// 获取数据 + /// 获取数据 /// /// 需要接收的类型 - /// 从站地址 - /// 主站地址 /// 开始地址 /// 获取字节数个数 /// 接收到的对应的类型和数据 @@ -147,7 +141,7 @@ namespace Modbus.Net try { var getBytes = await GetDatasAsync(startAddress, - new KeyValuePair(typeof(T), getByteCount)); + new KeyValuePair(typeof (T), getByteCount)); return BigEndianValueHelper.Instance.ObjectArrayToDestinationArray(getBytes); } catch (Exception) @@ -157,7 +151,7 @@ namespace Modbus.Net } /// - /// 获取数据 + /// 获取数据 /// /// 开始地址 /// 获取类型和个数的队列 @@ -170,7 +164,7 @@ namespace Modbus.Net } /// - /// 获取数据 + /// 获取数据 /// /// 开始地址 /// 获取类型和个数的队列 @@ -181,13 +175,13 @@ namespace Modbus.Net { var translateTypeAndCount = getTypeAndCountList as IList> ?? getTypeAndCountList.ToList(); - int bAllCount = ( + var bAllCount = ( from getTypeAndCount in translateTypeAndCount let typeName = getTypeAndCount.Key.FullName let bCount = BigEndianValueHelper.Instance.ByteLength[typeName] select (int) Math.Ceiling(bCount*getTypeAndCount.Value)).Sum(); var getReturnValue = await GetDatasAsync(startAddress, bAllCount); - byte[] getBytes = getReturnValue; + var getBytes = getReturnValue; return GetLittleEndian ? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount) : BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount); @@ -199,7 +193,7 @@ namespace Modbus.Net } /// - /// 设置数据 + /// 设置数据 /// /// 开始地址 /// 设置数据 @@ -210,13 +204,13 @@ namespace Modbus.Net } /// - /// 设置数据 + /// 设置数据 /// /// 开始地址 /// 设置数据 /// 是否设置成功 public abstract Task SetDatasAsync(string startAddress, object[] setContents); - + /* /// /// 获取PLC时间 @@ -233,7 +227,7 @@ namespace Modbus.Net */ /// - /// 连接设备 + /// 连接设备 /// /// 设备是否连接成功 public bool Connect() @@ -242,7 +236,7 @@ namespace Modbus.Net } /// - /// 连接设备 + /// 连接设备 /// /// 设备是否连接成功 public async Task ConnectAsync() @@ -251,13 +245,12 @@ namespace Modbus.Net } /// - /// 断开设备 + /// 断开设备 /// /// 设备是否断开成功 public bool Disconnect() { return Wrapper.Disconnect(); } - } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/CRC16.cs b/Modbus.Net/Modbus.Net/CRC16.cs index 7fed232..b201256 100644 --- a/Modbus.Net/Modbus.Net/CRC16.cs +++ b/Modbus.Net/Modbus.Net/CRC16.cs @@ -1,16 +1,21 @@ -using System; +/* + * Crc16来自于多个网络上的代码,Modbus.Net的作者不保留对Crc16类的版权。 + * Crc16 class comes from mutiple websites, the author of "Modbus.Net" donnot obtain the copyright of Crc16(only). + */ + +using System; namespace Modbus.Net { public class Crc16 { + private static Crc16 _crc16; + /// - /// CRC验证表 + /// CRC验证表 /// public byte[] crc_table = new byte[512]; - private static Crc16 _crc16 = null; - public static Crc16 GetInstance() { if (_crc16 == null) @@ -23,40 +28,40 @@ namespace Modbus.Net #region 生成CRC码 /// - /// 生成CRC码 + /// 生成CRC码 /// /// 发送或返回的命令,CRC码除外 /// 存储CRC码的字节的数组 /// 生成的CRC码 public short GetCRC(byte[] message, ref byte[] Rcvbuf) { - int IX,IY,CRC; - int Len = message.Length; - CRC=0xFFFF; + int IX, IY, CRC; + var Len = message.Length; + CRC = 0xFFFF; //set all 1 - if (Len<=0) - CRC = 0; - else - { - Len--; - for (IX=0;IX<=Len;IX++) - { - CRC=CRC^(message[IX]); - for(IY=0;IY<=7;IY++) - { - if ((CRC&1)!=0 ) - CRC=(CRC>>1)^0xA001; - else - CRC=CRC>>1; + if (Len <= 0) + CRC = 0; + else + { + Len--; + for (IX = 0; IX <= Len; IX++) + { + CRC = CRC ^ message[IX]; + for (IY = 0; IY <= 7; IY++) + { + if ((CRC & 1) != 0) + CRC = (CRC >> 1) ^ 0xA001; + else + CRC = CRC >> 1; // - } - } - } - Rcvbuf[1] = (byte)((CRC & 0xff00)>>8);//高位置 - Rcvbuf[0] = (byte)(CRC & 0x00ff); //低位置 - CRC= Rcvbuf[0]<<8; - CRC+= Rcvbuf[1]; - return (short)CRC; + } + } + } + Rcvbuf[1] = (byte) ((CRC & 0xff00) >> 8); //高位置 + Rcvbuf[0] = (byte) (CRC & 0x00ff); //低位置 + CRC = Rcvbuf[0] << 8; + CRC += Rcvbuf[1]; + return (short) CRC; } #endregion @@ -64,31 +69,28 @@ namespace Modbus.Net #region CRC验证 /// - /// CRC校验 + /// CRC校验 /// /// ST开头,&&结尾 /// 十六进制数 public bool CrcEfficacy(byte[] byteframe) { - byte[] recvbuff = new byte[2]; - byte[] byteArr = new byte[byteframe.Length - 2]; + var recvbuff = new byte[2]; + var byteArr = new byte[byteframe.Length - 2]; Array.Copy(byteframe, 0, byteArr, 0, byteArr.Length); GetCRC(byteArr, ref recvbuff); if (recvbuff[0] == byteframe[byteframe.Length - 2] && recvbuff[1] == byteframe[byteframe.Length - 1]) { return true; } - else - { - return false; - } + return false; } #endregion /// - /// 取模FF(255) - /// 取反+1 + /// 取模FF(255) + /// 取反+1 /// /// /// @@ -97,25 +99,25 @@ namespace Modbus.Net var index = message.IndexOf(Environment.NewLine, StringComparison.InvariantCulture); var writeUncheck = message.Substring(1, index - 2); var checkString = message.Substring(index - 2, 2); - char[] hexArray = new char[writeUncheck.Length]; + var hexArray = new char[writeUncheck.Length]; hexArray = writeUncheck.ToCharArray(); int decNum = 0, decNumMSB = 0, decNumLSB = 0; int decByte, decByteTotal = 0; - bool msb = true; + var msb = true; - for (int t = 0; t <= hexArray.GetUpperBound(0); t++) + for (var t = 0; t <= hexArray.GetUpperBound(0); t++) { if ((hexArray[t] >= 48) && (hexArray[t] <= 57)) - decNum = (hexArray[t] - 48); + decNum = hexArray[t] - 48; else if ((hexArray[t] >= 65) & (hexArray[t] <= 70)) decNum = 10 + (hexArray[t] - 65); if (msb) { - decNumMSB = decNum * 16; + decNumMSB = decNum*16; msb = false; } else @@ -130,7 +132,7 @@ namespace Modbus.Net } } - decByteTotal = (255 - decByteTotal) + 1; + decByteTotal = 255 - decByteTotal + 1; decByteTotal = decByteTotal & 255; int a, b = 0; @@ -141,7 +143,7 @@ namespace Modbus.Net for (i = 0; decByteTotal > 0; i++) { //b = Convert.ToInt32(System.Math.Pow(16.0, i)); - a = decByteTotal % 16; + a = decByteTotal%16; decByteTotal /= 16; if (a <= 9) hexByte = a.ToString(); @@ -169,7 +171,7 @@ namespace Modbus.Net break; } } - hexTotal = String.Concat(hexByte, hexTotal); + hexTotal = string.Concat(hexByte, hexTotal); } return hexTotal == checkString; } @@ -177,13 +179,13 @@ namespace Modbus.Net public string GetLRC(byte[] code) { byte sum = 0; - foreach (byte b in code) + foreach (var b in code) { sum += b; } - sum = (byte)(~sum + 1);//取反+1 - string lrc = sum.ToString("X2"); + sum = (byte) (~sum + 1); //取反+1 + var lrc = sum.ToString("X2"); return lrc; } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/ComConnector.cs b/Modbus.Net/Modbus.Net/ComConnector.cs index bc48f10..e5b29fd 100644 --- a/Modbus.Net/Modbus.Net/ComConnector.cs +++ b/Modbus.Net/Modbus.Net/ComConnector.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.IO.Ports; using System.Text; using System.Threading; @@ -6,12 +7,45 @@ using System.Threading.Tasks; namespace Modbus.Net { + /// + /// 串口通讯类 + /// public class ComConnector : BaseConnector, IDisposable { - public override string ConnectionToken => _com; + public delegate byte[] GetDate(byte[] bts); + + private readonly int _baudRate; + + //private GetDate mygetDate; + private readonly string _com; + private readonly int _dataBits; + private readonly Parity _parity; + private readonly StopBits _stopBits; + private readonly int _timeoutTime; private SerialPort _serialPort1; + private bool m_disposed = true; + + public ComConnector(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits, int timeoutTime) + { + _com = com; + _timeoutTime = timeoutTime; + _baudRate = baudRate; + _parity = parity; + _stopBits = stopBits; + _dataBits = dataBits; + + //端口号 + //读超时 + //比特率 + //奇偶校验 + //停止位 + //数据位 + } + + public override string ConnectionToken => _com; + private SerialPort SerialPort1 { get @@ -25,38 +59,222 @@ namespace Modbus.Net Parity = _parity, StopBits = _stopBits, DataBits = _dataBits, - ReadTimeout = _timeoutTime, + ReadTimeout = _timeoutTime }; } return _serialPort1; } - } - public delegate byte[] GetDate(byte[] bts); - - //private GetDate mygetDate; - private readonly string _com; - private readonly int _timeoutTime; - private readonly int _baudRate; - private readonly Parity _parity; - private readonly StopBits _stopBits; - private readonly int _dataBits; - - public ComConnector(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits, int timeoutTime) + /// + /// 实现IDisposable接口 + /// + public void Dispose() { - _com = com; - _timeoutTime = timeoutTime; - _baudRate = baudRate; - _parity = parity; - _stopBits = stopBits; - _dataBits = dataBits; + Dispose(true); + //.NET Framework 类库 + // GC..::.SuppressFinalize 方法 + //请求系统不要调用指定对象的终结器。 + GC.SuppressFinalize(this); + } - //端口号 - //比特率 - //奇偶校验 - //停止位 - //读超时,即在1000内未读到数据就引起超时异常 + /// + /// 串口读(非阻塞方式读串口,直到串口缓冲区中没有数据 + /// + /// 串口数据缓冲 + /// 串口数据缓冲空间大小 + /// 设置串口读放弃时间 + /// 字节间隔最大时间 + /// 串口实际读入数据个数 + public int ReadComm(out byte[] readBuf, int bufRoom, int HowTime, int ByteTime) + { + //throw new System.NotImplementedException(); + readBuf = new byte[1023]; + Array.Clear(readBuf, 0, readBuf.Length); + + int nReadLen, nBytelen; + if (SerialPort1.IsOpen == false) + return -1; + nBytelen = 0; + SerialPort1.ReadTimeout = HowTime; + + + try + { + while (SerialPort1.BytesToRead > 0) + { + readBuf[nBytelen] = (byte) SerialPort1.ReadByte(); + var bTmp = new byte[bufRoom]; + Array.Clear(bTmp, 0, bTmp.Length); + + nReadLen = ReadBlock(bTmp, bufRoom, ByteTime); + + if (nReadLen > 0) + { + Array.Copy(bTmp, 0, readBuf, nBytelen + 1, nReadLen); + nBytelen += 1 + nReadLen; + } + + else if (nReadLen == 0) + nBytelen += 1; + } + } + catch (Exception ex) + { + throw new Exception(ex.Message); + } + + return nBytelen; + } + + /// + /// 串口同步读(阻塞方式读串口,直到串口缓冲区中没有数据,靠字符间间隔超时确定没有数据) + /// + /// 串口数据缓冲 + /// 串口数据缓冲空间大小 + /// 字节间隔最大时间 + /// 从串口实际读入的字节个数 + public int ReadBlock(byte[] ReadBuf, int ReadRoom, int ByteTime) + { + sbyte nBytelen; + //long nByteRead; + + if (SerialPort1.IsOpen == false) + return 0; + nBytelen = 0; + SerialPort1.ReadTimeout = ByteTime; + + while (nBytelen < ReadRoom - 1 && SerialPort1.BytesToRead > 0) + { + try + { + ReadBuf[nBytelen] = (byte) SerialPort1.ReadByte(); + nBytelen++; // add one + } + catch (Exception ex) + { + throw new Exception(ex.Message); + } + } + ReadBuf[nBytelen] = 0x00; + return nBytelen; + } + + + /// + /// 字符数组转字符串16进制 + /// + /// 二进制字节 + /// 类似"01 02 0F" + public static string ByteToString(byte[] InBytes) + { + var StringOut = ""; + foreach (var InByte in InBytes) + { + StringOut = StringOut + string.Format("{0:X2}", InByte) + " "; + } + + return StringOut.Trim(); + } + + /// + /// strhex 转字节数组 + /// + /// 类似"01 02 0F" 用空格分开的 + /// + public static byte[] StringToByte(string InString) + { + string[] ByteStrings; + ByteStrings = InString.Split(" ".ToCharArray()); + byte[] ByteOut; + ByteOut = new byte[ByteStrings.Length]; + for (var i = 0; i <= ByteStrings.Length - 1; i++) + { + ByteOut[i] = byte.Parse(ByteStrings[i], NumberStyles.HexNumber); + } + return ByteOut; + } + + /// + /// strhex 转字节数组 + /// + /// 类似"01 02 0F" 中间无空格 + /// + public static byte[] StringToByte_2(string InString) + { + byte[] ByteOut; + InString = InString.Replace(" ", ""); + try + { + var ByteStrings = new string[InString.Length/2]; + var j = 0; + for (var i = 0; i < ByteStrings.Length; i++) + { + ByteStrings[i] = InString.Substring(j, 2); + j += 2; + } + + ByteOut = new byte[ByteStrings.Length]; + for (var i = 0; i <= ByteStrings.Length - 1; i++) + { + ByteOut[i] = byte.Parse(ByteStrings[i], NumberStyles.HexNumber); + } + } + catch (Exception ex) + { + throw new Exception(ex.Message); + } + + return ByteOut; + } + + /// + /// 字符串 转16进制字符串 + /// + /// unico + /// 类似“01 0f” + public static string Str_To_0X(string InString) + { + return ByteToString(Encoding.Default.GetBytes(InString)); + } + + /// + /// 虚方法,可供子类重写 + /// + /// + protected virtual void Dispose(bool disposing) + { + if (!m_disposed) + { + if (disposing) + { + // Release managed resources + } + // Release unmanaged resources + if (_serialPort1 != null) + { + try + { + _serialPort1.Close(); + } + catch (Exception) + { + //ignore + } + _serialPort1.Dispose(); + _serialPort1 = null; + } + m_disposed = true; + } + } + + /// + /// 析构函数 + /// 当客户端没有显示调用Dispose()时由GC完成资源回收功能 + /// + ~ComConnector() + { + Dispose(false); } #region 发送接收数据 @@ -110,11 +328,10 @@ namespace Modbus.Net } public void SendMsg(string senStr) - { - byte[] myByte = StringToByte_2(senStr); + { + var myByte = StringToByte_2(senStr); SendMsg(myByte); - } public override Task SendMsgWithoutReturnAsync(byte[] message) @@ -136,7 +353,7 @@ namespace Modbus.Net { Dispose(); SerialPort1.Open(); - } + } } SerialPort1.Write(sendbytes, 0, sendbytes.Length); return ReadMsg(); @@ -164,18 +381,16 @@ namespace Modbus.Net { return false; } - } public string ReadMsgStr() { - string rd = ""; + var rd = ""; - byte[] data = ReadMsg(); + var data = ReadMsg(); rd = ByteToString(data); return rd; - } public byte[] ReadMsg() @@ -189,8 +404,8 @@ namespace Modbus.Net byte[] data; Thread.Sleep(100); - int i = ReadComm(out data, 10, 5000, 1000); - byte[] returndata = new byte[i]; + var i = ReadComm(out data, 10, 5000, 1000); + var returndata = new byte[i]; Array.Copy(data, 0, returndata, 0, i); return returndata; } @@ -198,225 +413,9 @@ namespace Modbus.Net { Dispose(); return null; - } + } } #endregion - - /// - /// 串口读(非阻塞方式读串口,直到串口缓冲区中没有数据 - /// - /// 串口数据缓冲 - /// 串口数据缓冲空间大小 - /// 设置串口读放弃时间 - /// 字节间隔最大时间 - /// 串口实际读入数据个数 - public int ReadComm(out Byte[] readBuf, int bufRoom, int HowTime, int ByteTime) - { - //throw new System.NotImplementedException(); - readBuf = new Byte[1023]; - Array.Clear(readBuf, 0, readBuf.Length); - - int nReadLen, nBytelen; - if (SerialPort1.IsOpen == false) - return -1; - nBytelen = 0; - SerialPort1.ReadTimeout = HowTime; - - - try - { - while (SerialPort1.BytesToRead > 0) - { - readBuf[nBytelen] = (byte) SerialPort1.ReadByte(); - byte[] bTmp = new byte[bufRoom]; - Array.Clear(bTmp, 0, bTmp.Length); - - nReadLen = ReadBlock(bTmp, bufRoom, ByteTime); - - if (nReadLen > 0) - { - Array.Copy(bTmp, 0, readBuf, nBytelen + 1, nReadLen); - nBytelen += 1 + nReadLen; - } - - else if (nReadLen == 0) - nBytelen += 1; - } - } - catch (Exception ex) - { - throw new Exception(ex.Message); - - } - - return nBytelen; - } - - /// - /// 串口同步读(阻塞方式读串口,直到串口缓冲区中没有数据,靠字符间间隔超时确定没有数据) - /// - /// 串口数据缓冲 - /// 串口数据缓冲空间大小 - /// 字节间隔最大时间 - /// 从串口实际读入的字节个数 - public int ReadBlock(byte[] ReadBuf, int ReadRoom, int ByteTime) - { - sbyte nBytelen; - //long nByteRead; - - if (SerialPort1.IsOpen == false) - return 0; - nBytelen = 0; - SerialPort1.ReadTimeout = ByteTime; - - while (nBytelen < ReadRoom - 1 && SerialPort1.BytesToRead > 0) - { - try - { - ReadBuf[nBytelen] = (byte) SerialPort1.ReadByte(); - nBytelen++; // add one - } - catch (Exception ex) - { - throw new Exception(ex.Message); - } - } - ReadBuf[nBytelen] = 0x00; - return nBytelen; - } - - - /// - /// 字符数组转字符串16进制 - /// - /// 二进制字节 - /// 类似"01 02 0F" - public static string ByteToString(byte[] InBytes) - { - string StringOut = ""; - foreach (byte InByte in InBytes) - { - StringOut = StringOut + String.Format("{0:X2}", InByte) + " "; - } - - return StringOut.Trim(); - } - - /// - /// strhex 转字节数组 - /// - /// 类似"01 02 0F" 用空格分开的 - /// - public static byte[] StringToByte(string InString) - { - string[] ByteStrings; - ByteStrings = InString.Split(" ".ToCharArray()); - byte[] ByteOut; - ByteOut = new byte[ByteStrings.Length]; - for (int i = 0; i <= ByteStrings.Length - 1; i++) - { - ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber); - } - return ByteOut; - } - - /// - /// strhex 转字节数组 - /// - /// 类似"01 02 0F" 中间无空格 - /// - public static byte[] StringToByte_2(string InString) - { - byte[] ByteOut; - InString = InString.Replace(" ", ""); - try - { - string[] ByteStrings = new string[InString.Length/2]; - int j = 0; - for (int i = 0; i < ByteStrings.Length; i++) - { - - ByteStrings[i] = InString.Substring(j, 2); - j += 2; - } - - ByteOut = new byte[ByteStrings.Length]; - for (int i = 0; i <= ByteStrings.Length - 1; i++) - { - ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber); - } - } - catch (Exception ex) - { - - throw new Exception(ex.Message); - } - - return ByteOut; - } - - /// - /// 字符串 转16进制字符串 - /// - /// unico - /// 类似“01 0f” - public static string Str_To_0X(string InString) - { - return ByteToString(UnicodeEncoding.Default.GetBytes(InString)); - } - - /// -     /// 实现IDisposable接口 -     /// - public void Dispose() - { - Dispose(true); - //.NET Framework 类库 - // GC..::.SuppressFinalize 方法 - //请求系统不要调用指定对象的终结器。 - GC.SuppressFinalize(this); - } - - private bool m_disposed = true; - - /// - /// 虚方法,可供子类重写 - /// - /// - protected virtual void Dispose(bool disposing) - { - if (!m_disposed) - { - if (disposing) - { - // Release managed resources - } - // Release unmanaged resources - if (_serialPort1 != null) - { - try - { - _serialPort1.Close(); - } - catch (Exception) - { - //ignore - } - _serialPort1.Dispose(); - _serialPort1 = null; - } - m_disposed = true; - } - } - - /// - /// 析构函数 - /// 当客户端没有显示调用Dispose()时由GC完成资源回收功能 - /// - ~ComConnector() - { - Dispose(false); - } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/ComProtocalLinker.cs b/Modbus.Net/Modbus.Net/ComProtocalLinker.cs index f3195ea..e596f0f 100644 --- a/Modbus.Net/Modbus.Net/ComProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net/ComProtocalLinker.cs @@ -1,18 +1,21 @@ -using System; -using System.IO.Ports; +using System.IO.Ports; namespace Modbus.Net { + /// + /// 串口连接对象 + /// public abstract class ComProtocalLinker : ProtocalLinker { - protected ComProtocalLinker(int baudRate, Parity parity, StopBits stopBits, int dataBits) : this(ConfigurationManager.COM, baudRate, parity, stopBits, dataBits) + protected ComProtocalLinker(int baudRate, Parity parity, StopBits stopBits, int dataBits) + : this(ConfigurationManager.COM, baudRate, parity, stopBits, dataBits) { } protected ComProtocalLinker(string com, int baudRate, Parity parity, StopBits stopBits, int dataBits) { //初始化连对象 - _baseConnector = new ComConnector(com, baudRate, parity, stopBits, dataBits, 30000); + BaseConnector = new ComConnector(com, baudRate, parity, stopBits, dataBits, 30000); } } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/IProtocalFormatting.cs b/Modbus.Net/Modbus.Net/IProtocalFormatting.cs index 9e26aa3..ca73ccc 100644 --- a/Modbus.Net/Modbus.Net/IProtocalFormatting.cs +++ b/Modbus.Net/Modbus.Net/IProtocalFormatting.cs @@ -1,26 +1,26 @@ namespace Modbus.Net { /// - /// 协议转换的接口 + /// 协议转换的接口 /// public interface IProtocalFormatting { /// - /// 从输入结构格式化 + /// 从输入结构格式化 /// /// 结构化的输入数据 /// 格式化后的字节流 byte[] Format(InputStruct message); /// - /// 从对象的参数数组格式化 + /// 从对象的参数数组格式化 /// /// 非结构化的输入数据 /// 格式化后的字节流 byte[] Format(params object[] message); /// - /// 把仪器返回的内容填充到输出结构中 + /// 把仪器返回的内容填充到输出结构中 /// /// 返回数据的字节流 /// 转换标记位 diff --git a/Modbus.Net/Modbus.Net/Modbus.Net.csproj b/Modbus.Net/Modbus.Net/Modbus.Net.csproj index 23c2ab2..ff1a8bf 100644 --- a/Modbus.Net/Modbus.Net/Modbus.Net.csproj +++ b/Modbus.Net/Modbus.Net/Modbus.Net.csproj @@ -53,6 +53,7 @@ + diff --git a/Modbus.Net/Modbus.Net/ProtocalLinker.cs b/Modbus.Net/Modbus.Net/ProtocalLinker.cs index 04dc728..0f5b54c 100644 --- a/Modbus.Net/Modbus.Net/ProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net/ProtocalLinker.cs @@ -1,52 +1,51 @@ using System.Reflection; -using System.Text; using System.Threading.Tasks; namespace Modbus.Net { /// - /// 基本的协议连接器 + /// 基本的协议连接器 /// public abstract class ProtocalLinker { - protected BaseConnector _baseConnector; + protected BaseConnector BaseConnector; - public string ConnectionToken => _baseConnector.ConnectionToken; + public string ConnectionToken => BaseConnector.ConnectionToken; /// - /// 设备是否连接 + /// 设备是否连接 /// - public bool IsConnected => _baseConnector != null && _baseConnector.IsConnected; + public bool IsConnected => BaseConnector != null && BaseConnector.IsConnected; /// - /// 连接设备 + /// 连接设备 /// /// 设备是否连接成功 public bool Connect() { - return _baseConnector.Connect(); + return BaseConnector.Connect(); } /// - /// 连接设备 + /// 连接设备 /// /// 设备是否连接成功 public async Task ConnectAsync() { - return await _baseConnector.ConnectAsync(); + return await BaseConnector.ConnectAsync(); } - + /// - /// 断开设备 + /// 断开设备 /// /// 设备是否断开成功 public bool Disconnect() { - return _baseConnector.Disconnect(); + return BaseConnector.Disconnect(); } /// - /// 发送并接收数据 + /// 发送并接收数据 /// /// 发送协议的内容 /// 接收协议的内容 @@ -56,19 +55,19 @@ namespace Modbus.Net } /// - /// 发送并接收数据 + /// 发送并接收数据 /// /// 发送协议的内容 /// 接收协议的内容 public virtual async Task SendReceiveAsync(byte[] content) { - byte[] extBytes = BytesExtend(content); - byte[] receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes); + var extBytes = BytesExtend(content); + var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes); return receiveBytes == null ? null : receiveBytes.Length == 0 ? receiveBytes : BytesDecact(receiveBytes); } /// - /// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议 + /// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议 /// /// 发送协议的内容 /// 接收协议的内容 @@ -78,14 +77,14 @@ namespace Modbus.Net } /// - /// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议 + /// 发送并接收数据,不进行协议扩展和收缩,用于特殊协议 /// /// 发送协议的内容 /// 接收协议的内容 public virtual async Task SendReceiveWithoutExtAndDecAsync(byte[] content) { //发送数据 - byte[] receiveBytes = await _baseConnector.SendMsgAsync(content); + var receiveBytes = await BaseConnector.SendMsgAsync(content); //容错处理 var checkRight = CheckRight(receiveBytes); return checkRight == null ? new byte[0] : (!checkRight.Value ? null : receiveBytes); @@ -93,7 +92,7 @@ namespace Modbus.Net } /// - /// 检查接收的数据是否正确 + /// 检查接收的数据是否正确 /// /// 接收协议的内容 /// 协议是否是正确的 @@ -105,29 +104,29 @@ namespace Modbus.Net } /// - /// 协议内容扩展,发送时根据需要扩展 + /// 协议内容扩展,发送时根据需要扩展 /// /// 扩展前的基本协议内容 /// 扩展后的协议内容 public byte[] BytesExtend(byte[] content) { //自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。 - ProtocalLinkerBytesExtend bytesExtend = - Assembly.Load(this.GetType().Assembly.FullName).CreateInstance(this.GetType().FullName + "BytesExtend") as + var bytesExtend = + Assembly.Load(GetType().Assembly.FullName).CreateInstance(GetType().FullName + "BytesExtend") as ProtocalLinkerBytesExtend; return bytesExtend?.BytesExtend(content); } /// - /// 协议内容缩减,接收时根据需要缩减 + /// 协议内容缩减,接收时根据需要缩减 /// /// 缩减前的完整协议内容 /// 缩减后的协议内容 public byte[] BytesDecact(byte[] content) { //自动查找相应的协议放缩类,命令规则为——当前的实际类名(注意是继承后的)+"BytesExtend"。 - ProtocalLinkerBytesExtend bytesExtend = - Assembly.Load(this.GetType().Assembly.GetName().Name).CreateInstance(this.GetType().FullName + "BytesExtend") as + var bytesExtend = + Assembly.Load(GetType().Assembly.GetName().Name).CreateInstance(GetType().FullName + "BytesExtend") as ProtocalLinkerBytesExtend; return bytesExtend?.BytesDecact(content); } diff --git a/Modbus.Net/Modbus.Net/ProtocalLinkerBytesExtend.cs b/Modbus.Net/Modbus.Net/ProtocalLinkerBytesExtend.cs index de94566..9c27752 100644 --- a/Modbus.Net/Modbus.Net/ProtocalLinkerBytesExtend.cs +++ b/Modbus.Net/Modbus.Net/ProtocalLinkerBytesExtend.cs @@ -1,24 +1,22 @@ -using System; - -namespace Modbus.Net +namespace Modbus.Net { /// - /// 协议字节伸缩 + /// 协议字节伸缩 /// public abstract class ProtocalLinkerBytesExtend { /// - /// 协议扩展,协议内容发送前调用 + /// 协议扩展,协议内容发送前调用 /// /// 扩展前的原始协议内容 /// 扩展后的协议内容 public abstract byte[] BytesExtend(byte[] content); /// - /// 协议收缩,协议内容接收后调用 + /// 协议收缩,协议内容接收后调用 /// /// 收缩前的完整协议内容 /// 收缩后的协议内容 public abstract byte[] BytesDecact(byte[] content); } -} +} \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/ProtocalUnit.cs b/Modbus.Net/Modbus.Net/ProtocalUnit.cs index 7f1255e..520b4eb 100644 --- a/Modbus.Net/Modbus.Net/ProtocalUnit.cs +++ b/Modbus.Net/Modbus.Net/ProtocalUnit.cs @@ -2,19 +2,25 @@ namespace Modbus.Net { + /// + /// 协议单元 + /// public abstract class ProtocalUnit : IProtocalFormatting { + /// + /// 是否为小端格式 + /// public bool IsLittleEndian { get; protected set; } = false; /// - /// 从输入结构格式化 + /// 从输入结构格式化 /// /// 结构化的输入数据 /// 格式化后的字节流 public abstract byte[] Format(InputStruct message); /// - /// 从对象的参数数组格式化 + /// 从对象的参数数组格式化 /// /// 非结构化的输入数据 /// 格式化后的字节流 @@ -24,7 +30,7 @@ namespace Modbus.Net } /// - /// 把仪器返回的内容填充到输出结构中 + /// 把仪器返回的内容填充到输出结构中 /// /// 返回数据的字节流 /// 转换标记位 @@ -32,7 +38,7 @@ namespace Modbus.Net public abstract OutputStruct Unformat(byte[] messageBytes, ref int pos); /// - /// 转换静态方法,把对象数组转换为字节数组。 + /// 转换静态方法,把对象数组转换为字节数组。 /// /// 是否是小端格式 /// 对象数组 @@ -45,33 +51,35 @@ namespace Modbus.Net } } + /// + /// 特殊协议单元,继承这个类的协议不会执行BytesExtend和BytesDecact + /// public abstract class SpecialProtocalUnit : ProtocalUnit { } /// - /// 输入结构 + /// 输入结构 /// public class InputStruct { } /// - /// 输出结构 + /// 输出结构 /// public class OutputStruct { } /// - /// 协议错误 + /// 协议错误 /// public class ProtocalErrorException : Exception { public ProtocalErrorException(string message) : base(message) { - } } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/README.md b/Modbus.Net/Modbus.Net/README.md index 8de139b..4df83f9 100644 --- a/Modbus.Net/Modbus.Net/README.md +++ b/Modbus.Net/Modbus.Net/README.md @@ -380,17 +380,17 @@ public class ReadDataModbusProtocal : ProtocalUnit public override byte[] Format(InputStruct message) { var r_message = (ReadDataModbusInputStruct)message; - return Format(r_message.BelongAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount); + return Format(r_message.SlaveAddress, r_message.FunctionCode, r_message.StartAddress, r_message.GetCount); } public override OutputStruct Unformat(byte[] messageBytes, ref int pos) { - byte belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); + byte slaveAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); byte functionCode = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); byte dataCount = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos); byte[] dataValue = new byte[dataCount]; Array.Copy(messageBytes, 3, dataValue, 0, dataCount); - return new ReadDataModbusOutputStruct(belongAddress, functionCode, dataCount, dataValue); + return new ReadDataModbusOutputStruct(slaveAddress, functionCode, dataCount, dataValue); } } ``` @@ -453,14 +453,14 @@ Implement low level api for Modbus. You need to implement three functions. ```C# public override void SetConnectionType(int connectionType) -protected override async Task GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount) -public override async Task SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents) +protected override async Task GetDatasAsync(byte slaveAddress, byte masterAddress, string startAddress, int getByteCount) +public override async Task SetDatasAsync(byte slaveAddress, byte masterAddress, string startAddress, object[] setContents) public override bool GetLittleEndian public override bool SetLittleEndian ``` -And don't remember set default AddressTranslator, belongAddress, masterAddress and Protocal. +And don't remember set default AddressTranslator, slaveAddress, masterAddress and Protocal. ```C# -public ModbusUtility(int connectionType, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress) +public ModbusUtility(int connectionType, byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress) { ConnectionString = null; ModbusType = (ModbusType)connectionType; @@ -552,8 +552,8 @@ Remember subpos system cannot cross a byte in current version. If you want to cr ###Version 1.2.2 * Address Utility (In Road) -* Move SlaveAddress parameter to GetData and SetData. (In Road) -* More functions in TaskManager. (In Road) +* More functions in TaskManager (In Road) +* More interfaces (In Road) ###Version 1.2.3 * OPC UA Support (In Road) diff --git a/Modbus.Net/Modbus.Net/TaskManager.cs b/Modbus.Net/Modbus.Net/TaskManager.cs index ee85011..b032873 100644 --- a/Modbus.Net/Modbus.Net/TaskManager.cs +++ b/Modbus.Net/Modbus.Net/TaskManager.cs @@ -1,4 +1,9 @@ -using System; +/* + * LimitedConcurrencyLevelTaskScheduler类来自于MSDN官方样例,Modbus.Net的作者不保留对这个类的版权。 + * LimitedConcurrencyLevelTaskScheduler class comes from offical samples of MSDN, the author of "Modbus.Net" "donnot" obtain the copyright of LimitedConcurrencyLevelTaskScheduler(only). + */ + +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -6,18 +11,27 @@ using System.Threading.Tasks; namespace Modbus.Net { + /// + /// 设备的读写方式 + /// public enum MachineDataType { Address, - CommunicationTag, + CommunicationTag } + /// + /// 返回结果的定义类 + /// public class TaskReturnDef { public string MachineId { get; set; } public Dictionary ReturnValues { get; set; } } + /// + /// 时间定义 + /// public static class TimeRestore { public static int Restore = 0; @@ -26,29 +40,31 @@ namespace Modbus.Net public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler { /// - /// Whether the current thread is processing work items. + /// Whether the current thread is processing work items. /// - [ThreadStatic] - private static bool _currentThreadIsProcessingItems; - /// - /// The list of tasks to be executed. - /// - private readonly LinkedList _tasks = new LinkedList(); // protected by lock(_tasks) - /// - /// The maximum concurrency level allowed by this scheduler. - /// - private readonly int _maxDegreeOfParallelism; - /// - /// Whether the scheduler is currently processing work items. - /// - private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks) + [ThreadStatic] private static bool _currentThreadIsProcessingItems; /// - /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the - /// specified degree of parallelism. + /// The maximum concurrency level allowed by this scheduler. + /// + private readonly int _maxDegreeOfParallelism; + + /// + /// The list of tasks to be executed. + /// + private readonly LinkedList _tasks = new LinkedList(); // protected by lock(_tasks) + + /// + /// Whether the scheduler is currently processing work items. + /// + private int _delegatesQueuedOrRunning; // protected by lock(_tasks) + + /// + /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the + /// specified degree of parallelism. /// /// - /// The maximum degree of parallelism provided by this scheduler. + /// The maximum degree of parallelism provided by this scheduler. /// public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { @@ -57,10 +73,18 @@ namespace Modbus.Net } /// - /// Queues a task to the scheduler. + /// Gets the maximum concurrency level supported by this scheduler. + /// + public sealed override int MaximumConcurrencyLevel + { + get { return _maxDegreeOfParallelism; } + } + + /// + /// Queues a task to the scheduler. /// /// - /// The task to be queued. + /// The task to be queued. /// protected sealed override void QueueTask(Task task) { @@ -78,7 +102,7 @@ namespace Modbus.Net } /// - /// Informs the ThreadPool that there's work to be executed for this scheduler. + /// Informs the ThreadPool that there's work to be executed for this scheduler. /// private void NotifyThreadPoolOfPendingWork() { @@ -105,15 +129,18 @@ namespace Modbus.Net // Get the next item from the queue item = _tasks.First.Value; - _tasks.RemoveFirst(); + _tasks.RemoveFirst(); } // Execute the task we pulled out of the queue - base.TryExecuteTask(item); + TryExecuteTask(item); } } - // We're done processing items on the current thread - finally { _currentThreadIsProcessingItems = false; } + // We're done processing items on the current thread + finally + { + _currentThreadIsProcessingItems = false; + } }, null); } @@ -130,17 +157,17 @@ namespace Modbus.Net if (taskWasPreviouslyQueued) TryDequeue(task); // Try to run the task. - return base.TryExecuteTask(task); + return TryExecuteTask(task); } /// - /// Attempts to remove a previously scheduled task from the scheduler. + /// Attempts to remove a previously scheduled task from the scheduler. /// /// - /// The task to be removed. + /// The task to be removed. /// /// - /// Whether the task could be found and removed. + /// Whether the task could be found and removed. /// protected sealed override bool TryDequeue(Task task) { @@ -148,19 +175,14 @@ namespace Modbus.Net } /// - /// Gets the maximum concurrency level supported by this scheduler. - /// - public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } } - - /// - /// Gets an enumerable of the tasks currently scheduled on this scheduler. + /// Gets an enumerable of the tasks currently scheduled on this scheduler. /// /// - /// An enumerable of the tasks currently scheduled. + /// An enumerable of the tasks currently scheduled. /// protected sealed override IEnumerable GetScheduledTasks() { - bool lockTaken = false; + var lockTaken = false; try { Monitor.TryEnter(_tasks, ref lockTaken); @@ -177,34 +199,73 @@ namespace Modbus.Net public class TaskManager { /// - /// 正在运行的设备 + /// 返回数据代理 /// - private HashSet _machines; - /// - /// 不在运行的设备 - /// - private HashSet _unlinkedMachines; + /// + public delegate void ReturnValuesDelegate(TaskReturnDef returnValue); + + /// + /// 正在运行的设备 + /// + private readonly HashSet _machines; + + /// + /// 不在运行的设备 + /// + private readonly HashSet _unlinkedMachines; - private TaskFactory _tasks; - private TaskScheduler _scheduler; private CancellationTokenSource _cts; /// - /// 正常读取的计时器 + /// 获取间隔 /// - private Timer _timer; - /// - /// 重连计时器 - /// - private Timer _timer2; + private int _getCycle; /// - /// 保持连接 + /// 保持连接 /// private bool _keepConnect; /// - /// 保持连接 + /// 任务调度 + /// + private TaskScheduler _scheduler; + + /// + /// 任务工厂 + /// + private TaskFactory _tasks; + + /// + /// 正常读取的计时器 + /// + private Timer _timer; + + /// + /// 重连计时器 + /// + private Timer _timer2; + + /// + /// 构造一个TaskManager + /// + /// 同时可以运行的任务数 + /// 读取数据的时间间隔(秒) + /// 读取数据后是否保持连接 + /// 获取与设置数据的方式 + public TaskManager(int maxRunningTask, int getCycle, bool keepConnect, + MachineDataType dataType = MachineDataType.CommunicationTag) + { + _scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask); + _machines = new HashSet(new BaseMachineEqualityComparer()); + _unlinkedMachines = new HashSet(new BaseMachineEqualityComparer()); + _getCycle = getCycle; + KeepConnect = keepConnect; + MachineDataType = dataType; + } + + /// + /// 保持连接 /// public bool KeepConnect { @@ -224,23 +285,7 @@ namespace Modbus.Net } /// - /// 返回数据代理 - /// - /// - public delegate void ReturnValuesDelegate(TaskReturnDef returnValue); - - /// - /// 返回数据事件 - /// - public event ReturnValuesDelegate ReturnValues; - - /// - /// 获取间隔 - /// - private int _getCycle; - - /// - /// 获取间隔,毫秒 + /// 获取间隔,毫秒 /// public int GetCycle { @@ -262,8 +307,8 @@ namespace Modbus.Net } } else if (value < 0) return; - else - { + else + { if (_timer != null) { _timer.Change(Timeout.Infinite, Timeout.Infinite); @@ -278,7 +323,7 @@ namespace Modbus.Net _getCycle = value; } _timer = new Timer(MaintainTasks, null, 0, _getCycle); - _timer2 = new Timer(MaintainTasks2, null, _getCycle * 2, _getCycle * 2); + _timer2 = new Timer(MaintainTasks2, null, _getCycle*2, _getCycle*2); //调试行,调试时请注释上面两行并取消下面一行的注释,每台设备只会执行一次数据获取。 //MaintainTasks(null); } @@ -291,10 +336,10 @@ namespace Modbus.Net { switch (value) { - case MachineDataType.Address: + case MachineDataType.Address: { GetDataType = MachineGetDataType.Address; - SetDataType=MachineSetDataType.Address; + SetDataType = MachineSetDataType.Address; break; } case MachineDataType.CommunicationTag: @@ -310,35 +355,26 @@ namespace Modbus.Net public MachineGetDataType GetDataType { get; set; } public MachineSetDataType SetDataType { get; set; } + /// + /// 最大可执行任务数 + /// public int MaxRunningTasks { get { return _scheduler.MaximumConcurrencyLevel; } set { TaskStop(); - _scheduler = new LimitedConcurrencyLevelTaskScheduler(value); + _scheduler = new LimitedConcurrencyLevelTaskScheduler(value); } } /// - /// 构造一个TaskManager + /// 返回数据事件 /// - /// 同时可以运行的任务数 - /// 读取数据的时间间隔(秒) - /// 读取数据后是否保持连接 - /// 获取与设置数据的方式 - public TaskManager(int maxRunningTask, int getCycle, bool keepConnect, MachineDataType dataType = MachineDataType.CommunicationTag) - { - _scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask); - _machines = new HashSet(new BaseMachineEqualityComparer()); - _unlinkedMachines = new HashSet(new BaseMachineEqualityComparer()); - _getCycle = getCycle; - KeepConnect = keepConnect; - MachineDataType = dataType; - } + public event ReturnValuesDelegate ReturnValues; /// - /// 添加一台设备 + /// 添加一台设备 /// /// 设备 public void AddMachine(BaseMachine machine) @@ -351,7 +387,7 @@ namespace Modbus.Net } /// - /// 添加多台设备 + /// 添加多台设备 /// /// 设备的列表 public void AddMachines(IEnumerable machines) @@ -366,7 +402,7 @@ namespace Modbus.Net } /// - /// 根据设备的连接地址移除设备 + /// 根据设备的连接地址移除设备 /// /// 设备的连接地址 public void RemoveMachineWithToken(string machineToken) @@ -382,7 +418,7 @@ namespace Modbus.Net } /// - /// 根据设备的id移除设备 + /// 根据设备的id移除设备 /// /// 设备的id public void RemoveMachineWithId(string id) @@ -398,21 +434,21 @@ namespace Modbus.Net } /// - /// 将设备指定为未连接 + /// 将设备指定为未连接 /// /// 设备的id public void MoveMachineToUnlinked(string id) { IEnumerable machines; - lock(_machines) + lock (_machines) { machines = _machines.Where(c => c.Id == id).ToList(); if (!machines.Any()) return; _machines.RemoveWhere(p => p.Id == id); } - lock(_unlinkedMachines) + lock (_unlinkedMachines) { - foreach(var machine in machines) + foreach (var machine in machines) { _unlinkedMachines.Add(machine); } @@ -420,7 +456,7 @@ namespace Modbus.Net } /// - /// 将设备指定为已连接 + /// 将设备指定为已连接 /// /// 设备的id public void MoveMachineToLinked(string id) @@ -442,7 +478,7 @@ namespace Modbus.Net } /// - /// 移除设备 + /// 移除设备 /// /// 设备的实例 public void RemoveMachine(BaseMachine machine) @@ -458,7 +494,7 @@ namespace Modbus.Net } /// - /// 已连接设备更新 + /// 已连接设备更新 /// /// private void MaintainTasks(object sender) @@ -467,7 +503,7 @@ namespace Modbus.Net } /// - /// 未连接设备更新 + /// 未连接设备更新 /// /// private void MaintainTasks2(object sender) @@ -476,7 +512,7 @@ namespace Modbus.Net } /// - /// 已连接设备更新 + /// 已连接设备更新 /// /// private async Task MaintainTasksAsync() @@ -484,7 +520,7 @@ namespace Modbus.Net try { var tasks = new List(); - HashSet saveMachines = new HashSet(); + var saveMachines = new HashSet(); IEnumerable saveMachinesEnum; lock (_machines) { @@ -493,21 +529,21 @@ namespace Modbus.Net } foreach (var machine in saveMachinesEnum) { - CancellationTokenSource cts = new CancellationTokenSource(); - cts.CancelAfter(TimeSpan.FromSeconds(_getCycle * 10)); + var cts = new CancellationTokenSource(); + cts.CancelAfter(TimeSpan.FromSeconds(_getCycle*10)); var task = _tasks.StartNew(() => RunTask(machine).WithCancellation(cts.Token)); tasks.Add(task); } await Task.WhenAll(tasks); } - catch + catch(Exception) { - return; + //ignore } } /// - /// 未连接设备更新 + /// 未连接设备更新 /// /// private async Task MaintainTasks2Async() @@ -515,28 +551,28 @@ namespace Modbus.Net try { var tasks = new List(); - HashSet saveMachines = new HashSet(); + var saveMachines = new HashSet(); lock (_unlinkedMachines) { saveMachines.UnionWith(_unlinkedMachines); } foreach (var machine in saveMachines) { - CancellationTokenSource cts = new CancellationTokenSource(); - cts.CancelAfter(TimeSpan.FromSeconds(_getCycle * 10)); + var cts = new CancellationTokenSource(); + cts.CancelAfter(TimeSpan.FromSeconds(_getCycle*10)); var task = _tasks.StartNew(() => RunTask(machine).WithCancellation(cts.Token)); tasks.Add(task); } await Task.WhenAll(tasks); } - catch + catch(Exception) { - return; + //ignore } } /// - /// 设置数据 + /// 设置数据 /// /// 设备的连接标识 /// 需要设置的数据 @@ -554,7 +590,7 @@ namespace Modbus.Net } /// - /// 启动TaskManager + /// 启动TaskManager /// public void TaskStart() { @@ -565,17 +601,14 @@ namespace Modbus.Net } /// - /// 停止TaskManager + /// 停止TaskManager /// public void TaskStop() { lock (_machines) { GetCycle = Timeout.Infinite; - if (_cts != null) - { - _cts.Cancel(); - } + _cts?.Cancel(); if (_machines != null) { foreach (var machine in _machines) @@ -588,7 +621,7 @@ namespace Modbus.Net } /// - /// 执行对具体设备的数据更新 + /// 执行对具体设备的数据更新 /// /// 设备的实例 /// @@ -599,7 +632,7 @@ namespace Modbus.Net //调试代码,调试时取消下面一下代码的注释,会同步调用获取数据。 //var ans = machine.GetDatas(); //设置Cancellation Token - CancellationTokenSource cts = new CancellationTokenSource(); + var cts = new CancellationTokenSource(); //超时后取消任务 cts.CancelAfter(TimeSpan.FromSeconds(_getCycle)); //读取数据 @@ -612,7 +645,7 @@ namespace Modbus.Net { MoveMachineToLinked(machine.Id); } - ReturnValues?.Invoke(new TaskReturnDef() + ReturnValues?.Invoke(new TaskReturnDef { MachineId = machine.Id, ReturnValues = ans @@ -624,7 +657,7 @@ namespace Modbus.Net { MoveMachineToUnlinked(machine.Id); } - ReturnValues?.Invoke(new TaskReturnDef() + ReturnValues?.Invoke(new TaskReturnDef { MachineId = machine.Id, ReturnValues = null diff --git a/Modbus.Net/Modbus.Net/TcpConnector.cs b/Modbus.Net/Modbus.Net/TcpConnector.cs index e850616..4dcb3e7 100644 --- a/Modbus.Net/Modbus.Net/TcpConnector.cs +++ b/Modbus.Net/Modbus.Net/TcpConnector.cs @@ -1,5 +1,4 @@ using System; -using System.Net; using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; @@ -25,21 +24,30 @@ namespace Modbus.Net /// public class TcpConnector : BaseConnector, IDisposable { - public override string ConnectionToken => _host; - private readonly string _host; - - private int _sendCount; - private int _receiveCount; - private int _errorCount; + private readonly int _port; // 2MB 的接收缓冲区,目的是一次接收完服务器发回的消息 private readonly byte[] _receiveBuffer = new byte[1024]; - private readonly int _port; + private int _errorCount; + private int _receiveCount; + + private int _sendCount; private TcpClient _socketClient; private int _timeoutTime; + private bool m_disposed; + + public TcpConnector(string ipaddress, int port, int timeoutTime) + { + _host = ipaddress; + _port = port; + TimeoutTime = timeoutTime; + } + + public override string ConnectionToken => _host; + public int TimeoutTime { get { return _timeoutTime; } @@ -53,18 +61,11 @@ namespace Modbus.Net } } - public TcpConnector(string ipaddress, int port, int timeoutTime) - { - _host = ipaddress; - _port = port; - TimeoutTime = timeoutTime; - } - public override bool IsConnected => _socketClient?.Client != null && _socketClient.Connected; /// -     /// 实现IDisposable接口 -     /// + /// 实现IDisposable接口 + /// public void Dispose() { Dispose(true); @@ -74,10 +75,8 @@ namespace Modbus.Net GC.SuppressFinalize(this); } - private bool m_disposed = false; - /// - /// 虚方法,可供子类重写 + /// 虚方法,可供子类重写 /// /// protected virtual void Dispose(bool disposing) @@ -99,8 +98,8 @@ namespace Modbus.Net } /// - /// 析构函数 - /// 当客户端没有显示调用Dispose()时由GC完成资源回收功能 + /// 析构函数 + /// 当客户端没有显示调用Dispose()时由GC完成资源回收功能 /// ~TcpConnector() { @@ -118,37 +117,37 @@ namespace Modbus.Net { Disconnect(); } + try + { + _socketClient = new TcpClient + { + SendTimeout = TimeoutTime, + ReceiveTimeout = TimeoutTime + }; + try { - _socketClient = new TcpClient - { - SendTimeout = TimeoutTime, - ReceiveTimeout = TimeoutTime - }; - - try - { - CancellationTokenSource cts = new CancellationTokenSource(); - cts.CancelAfter(TimeoutTime); - await _socketClient.ConnectAsync(_host, _port).WithCancellation(cts.Token); - } - catch (Exception e) - { - AddInfo("client connected exception: " + e.Message); - } - if (_socketClient.Connected) - { - AddInfo("client connected."); - return true; - } - AddInfo("connect failed."); - return false; + var cts = new CancellationTokenSource(); + cts.CancelAfter(TimeoutTime); + await _socketClient.ConnectAsync(_host, _port).WithCancellation(cts.Token); } - catch (Exception err) + catch (Exception e) { - AddInfo("client connect exception: " + err.Message); - return false; + AddInfo("client connected exception: " + e.Message); } + if (_socketClient.Connected) + { + AddInfo("client connected."); + return true; + } + AddInfo("connect failed."); + return false; + } + catch (Exception err) + { + AddInfo("client connect exception: " + err.Message); + return false; + } } public override bool Disconnect() @@ -192,7 +191,7 @@ namespace Modbus.Net /// 是否发送成功 public override async Task SendMsgWithoutReturnAsync(byte[] message) { - byte[] datagram = message; + var datagram = message; try { @@ -228,7 +227,7 @@ namespace Modbus.Net /// 是否发送成功 public override async Task SendMsgAsync(byte[] message) { - byte[] datagram = message; + var datagram = message; try { @@ -257,7 +256,7 @@ namespace Modbus.Net { try { - int len = await stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length); + var len = await stream.ReadAsync(_receiveBuffer, 0, _receiveBuffer.Length); stream.Flush(); // 异步接收回答 if (len > 0) diff --git a/Modbus.Net/Modbus.Net/TcpProtocalLinker.cs b/Modbus.Net/Modbus.Net/TcpProtocalLinker.cs index a49ccf3..a117c00 100644 --- a/Modbus.Net/Modbus.Net/TcpProtocalLinker.cs +++ b/Modbus.Net/Modbus.Net/TcpProtocalLinker.cs @@ -1,21 +1,18 @@ -using System; - -namespace Modbus.Net +namespace Modbus.Net { /// - /// Tcp连接对象 + /// Tcp连接对象 /// public abstract class TcpProtocalLinker : ProtocalLinker { - protected TcpProtocalLinker() : this(ConfigurationManager.IP, int.Parse(ConfigurationManager.ModbusPort)) { - } protected TcpProtocalLinker(string ip, int port) { - _baseConnector = new TcpConnector(ip, port, int.Parse(ConfigurationManager.IPConnectionTimeout)); + //初始化连接对象 + BaseConnector = new TcpConnector(ip, port, int.Parse(ConfigurationManager.IPConnectionTimeout)); } - } + } } \ No newline at end of file diff --git a/Modbus.Net/Modbus.Net/ValueHelper.cs b/Modbus.Net/Modbus.Net/ValueHelper.cs index 377ff6d..1bc643a 100644 --- a/Modbus.Net/Modbus.Net/ValueHelper.cs +++ b/Modbus.Net/Modbus.Net/ValueHelper.cs @@ -1,19 +1,17 @@ using System; using System.Collections; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; using System.Text; namespace Modbus.Net { /// - /// 值与字节数组之间转换的辅助类,这是一个Singleton类 - /// 作者:罗圣(Chris L.) + /// 值与字节数组之间转换的辅助类,这是一个Singleton类 /// public class ValueHelper { - public Dictionary ByteLength = new Dictionary() + public Dictionary ByteLength = new Dictionary { {"System.Boolean", 0.125}, {"System.Byte", 1}, @@ -32,166 +30,153 @@ namespace Modbus.Net } /// - /// 协议中的内容构造是否小端的,默认是小端构造协议。 + /// 协议中的内容构造是否小端的,默认是小端构造协议。 /// public static bool LittleEndian => true; - #region Factory - - private static ValueHelper _instance; - - protected virtual ValueHelper _Instance => _instance; - /// - /// ValueHelper单例的实例 - /// - public static ValueHelper Instance => _instance ?? (_instance = new ValueHelper()); - - #endregion - - /// - /// 将一个byte数字转换为一个byte元素的数组。 + /// 将一个byte数字转换为一个byte元素的数组。 /// /// byte数字 /// byte数组 - public Byte[] GetBytes(byte value) + public byte[] GetBytes(byte value) { return new[] {value}; } /// - /// 将short数字转换为byte数组 + /// 将short数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(short value) + public virtual byte[] GetBytes(short value) { return BitConverter.GetBytes(value); } /// - /// 将int数字转换为byte数组 + /// 将int数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(int value) + public virtual byte[] GetBytes(int value) { return BitConverter.GetBytes(value); } /// - /// 将long数字转换为byte数组 + /// 将long数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(long value) + public virtual byte[] GetBytes(long value) { return BitConverter.GetBytes(value); } /// - /// 将ushort数字转换为byte数组 + /// 将ushort数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(ushort value) + public virtual byte[] GetBytes(ushort value) { return BitConverter.GetBytes(value); } /// - /// 将uint数字转换为byte数组 + /// 将uint数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(uint value) + public virtual byte[] GetBytes(uint value) { return BitConverter.GetBytes(value); } /// - /// 将ulong数字转换为byte数组 + /// 将ulong数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(ulong value) + public virtual byte[] GetBytes(ulong value) { return BitConverter.GetBytes(value); } /// - /// 将float数字转换为byte数组 + /// 将float数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(float value) + public virtual byte[] GetBytes(float value) { return BitConverter.GetBytes(value); } /// - /// 将double数字转换为byte数组 + /// 将double数字转换为byte数组 /// /// /// - public virtual Byte[] GetBytes(double value) + public virtual byte[] GetBytes(double value) { return BitConverter.GetBytes(value); } /// - /// 将object数字转换为byte数组 + /// 将object数字转换为byte数组 /// /// /// /// - public virtual Byte[] GetBytes(object value, Type type) + public virtual byte[] GetBytes(object value, Type type) { switch (type.FullName) { case "System.Int16": { - byte[] bytes = _Instance.GetBytes((short) value); + var bytes = _Instance.GetBytes((short) value); return bytes; } case "System.Int32": { - byte[] bytes = _Instance.GetBytes((int) value); + var bytes = _Instance.GetBytes((int) value); return bytes; } case "System.Int64": { - byte[] bytes = _Instance.GetBytes((long) value); + var bytes = _Instance.GetBytes((long) value); return bytes; } case "System.UInt16": { - byte[] bytes = _Instance.GetBytes((ushort) value); + var bytes = _Instance.GetBytes((ushort) value); return bytes; } case "System.UInt32": { - byte[] bytes = _Instance.GetBytes((uint) value); + var bytes = _Instance.GetBytes((uint) value); return bytes; } case "System.UInt64": { - byte[] bytes = _Instance.GetBytes((ulong) value); + var bytes = _Instance.GetBytes((ulong) value); return bytes; } case "System.Single": { - byte[] bytes = _Instance.GetBytes((float) value); + var bytes = _Instance.GetBytes((float) value); return bytes; } case "System.Double": { - byte[] bytes = _Instance.GetBytes((double) value); + var bytes = _Instance.GetBytes((double) value); return bytes; } case "System.Byte": { - byte[] bytes = _Instance.GetBytes((byte) value); + var bytes = _Instance.GetBytes((byte) value); return bytes; } default: @@ -202,7 +187,7 @@ namespace Modbus.Net } /// - /// 将byte数组中相应的位置转换为对应类型的数字 + /// 将byte数组中相应的位置转换为对应类型的数字 /// /// /// @@ -214,181 +199,181 @@ namespace Modbus.Net switch (t.FullName) { case "System.Int16": - { - short value = _Instance.GetShort(data, ref pos); - return value; - } + { + var value = _Instance.GetShort(data, ref pos); + return value; + } case "System.Int32": - { - int value = _Instance.GetInt(data, ref pos); - return value; - } + { + var value = _Instance.GetInt(data, ref pos); + return value; + } case "System.Int64": - { - long value = _Instance.GetLong(data, ref pos); - return value; - } + { + var value = _Instance.GetLong(data, ref pos); + return value; + } case "System.UInt16": - { - ushort value = _Instance.GetUShort(data, ref pos); - return value; - } + { + var value = _Instance.GetUShort(data, ref pos); + return value; + } case "System.UInt32": - { - uint value = _Instance.GetUInt(data, ref pos); - return value; - } + { + var value = _Instance.GetUInt(data, ref pos); + return value; + } case "System.UInt64": - { - ulong value = _Instance.GetULong(data, ref pos); - return value; - } + { + var value = _Instance.GetULong(data, ref pos); + return value; + } case "System.Single": - { - float value = _Instance.GetFloat(data, ref pos); - return value; - } + { + var value = _Instance.GetFloat(data, ref pos); + return value; + } case "System.Double": - { - double value = _Instance.GetDouble(data, ref pos); - return value; - } + { + var value = _Instance.GetDouble(data, ref pos); + return value; + } case "System.Byte": - { - byte value = _Instance.GetByte(data, ref pos); - return value; - } + { + var value = _Instance.GetByte(data, ref pos); + return value; + } case "System.Boolean": - { - bool value = _Instance.GetBit(data, ref pos, ref subPos); - return value; - } + { + var value = _Instance.GetBit(data, ref pos, ref subPos); + return value; + } default: - { - throw new NotImplementedException("没有实现除整数以外的其它转换方式"); - } + { + throw new NotImplementedException("没有实现除整数以外的其它转换方式"); + } } } /// - /// 将byte数组中相应的位置转换为byte数字 + /// 将byte数组中相应的位置转换为byte数字 /// /// /// /// public virtual byte GetByte(byte[] data, ref int pos) { - byte t = data[pos]; + var t = data[pos]; pos += 1; return t; } /// - /// 将byte数组中相应的位置转换为short数字 + /// 将byte数组中相应的位置转换为short数字 /// /// /// /// public virtual short GetShort(byte[] data, ref int pos) { - short t = BitConverter.ToInt16(data, pos); + var t = BitConverter.ToInt16(data, pos); pos += 2; return t; } /// - /// 将byte数组中相应的位置转换为int数字 + /// 将byte数组中相应的位置转换为int数字 /// /// /// /// public virtual int GetInt(byte[] data, ref int pos) { - int t = BitConverter.ToInt32(data, pos); + var t = BitConverter.ToInt32(data, pos); pos += 4; return t; } /// - /// 将byte数组中相应的位置转换为long数字 + /// 将byte数组中相应的位置转换为long数字 /// /// /// /// public virtual long GetLong(byte[] data, ref int pos) { - long t = BitConverter.ToInt64(data, pos); + var t = BitConverter.ToInt64(data, pos); pos += 8; return t; } /// - /// 将byte数组中相应的位置转换为ushort数字 + /// 将byte数组中相应的位置转换为ushort数字 /// /// /// /// public virtual ushort GetUShort(byte[] data, ref int pos) { - ushort t = BitConverter.ToUInt16(data, pos); + var t = BitConverter.ToUInt16(data, pos); pos += 2; return t; } /// - /// 将byte数组中相应的位置转换为uint数字 + /// 将byte数组中相应的位置转换为uint数字 /// /// /// /// public virtual uint GetUInt(byte[] data, ref int pos) { - uint t = BitConverter.ToUInt32(data, pos); + var t = BitConverter.ToUInt32(data, pos); pos += 4; return t; } /// - /// 将byte数组中相应的位置转换为ulong数字 + /// 将byte数组中相应的位置转换为ulong数字 /// /// /// /// public virtual ulong GetULong(byte[] data, ref int pos) { - ulong t = BitConverter.ToUInt64(data, pos); + var t = BitConverter.ToUInt64(data, pos); pos += 8; return t; } /// - /// 将byte数组中相应的位置转换为float数字 + /// 将byte数组中相应的位置转换为float数字 /// /// /// /// public virtual float GetFloat(byte[] data, ref int pos) { - float t = BitConverter.ToSingle(data, pos); + var t = BitConverter.ToSingle(data, pos); pos += 4; return t; } /// - /// 将byte数组中相应的位置转换为double数字 + /// 将byte数组中相应的位置转换为double数字 /// /// /// /// public virtual double GetDouble(byte[] data, ref int pos) { - double t = BitConverter.ToDouble(data, pos); + var t = BitConverter.ToDouble(data, pos); pos += 8; return t; } /// - /// 将byte数组中相应的位置转换为字符串 + /// 将byte数组中相应的位置转换为字符串 /// /// /// @@ -397,24 +382,24 @@ namespace Modbus.Net /// public virtual string GetString(byte[] data, int count, ref int pos, Encoding encoding) { - string t = encoding.GetString(data, pos, count); + var t = encoding.GetString(data, pos, count); pos += count; return t; } /// - /// 将byte数组中相应的位置转换为8个bit数字 + /// 将byte数组中相应的位置转换为8个bit数字 /// /// /// /// public virtual bool[] GetBits(byte[] data, ref int pos) { - bool[] t = new bool[8]; - byte temp = data[pos]; - for (int i = 0; i < 8; i++) + var t = new bool[8]; + var temp = data[pos]; + for (var i = 0; i < 8; i++) { - t[i] = temp % 2 > 0; + t[i] = temp%2 > 0; temp /= 2; } pos += 1; @@ -422,20 +407,20 @@ namespace Modbus.Net } /// - /// 获取一个byte中相对应的bit数组展开中第n个位置中的bit元素。 + /// 获取一个byte中相对应的bit数组展开中第n个位置中的bit元素。 /// /// byte数字 /// bit数组中的对应位置 /// 小数位 /// 对应位置的bit元素 public bool GetBit(byte number, ref int pos, ref int subPos) - { + { if (subPos < 0 && subPos >= 8) throw new IndexOutOfRangeException(); - int ans = number % 2; - int i = 0; + var ans = number%2; + var i = 0; while (i <= subPos) { - ans = number % 2; + ans = number%2; number /= 2; i++; } @@ -448,41 +433,53 @@ namespace Modbus.Net return ans > 0; } + /// + /// 获取一个字节数组中某个Bit位的数据 + /// + /// + /// + /// + /// public virtual bool GetBit(byte[] number, ref int pos, ref int subPos) { return GetBit(number[pos], ref pos, ref subPos); } + /// + /// 反转一个字节的8个Bit位 + /// + /// + /// public virtual byte ReverseByte(byte originalByte) { byte result = 0; - for (int i = 0; i < 8; i++) + for (var i = 0; i < 8; i++) { result <<= 1; - result |= (byte)(originalByte & 1); + result |= (byte) (originalByte & 1); originalByte >>= 1; } return result; } /// - /// 将待转换的对象数组转换为需要发送的byte数组 + /// 将待转换的对象数组转换为需要发送的byte数组 /// /// /// public virtual byte[] ObjectArrayToByteArray(object[] contents) { - bool b = false; + var b = false; //先查找传入的结构中有没有数组,有的话将其打开 var newContentsList = new List(); - foreach (object content in contents) + foreach (var content in contents) { - string t = content.GetType().ToString(); + var t = content.GetType().ToString(); if (t.Substring(t.Length - 2, 2) == "[]") { b = true; //自动将目标数组中内含的子数组展开,是所有包含在子数组拼接为一个数组 - IEnumerable contentArray = + var contentArray = ArrayList.Adapter((Array) content).ToArray(typeof (object)).OfType(); newContentsList.AddRange(contentArray); } @@ -496,12 +493,12 @@ namespace Modbus.Net //把参数一个一个翻译为相对应的字节,然后拼成一个队列 var translateTarget = new List(); //将bool类型拼装为byte类型时,按照8个一组,不满8个时补false为原则进行 - bool lastIsBool = false; + var lastIsBool = false; byte boolToByteTemp = 0; - int boolToByteCount = 0; - foreach (object content in contents) + var boolToByteCount = 0; + foreach (var content in contents) { - string t = content.GetType().ToString(); + var t = content.GetType().ToString(); if (t == "System.Boolean") { if (boolToByteCount >= 8) @@ -513,11 +510,11 @@ namespace Modbus.Net lastIsBool = true; if (LittleEndian) { - boolToByteTemp = (byte)(boolToByteTemp * 2 + ((bool)content ? 1 : 0)); + boolToByteTemp = (byte) (boolToByteTemp*2 + ((bool) content ? 1 : 0)); } else - { - boolToByteTemp += (byte)((bool)content ? Math.Pow(2, boolToByteCount) : 0); + { + boolToByteTemp += (byte) ((bool) content ? Math.Pow(2, boolToByteCount) : 0); } boolToByteCount++; } @@ -533,56 +530,56 @@ namespace Modbus.Net switch (t) { case "System.Int16": - { - translateTarget.AddRange(_Instance.GetBytes((short)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((short) content)); + break; + } case "System.Int32": - { - translateTarget.AddRange(_Instance.GetBytes((int)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((int) content)); + break; + } case "System.Int64": - { - translateTarget.AddRange(_Instance.GetBytes((long)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((long) content)); + break; + } case "System.UInt16": - { - translateTarget.AddRange(_Instance.GetBytes((ushort)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((ushort) content)); + break; + } case "System.UInt32": - { - translateTarget.AddRange(_Instance.GetBytes((uint)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((uint) content)); + break; + } case "System.UInt64": - { - translateTarget.AddRange(_Instance.GetBytes((ulong)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((ulong) content)); + break; + } case "System.Single": - { - translateTarget.AddRange(_Instance.GetBytes((float)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((float) content)); + break; + } case "System.Double": - { - translateTarget.AddRange(_Instance.GetBytes((double)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((double) content)); + break; + } case "System.Byte": - { - translateTarget.AddRange(_Instance.GetBytes((byte)content)); - break; - } + { + translateTarget.AddRange(_Instance.GetBytes((byte) content)); + break; + } default: - { - throw new NotImplementedException("没有实现除整数以外的其它转换方式"); - } + { + throw new NotImplementedException("没有实现除整数以外的其它转换方式"); + } } - } + } } //最后是bool拼装时,表示数字还没有添加,把数字添加进返回数组中。 if (lastIsBool) @@ -594,16 +591,23 @@ namespace Modbus.Net } /// - /// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 + /// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 /// /// byte数组 /// 单一的类型和需要转换的个数的键值对 /// object数组 public virtual object[] ByteArrayToObjectArray(byte[] contents, KeyValuePair translateTypeAndCount) { - return ByteArrayToObjectArray(contents, new List>() {translateTypeAndCount}); + return ByteArrayToObjectArray(contents, new List> {translateTypeAndCount}); } + /// + /// 将一个byte数组转换成用户指定类型的数组,使用模板参数确定需要转换的类型 + /// + /// + /// + /// + /// public virtual T[] ByteArrayToDestinationArray(byte[] contents, int getCount) { var objectArray = _Instance.ByteArrayToObjectArray(contents, @@ -612,19 +616,22 @@ namespace Modbus.Net } /// - /// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 + /// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 /// /// byte数组 - /// 一连串类型和需要转换的个数的键值对,该方法会依次转换每一个需要转的目标数据类型。比如:typeof(int),5; typeof(short),3 会转换出8个元素(当然前提是byte数组足够长的时候),5个int和3个short,然后全部变为object类型返回。 + /// + /// 一连串类型和需要转换的个数的键值对,该方法会依次转换每一个需要转的目标数据类型。比如:typeof(int),5; typeof(short),3 + /// 会转换出8个元素(当然前提是byte数组足够长的时候),5个int和3个short,然后全部变为object类型返回。 + /// /// object数组 public virtual object[] ByteArrayToObjectArray(byte[] contents, IEnumerable> translateTypeAndCount) { - List translation = new List(); - int count = 0; + var translation = new List(); + var count = 0; foreach (var translateUnit in translateTypeAndCount) { - for (int i = 0; i < translateUnit.Value; i++) + for (var i = 0; i < translateUnit.Value; i++) { if (count >= contents.Length) break; try @@ -633,64 +640,63 @@ namespace Modbus.Net { case "System.Int16": { - short value = _Instance.GetShort(contents, ref count); + var value = _Instance.GetShort(contents, ref count); translation.Add(value); break; } case "System.Int32": { - int value = _Instance.GetInt(contents, ref count); + var value = _Instance.GetInt(contents, ref count); translation.Add(value); break; } case "System.Int64": { - long value = _Instance.GetLong(contents, ref count); + var value = _Instance.GetLong(contents, ref count); translation.Add(value); break; } case "System.UInt16": { - ushort value = _Instance.GetUShort(contents, ref count); + var value = _Instance.GetUShort(contents, ref count); translation.Add(value); break; } case "System.UInt32": { - uint value = _Instance.GetUInt(contents, ref count); + var value = _Instance.GetUInt(contents, ref count); translation.Add(value); break; } case "System.UInt64": { - ulong value = _Instance.GetULong(contents, ref count); + var value = _Instance.GetULong(contents, ref count); translation.Add(value); break; } case "System.Single": { - float value = _Instance.GetFloat(contents, ref count); + var value = _Instance.GetFloat(contents, ref count); translation.Add(value); break; } case "System.Double": { - double value = _Instance.GetDouble(contents, ref count); + var value = _Instance.GetDouble(contents, ref count); translation.Add(value); break; } case "System.Byte": { - byte value = _Instance.GetByte(contents, ref count); + var value = _Instance.GetByte(contents, ref count); translation.Add(value); break; } case "System.Boolean": { - - bool[] value = _Instance.GetBits(contents, ref count); - int k = translateUnit.Value - i < 8 ? translateUnit.Value - i : 8; - for (int j = 0; j < k; j++) + var value = _Instance.GetBits(contents, ref count); + var k = translateUnit.Value - i < 8 ? translateUnit.Value - i : 8; + for (var j = 0; j < k; j++) { translation.Add(value[j]); } @@ -713,15 +719,15 @@ namespace Modbus.Net } /// - /// 将object数组转换为目标类型的单一数组 + /// 将object数组转换为目标类型的单一数组 /// /// 需要转换的目标类型 /// object数组 /// 目标数组 public T[] ObjectArrayToDestinationArray(object[] contents) { - T[] array = new T[contents.Length]; - Array.Copy(contents,array,contents.Length); + var array = new T[contents.Length]; + Array.Copy(contents, array, contents.Length); return array; } @@ -733,52 +739,52 @@ namespace Modbus.Net { case "System.Int16": { - bool success = _Instance.SetValue(contents, setPos, (short)setValue); + var success = _Instance.SetValue(contents, setPos, (short) setValue); return success; } case "System.Int32": { - bool success = _Instance.SetValue(contents, setPos, (int) setValue); + var success = _Instance.SetValue(contents, setPos, (int) setValue); return success; } case "System.Int64": { - bool success = _Instance.SetValue(contents, setPos, (long) setValue); + var success = _Instance.SetValue(contents, setPos, (long) setValue); return success; } case "System.UInt16": { - bool success = _Instance.SetValue(contents, setPos, (ushort) setValue); + var success = _Instance.SetValue(contents, setPos, (ushort) setValue); return success; } case "System.UInt32": { - bool success = _Instance.SetValue(contents, setPos, (uint) setValue); + var success = _Instance.SetValue(contents, setPos, (uint) setValue); return success; } case "System.UInt64": { - bool success = _Instance.SetValue(contents, setPos, (ulong) setValue); + var success = _Instance.SetValue(contents, setPos, (ulong) setValue); return success; } case "System.Single": { - bool success = _Instance.SetValue(contents, setPos, (float) setValue); + var success = _Instance.SetValue(contents, setPos, (float) setValue); return success; } case "System.Double": { - bool success = _Instance.SetValue(contents, setPos, (double) setValue); + var success = _Instance.SetValue(contents, setPos, (double) setValue); return success; } case "System.Byte": { - bool success = _Instance.SetValue(contents, setPos, (byte) setValue); + var success = _Instance.SetValue(contents, setPos, (byte) setValue); return success; } case "System.Boolean": { - bool success = _Instance.SetBit(contents, setPos, subPos, (bool) setValue); + var success = _Instance.SetBit(contents, setPos, subPos, (bool) setValue); return success; } default: @@ -789,7 +795,7 @@ namespace Modbus.Net } /// - /// 将short值设置到byte数组中 + /// 将short值设置到byte数组中 /// /// 待设置的byte数组 /// 设置的位置 @@ -799,7 +805,7 @@ namespace Modbus.Net { try { - byte[] datas = _Instance.GetBytes(setValue, setValue.GetType()); + var datas = _Instance.GetBytes(setValue, setValue.GetType()); Array.Copy(datas, 0, contents, pos, datas.Length); return true; } @@ -810,7 +816,7 @@ namespace Modbus.Net } /// - /// 设置对应数字中相应位置的bit的值 + /// 设置对应数字中相应位置的bit的值 /// /// byte数子 /// 设置位置 @@ -818,29 +824,26 @@ namespace Modbus.Net /// public byte SetBit(byte number, int subPos, bool setBit) { - int creation = 0; + var creation = 0; if (setBit) { - for (int i = 7; i >= 0; i--) + for (var i = 7; i >= 0; i--) { creation *= 2; if (i == subPos) creation++; } - return (byte)(number | creation); + return (byte) (number | creation); } - else + for (var i = 7; i >= 0; i--) { - for (int i = 7; i >= 0; i--) - { - creation *= 2; - if (i != subPos) creation++; - } - return (byte)(number & creation); + creation *= 2; + if (i != subPos) creation++; } + return (byte) (number & creation); } /// - /// 设置一组数据中的一个bit + /// 设置一组数据中的一个bit /// /// 待设置的字节数组 /// 位置 @@ -857,61 +860,74 @@ namespace Modbus.Net catch (Exception) { return false; - } + } } + + #region Factory + + private static ValueHelper _instance; + + protected virtual ValueHelper _Instance => _instance; + + /// + /// ValueHelper单例的实例 + /// + public static ValueHelper Instance => _instance ?? (_instance = new ValueHelper()); + + #endregion } public class BigEndianValueHelper : ValueHelper { private static BigEndianValueHelper _bigEndianInstance; - protected override ValueHelper _Instance => _bigEndianInstance; - protected BigEndianValueHelper() { - } + protected override ValueHelper _Instance => _bigEndianInstance; + protected new bool LittleEndian => false; - public new static BigEndianValueHelper Instance => _bigEndianInstance ?? (_bigEndianInstance = new BigEndianValueHelper()); + public new static BigEndianValueHelper Instance + => _bigEndianInstance ?? (_bigEndianInstance = new BigEndianValueHelper()); - public override Byte[] GetBytes(short value) + public override byte[] GetBytes(short value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(int value) + public override byte[] GetBytes(int value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(long value) + public override byte[] GetBytes(long value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(ushort value) + public override byte[] GetBytes(ushort value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(uint value) + public override byte[] GetBytes(uint value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(ulong value) + public override byte[] GetBytes(ulong value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(float value) + public override byte[] GetBytes(float value) { return Reverse(BitConverter.GetBytes(value)); } - public override Byte[] GetBytes(double value) + public override byte[] GetBytes(double value) { return Reverse(BitConverter.GetBytes(value)); } @@ -919,7 +935,7 @@ namespace Modbus.Net public override short GetShort(byte[] data, ref int pos) { Array.Reverse(data, pos, 2); - short t = BitConverter.ToInt16(data, pos); + var t = BitConverter.ToInt16(data, pos); Array.Reverse(data, pos, 2); pos += 2; return t; @@ -928,7 +944,7 @@ namespace Modbus.Net public override int GetInt(byte[] data, ref int pos) { Array.Reverse(data, pos, 4); - int t = BitConverter.ToInt32(data, pos); + var t = BitConverter.ToInt32(data, pos); Array.Reverse(data, pos, 4); pos += 4; return t; @@ -937,7 +953,7 @@ namespace Modbus.Net public override long GetLong(byte[] data, ref int pos) { Array.Reverse(data, pos, 8); - long t = BitConverter.ToInt64(data, pos); + var t = BitConverter.ToInt64(data, pos); Array.Reverse(data, pos, 8); pos += 8; return t; @@ -946,7 +962,7 @@ namespace Modbus.Net public override ushort GetUShort(byte[] data, ref int pos) { Array.Reverse(data, pos, 2); - ushort t = BitConverter.ToUInt16(data, pos); + var t = BitConverter.ToUInt16(data, pos); Array.Reverse(data, pos, 2); pos += 2; return t; @@ -955,7 +971,7 @@ namespace Modbus.Net public override uint GetUInt(byte[] data, ref int pos) { Array.Reverse(data, pos, 4); - uint t = BitConverter.ToUInt32(data, pos); + var t = BitConverter.ToUInt32(data, pos); Array.Reverse(data, pos, 4); pos += 4; return t; @@ -964,7 +980,7 @@ namespace Modbus.Net public override ulong GetULong(byte[] data, ref int pos) { Array.Reverse(data, pos, 8); - ulong t = BitConverter.ToUInt64(data, pos); + var t = BitConverter.ToUInt64(data, pos); Array.Reverse(data, pos, 8); pos += 8; return t; @@ -973,7 +989,7 @@ namespace Modbus.Net public override float GetFloat(byte[] data, ref int pos) { Array.Reverse(data, pos, 4); - float t = BitConverter.ToSingle(data, pos); + var t = BitConverter.ToSingle(data, pos); Array.Reverse(data, pos, 4); pos += 4; return t; @@ -982,7 +998,7 @@ namespace Modbus.Net public override double GetDouble(byte[] data, ref int pos) { Array.Reverse(data, pos, 8); - double t = BitConverter.ToDouble(data, pos); + var t = BitConverter.ToDouble(data, pos); Array.Reverse(data, pos, 8); pos += 8; return t; @@ -1005,11 +1021,11 @@ namespace Modbus.Net public override bool[] GetBits(byte[] data, ref int pos) { - bool[] t = new bool[8]; - byte temp = data[pos]; - for (int i = 0; i < 8; i++) + var t = new bool[8]; + var temp = data[pos]; + for (var i = 0; i < 8; i++) { - t[7 - i] = temp % 2 > 0; + t[7 - i] = temp%2 > 0; temp /= 2; } pos += 1; @@ -1021,7 +1037,7 @@ namespace Modbus.Net return base.SetBit(number, pos, 7 - subPos, setBit); } - private Byte[] Reverse(Byte[] data) + private byte[] Reverse(byte[] data) { Array.Reverse(data); return data;