diff --git a/Modbus.Net/ModBus.Net/AddressTranslator.cs b/Modbus.Net/ModBus.Net/AddressTranslator.cs index f465ec0..b564681 100644 --- a/Modbus.Net/ModBus.Net/AddressTranslator.cs +++ b/Modbus.Net/ModBus.Net/AddressTranslator.cs @@ -76,6 +76,9 @@ namespace ModBus.Net } } + /// + /// 基本的单元转换器 + /// public class AddressTranslatorBase : AddressTranslator { public override ushort AddressTranslate(string address) diff --git a/Modbus.Net/ModBus.Net/BaseConnector.cs b/Modbus.Net/ModBus.Net/BaseConnector.cs index 5e3e60b..4aacf2b 100644 --- a/Modbus.Net/ModBus.Net/BaseConnector.cs +++ b/Modbus.Net/ModBus.Net/BaseConnector.cs @@ -8,9 +8,27 @@ namespace ModBus.Net { public abstract class BaseConnector { + /// + /// 连接PLC + /// + /// public abstract bool Connect(); + /// + /// 断开PLC + /// + /// public abstract bool Disconnect(); + /// + /// 无返回发送数据 + /// + /// + /// public abstract bool SendMsgWithoutReturn(byte[] message); + /// + /// 带返回发送数据 + /// + /// + /// public abstract byte[] SendMsg(byte[] message); } } diff --git a/Modbus.Net/ModBus.Net/BaseUtility.cs b/Modbus.Net/ModBus.Net/BaseUtility.cs index 75a0ad9..cbb2708 100644 --- a/Modbus.Net/ModBus.Net/BaseUtility.cs +++ b/Modbus.Net/ModBus.Net/BaseUtility.cs @@ -8,9 +8,37 @@ namespace ModBus.Net { public abstract class BaseUtility { + /// + /// 协议收发主体 + /// + protected BaseProtocal Wrapper; + /// + /// 设置连接字符串 + /// + /// 连接字符串 public abstract void SetConnectionString(string connectionString); + /// + /// 设置连接类型 + /// + /// 连接类型 public abstract void SetConnectionType(int connectionType); + /// + /// 获取数据 + /// + /// 从站地址 + /// 功能码 + /// 开始地址 + /// 接收个数 + /// 接收到的byte数据 public abstract byte[] GetDatas(byte belongAddress, byte functionCode, string startAddress, ushort getCount); + /// + /// 设置数据 + /// + /// 从站地址 + /// 功能码 + /// 开始地址 + /// 设置个数 + /// 是否设置成功 public abstract bool SetDatas(byte belongAddress, byte functionCode, string startAddress, object[] setContents); } } diff --git a/Modbus.Net/ModBus.Net/RtuProtocalLinker.cs b/Modbus.Net/ModBus.Net/ComProtocalLinker.cs similarity index 70% rename from Modbus.Net/ModBus.Net/RtuProtocalLinker.cs rename to Modbus.Net/ModBus.Net/ComProtocalLinker.cs index ed2f0af..f397213 100644 --- a/Modbus.Net/ModBus.Net/RtuProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ComProtocalLinker.cs @@ -6,15 +6,15 @@ using System.Threading.Tasks; namespace ModBus.Net { - public abstract class RtuProtocalLinker : ProtocalLinker + public abstract class ComProtocalLinker : ProtocalLinker { - protected RtuProtocalLinker() + protected ComProtocalLinker() { //初始化连对象 _baseConnector = new ComConnector(ConfigurationManager.COM); } - protected RtuProtocalLinker(string com) + protected ComProtocalLinker(string com) { _baseConnector = new ComConnector(com); } diff --git a/Modbus.Net/ModBus.Net/ModBus.Net.csproj b/Modbus.Net/ModBus.Net/ModBus.Net.csproj index cddca3b..da83504 100644 --- a/Modbus.Net/ModBus.Net/ModBus.Net.csproj +++ b/Modbus.Net/ModBus.Net/ModBus.Net.csproj @@ -46,7 +46,7 @@ - + True True diff --git a/Modbus.Net/ModBus.Net/ModbusProtocal.cs b/Modbus.Net/ModBus.Net/ModbusProtocal.cs index 60cb174..02f1a61 100644 --- a/Modbus.Net/ModBus.Net/ModbusProtocal.cs +++ b/Modbus.Net/ModBus.Net/ModbusProtocal.cs @@ -2,18 +2,19 @@ using System.Collections.Generic; using System.Runtime.Remoting.Messaging; -public enum ModbusProtocalFunctionCode -{ - -} - -internal enum ModbusProtocalTimeFunctionCode +/// +/// 跟时间有关的功能码 +/// +internal enum ModbusProtocalTimeFunctionCode : byte { GetSystemTime = 3, SetSystemTime = 16, }; -public enum ModbusProtocalReadDataFunctionCode +/// +/// 跟读数据有关的功能码 +/// +public enum ModbusProtocalReadDataFunctionCode : byte { ReadCoilStatus = 1, ReadInputStatus = 2, @@ -21,11 +22,15 @@ public enum ModbusProtocalReadDataFunctionCode ReadInputRegister = 4, } -public enum ModbusProtocalWriteDataFunctionCode +/// +/// 跟写数据有关的功能码 +/// +public enum ModbusProtocalWriteDataFunctionCode : byte { WriteMultiCoil = 15, WriteMultiRegister = 16, } + namespace ModBus.Net { public abstract class ModbusProtocal : BaseProtocal @@ -33,6 +38,7 @@ namespace ModBus.Net } + #region 读PLC数据 public class ReadDataInputStruct : InputStruct { public ReadDataInputStruct(byte belongAddress, ModbusProtocalReadDataFunctionCode functionCode, string startAddress, ushort getCount) @@ -92,6 +98,9 @@ namespace ModBus.Net } } + #endregion + + #region 写PLC数据 public class WriteDataInputStruct : InputStruct { public WriteDataInputStruct(byte belongAddress, ModbusProtocalWriteDataFunctionCode functionCode, string startAddress, object[] writeValue) @@ -162,6 +171,9 @@ namespace ModBus.Net } } + #endregion + + #region 读PLC时间 public class GetSystemTimeInputStruct : InputStruct { public GetSystemTimeInputStruct(byte belongAddress) @@ -231,6 +243,9 @@ namespace ModBus.Net } } + #endregion + + #region 写PLC时间 public class SetSystemTimeInputStruct : InputStruct { public SetSystemTimeInputStruct(byte belongAddress, DateTime time) @@ -317,16 +332,11 @@ namespace ModBus.Net return new SetSystemTimeOutputStruct(belongAddress, functionCode, startAddress, writeCount); } } + #endregion - public class ProtocalErrorException : Exception - { - public ProtocalErrorException(string message) - : base(message) - { - - } - } - + /// + /// Modbus协议错误表 + /// public class ModbusProtocalErrorException : ProtocalErrorException { public int ErrorMessageNumber { get; private set; } diff --git a/Modbus.Net/ModBus.Net/ModbusRtuProtocal.cs b/Modbus.Net/ModBus.Net/ModbusRtuProtocal.cs index e0b8055..2e1b420 100644 --- a/Modbus.Net/ModBus.Net/ModbusRtuProtocal.cs +++ b/Modbus.Net/ModBus.Net/ModbusRtuProtocal.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; namespace ModBus.Net { + /// + /// Modbus/Rtu协议 + /// public class ModbusRtuProtocal : ModbusProtocal { public ModbusRtuProtocal() diff --git a/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs b/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs index b9349b9..68fb74b 100644 --- a/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ModbusRtuProtocalLinker.cs @@ -6,14 +6,16 @@ using System.Threading.Tasks; namespace ModBus.Net { - class ModbusRtuProtocalLinker : RtuProtocalLinker + class ModbusRtuProtocalLinker : ComProtocalLinker { public override bool CheckRight(byte[] content) { + //CRC校验失败 if (!Crc16.GetInstance().CrcEfficacy(content)) { throw new ModbusProtocalErrorException(501); } + //Modbus协议错误 if (content[1] > 127) { throw new ModbusProtocalErrorException(content[2]); @@ -21,7 +23,7 @@ namespace ModBus.Net return true; } - public ModbusRtuProtocalLinker() : base() + public ModbusRtuProtocalLinker() : this(ConfigurationManager.COM) { } diff --git a/Modbus.Net/ModBus.Net/ModbusTCPProtocal.cs b/Modbus.Net/ModBus.Net/ModbusTCPProtocal.cs index 2f6f284..372ed5c 100644 --- a/Modbus.Net/ModBus.Net/ModbusTCPProtocal.cs +++ b/Modbus.Net/ModBus.Net/ModbusTCPProtocal.cs @@ -7,7 +7,6 @@ namespace ModBus.Net /// public class ModbusTcpProtocal : ModbusProtocal { - //将连接器设置为Tcp连接器 public ModbusTcpProtocal() { _protocalLinker = new ModbusTcpProtocalLinker(); diff --git a/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs b/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs index c4ebd84..3b65b17 100644 --- a/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/ModbusTcpProtocalLinker.cs @@ -10,10 +10,12 @@ namespace ModBus.Net { public override bool CheckRight(byte[] content) { + //长度校验失败 if (content[5] != content.Length - 6) { throw new ModbusProtocalErrorException(500); } + //Modbus协议错误 if (content[7] > 127) { throw new ModbusProtocalErrorException(content[2]); @@ -21,7 +23,7 @@ namespace ModBus.Net return true; } - public ModbusTcpProtocalLinker() : base() + public ModbusTcpProtocalLinker() : this(ConfigurationManager.IP) { } diff --git a/Modbus.Net/ModBus.Net/ModbusUtility.cs b/Modbus.Net/ModBus.Net/ModbusUtility.cs index 7121d0e..abb5ee9 100644 --- a/Modbus.Net/ModBus.Net/ModbusUtility.cs +++ b/Modbus.Net/ModBus.Net/ModbusUtility.cs @@ -2,9 +2,18 @@ using System.Collections; using System.Windows.Forms; +/// +/// Modbus连接类型 +/// public enum ModbusType { + /// + /// Rtu连接 + /// Rtu = 0, + /// + /// Tcp连接 + /// Tcp = 1, } @@ -12,11 +21,7 @@ namespace ModBus.Net { public class ModbusUtility : BaseUtility { - private BaseProtocal _wrapper; - - private string _connectionString; - - public string ConnectionString { get; set; } + protected string ConnectionString { get; set; } private ModbusType _modbusType; @@ -33,12 +38,12 @@ namespace ModBus.Net { case ModbusType.Rtu: { - _wrapper = ConnectionString == null ? new ModbusRtuProtocal() : new ModbusRtuProtocal(ConnectionString); + Wrapper = ConnectionString == null ? new ModbusRtuProtocal() : new ModbusRtuProtocal(ConnectionString); break; } case ModbusType.Tcp: { - _wrapper = ConnectionString == null ? new ModbusTcpProtocal() : new ModbusTcpProtocal(ConnectionString); + Wrapper = ConnectionString == null ? new ModbusTcpProtocal() : new ModbusTcpProtocal(ConnectionString); break; } } @@ -73,7 +78,7 @@ namespace ModBus.Net { var inputStruct = new ReadDataInputStruct(belongAddress, (ModbusProtocalReadDataFunctionCode)functionCode, startAddress, getCount); var outputStruct = - _wrapper.SendReceive(_wrapper["ReadDataModbusProtocal"], inputStruct) as ReadDataOutputStruct; + Wrapper.SendReceive(Wrapper["ReadDataModbusProtocal"], inputStruct) as ReadDataOutputStruct; return outputStruct.DataValue; } catch @@ -89,7 +94,7 @@ namespace ModBus.Net var inputStruct = new WriteDataInputStruct(belongAddress, (ModbusProtocalWriteDataFunctionCode) functionCode, startAddress, setContents); var outputStruct = - _wrapper.SendReceive(_wrapper["WriteDataModbusProtocal"], inputStruct) as + Wrapper.SendReceive(Wrapper["WriteDataModbusProtocal"], inputStruct) as WriteDataOutputStruct; if (outputStruct.WriteCount != setContents.Length) return false; return true; diff --git a/Modbus.Net/ModBus.Net/ProtocalLinkerBytesExtend.cs b/Modbus.Net/ModBus.Net/ProtocalLinkerBytesExtend.cs index f243b1a..fda64f4 100644 --- a/Modbus.Net/ModBus.Net/ProtocalLinkerBytesExtend.cs +++ b/Modbus.Net/ModBus.Net/ProtocalLinkerBytesExtend.cs @@ -57,7 +57,7 @@ namespace ModBus.Net public override byte[] BytesExtend(byte[] content) { byte[] crc = new byte[2]; - //Modbus/Tcp协议扩张,增加CRC校验 + //Modbus/Rtu协议扩张,增加CRC校验 byte[] newFormat = new byte[content.Length + 2]; Crc16.GetInstance().GetCRC(content, ref crc); Array.Copy(content, 0, newFormat, 0, content.Length); @@ -67,7 +67,7 @@ namespace ModBus.Net public override byte[] BytesDecact(byte[] content) { - //Modbus/Com协议收缩,抛弃后面1个字节的内容 + //Modbus/Rtu协议收缩,抛弃后面1个字节的内容 byte[] newContent = new byte[content.Length - 2]; Array.Copy(content, 0, newContent, 0, newContent.Length); return newContent; diff --git a/Modbus.Net/ModBus.Net/ProtocalUnit.cs b/Modbus.Net/ModBus.Net/ProtocalUnit.cs index e6914d0..c109b8b 100644 --- a/Modbus.Net/ModBus.Net/ProtocalUnit.cs +++ b/Modbus.Net/ModBus.Net/ProtocalUnit.cs @@ -64,4 +64,16 @@ namespace ModBus.Net 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/TcpProtocalLinker.cs b/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs index f51c4a3..d277165 100644 --- a/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs +++ b/Modbus.Net/ModBus.Net/TcpProtocalLinker.cs @@ -4,11 +4,11 @@ using System.Linq; namespace ModBus.Net { + /// + /// Tcp连接对象 + /// public abstract class TcpProtocalLinker : ProtocalLinker { - /// - /// 连接对象 - /// protected TcpProtocalLinker() : this(ConfigurationManager.IP) { @@ -18,6 +18,7 @@ namespace ModBus.Net protected TcpProtocalLinker(string ip) { int port; + //是否启用ConfigurationManager里的Port参数 if (ConfigurationManager.ResourceManager.GetString("Port") != null && int.TryParse(ConfigurationManager.ResourceManager.GetString("Port"),out port)) { diff --git a/Modbus.Net/ModBus.Net/ValueHelper.cs b/Modbus.Net/ModBus.Net/ValueHelper.cs index 87e4dbe..02b155d 100644 --- a/Modbus.Net/ModBus.Net/ValueHelper.cs +++ b/Modbus.Net/ModBus.Net/ValueHelper.cs @@ -36,6 +36,9 @@ namespace ModBus.Net protected static ValueHelper _Instance = null; + /// + /// ValueHelper单例的实例 + /// public static ValueHelper Instance { get @@ -50,51 +53,102 @@ namespace ModBus.Net #endregion + /// + /// 将一个byte数字转换为一个byte元素的数组。 + /// + /// byte数字 + /// byte数组 public Byte[] GetBytes(byte value) { return new[] {value}; } + /// + /// 将short数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(short value) { return BitConverter.GetBytes(value); } + /// + /// 将int数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(int value) { return BitConverter.GetBytes(value); } + /// + /// 将long数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(long value) { return BitConverter.GetBytes(value); } + /// + /// 将ushort数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(ushort value) { return BitConverter.GetBytes(value); } + /// + /// 将uint数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(uint value) { return BitConverter.GetBytes(value); } + /// + /// 将ulong数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(ulong value) { return BitConverter.GetBytes(value); } + /// + /// 将float数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(float value) { return BitConverter.GetBytes(value); } + /// + /// 将double数字转换为byte数组 + /// + /// + /// public virtual Byte[] GetBytes(double value) { return BitConverter.GetBytes(value); } + /// + /// 将byte数组中相应的位置转换为byte数字 + /// + /// + /// + /// public virtual byte GetByte(byte[] data, ref int pos) { byte t = data[pos]; @@ -102,6 +156,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为short数字 + /// + /// + /// + /// public virtual short GetShort(byte[] data, ref int pos) { short t = BitConverter.ToInt16(data, pos); @@ -109,6 +169,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为int数字 + /// + /// + /// + /// public virtual int GetInt(byte[] data, ref int pos) { int t = BitConverter.ToInt32(data, pos); @@ -116,6 +182,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为long数字 + /// + /// + /// + /// public virtual long GetLong(byte[] data, ref int pos) { long t = BitConverter.ToInt64(data, pos); @@ -123,6 +195,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为ushort数字 + /// + /// + /// + /// public virtual ushort GetUShort(byte[] data, ref int pos) { ushort t = BitConverter.ToUInt16(data, pos); @@ -130,6 +208,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为uint数字 + /// + /// + /// + /// public virtual uint GetUInt(byte[] data, ref int pos) { uint t = BitConverter.ToUInt32(data, pos); @@ -137,6 +221,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为ulong数字 + /// + /// + /// + /// public virtual ulong GetULong(byte[] data, ref int pos) { ulong t = BitConverter.ToUInt64(data, pos); @@ -144,6 +234,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为float数字 + /// + /// + /// + /// public virtual float GetFloat(byte[] data, ref int pos) { float t = BitConverter.ToSingle(data, pos); @@ -151,6 +247,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为double数字 + /// + /// + /// + /// public virtual double GetDouble(byte[] data, ref int pos) { double t = BitConverter.ToDouble(data, pos); @@ -158,6 +260,12 @@ namespace ModBus.Net return t; } + /// + /// 将byte数组中相应的位置转换为8个bit数字 + /// + /// + /// + /// public virtual bool[] GetBits(byte[] data, ref int pos) { bool[] t = new bool[8]; @@ -171,6 +279,11 @@ namespace ModBus.Net return t; } + /// + /// 将待转换的对象数组转换为需要发送的byte数组 + /// + /// + /// public byte[] ObjectArrayToByteArray(object[] contents) { bool b = false; @@ -182,6 +295,7 @@ namespace ModBus.Net if (t.Substring(t.Length - 2, 2) == "[]") { b = true; + //自动将目标数组中内含的子数组展开,是所有包含在子数组拼接为一个数组 IEnumerable contentArray = ArrayList.Adapter((Array) content).ToArray(typeof (object)).OfType(); newContentsList.AddRange(contentArray); @@ -195,6 +309,7 @@ namespace ModBus.Net if (b) return ObjectArrayToByteArray(newContentsList.ToArray()); //把参数一个一个翻译为相对应的字节,然后拼成一个队列 var translateTarget = new List(); + //将bool类型拼装为byte类型时,按照8个一组,不满8个时补false为原则进行 bool lastIsBool = false; byte boolToByteTemp = 0; int boolToByteCount = 0; @@ -283,19 +398,32 @@ namespace ModBus.Net } } } - //最后把队列转换为数组 + //最后是bool拼装时,表示数字还没有添加,把数字添加进返回数组中。 if (lastIsBool) { translateTarget.Add(boolToByteTemp); } + //最后把队列转换为数组 return translateTarget.ToArray(); } + /// + /// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 + /// + /// byte数组 + /// 单一的类型和需要转换的个数的键值对 + /// object数组 public object[] ByteArrayToObjectArray(byte[] contents, KeyValuePair translateTypeAndCount) { return ByteArrayToObjectArray(contents, new List>() {translateTypeAndCount}); } + /// + /// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 + /// + /// byte数组 + /// 一连串类型和需要转换的个数的键值对,该方法会依次转换每一个需要转的目标数据类型。比如:typeof(int),5; typeof(short),3 会转换出8个元素(当然前提是byte数组足够长的时候),5个int和3个short,然后全部变为object类型返回。 + /// object数组 public object[] ByteArrayToObjectArray(byte[] contents, IEnumerable> translateTypeAndCount) { @@ -388,6 +516,12 @@ namespace ModBus.Net return translation.ToArray(); } + /// + /// 将object数组转换为目标类型的单一数组 + /// + /// 需要转换的目标类型 + /// object数组 + /// 目标数组 public T[] ObjectArrayToDestinationArray(object[] contents) { T[] array = new T[contents.Length]; @@ -395,6 +529,12 @@ namespace ModBus.Net return array; } + /// + /// 获取一个byte中相对应的bit数组展开中第n个位置中的bit元素。 + /// + /// byte数字 + /// bit数组中的对应位置 + /// 对应位置的bit元素 public bool GetBit(byte number, ref int pos) { if (pos < 0 && pos > 8) throw new IndexOutOfRangeException(); @@ -410,26 +550,33 @@ namespace ModBus.Net return ans > 0; } - public ushort SetBit(ushort number, int pos, bool setBit) + /// + /// 设置对应数字中相应位置的bit的值 + /// + /// byte数子 + /// 设置位置 + /// 设置bit大小,true为1,false为0 + /// + public byte SetBit(byte number, int pos, bool setBit) { int creation = 0; if (setBit) { - for (int i = 0; i < 16; i++) + for (int i = 0; i < 8; i++) { creation *= 2; if (i == pos) creation++; } - return (ushort) (number | creation); + return (byte) (number | creation); } else { - for (int i = 0; i < 16; i++) + for (int i = 0; i < 8; i++) { creation *= 2; if (i != pos) creation++; } - return (ushort) (number & creation); + return (byte) (number & creation); } } }