From f173faf693881934706cfc0584b16ea2c0d33b09 Mon Sep 17 00:00:00 2001 From: "parallelbgls@outlook.com" Date: Fri, 19 Sep 2014 11:38:52 +0800 Subject: [PATCH] 2014-09-19 update 1 --- Modbus.Net/ModBus.Net/AddressTranslator.cs | 27 +++--- Modbus.Net/ModBus.Net/BaseProtocal.cs | 1 + Modbus.Net/ModBus.Net/ModbusProtocal.cs | 16 ++-- Modbus.Net/ModBus.Net/ProtocalUnit.cs | 89 ++---------------- Modbus.Net/ModBus.Net/ValueHelper.cs | 104 ++++++++++++++++++++- 5 files changed, 136 insertions(+), 101 deletions(-) diff --git a/Modbus.Net/ModBus.Net/AddressTranslator.cs b/Modbus.Net/ModBus.Net/AddressTranslator.cs index 23aeb9e..1b53b2b 100644 --- a/Modbus.Net/ModBus.Net/AddressTranslator.cs +++ b/Modbus.Net/ModBus.Net/AddressTranslator.cs @@ -7,9 +7,6 @@ namespace ModBus.Net /// public abstract class AddressTranslator { - protected static AddressTranslator _instance; - public Dictionary TransDictionary; - public abstract ushort AddressTranslate(string address); } @@ -18,6 +15,8 @@ namespace ModBus.Net /// public class AddressTranslatorNA200H : AddressTranslator { + public Dictionary TransDictionary; + private AddressTranslatorNA200H() { TransDictionary = new Dictionary(); @@ -36,15 +35,6 @@ namespace ModBus.Net TransDictionary.Add("V", 0); } - public static AddressTranslator GetInstance() - { - if (_instance == null) - { - _instance = new AddressTranslatorNA200H(); - } - return _instance; - } - public override ushort AddressTranslate(string address) { address = address.ToUpper(); @@ -60,4 +50,17 @@ namespace ModBus.Net return (ushort) (TransDictionary[head] + ushort.Parse(tail) - 1); } } + + public class AddressTranslatorBase : AddressTranslator + { + public override ushort AddressTranslate(string address) + { + ushort num; + if (ushort.TryParse(address, out num)) + { + return num; + } + return 0; + } + } } \ No newline at end of file diff --git a/Modbus.Net/ModBus.Net/BaseProtocal.cs b/Modbus.Net/ModBus.Net/BaseProtocal.cs index d1f2232..32cdc26 100644 --- a/Modbus.Net/ModBus.Net/BaseProtocal.cs +++ b/Modbus.Net/ModBus.Net/BaseProtocal.cs @@ -16,6 +16,7 @@ namespace ModBus.Net /// 数据是否正确接收 protected ProtocalLinker _protocalLinker; + protected BaseProtocal() { Protocals = new Dictionary(); diff --git a/Modbus.Net/ModBus.Net/ModbusProtocal.cs b/Modbus.Net/ModBus.Net/ModbusProtocal.cs index 3e78e69..16dedcb 100644 --- a/Modbus.Net/ModBus.Net/ModbusProtocal.cs +++ b/Modbus.Net/ModBus.Net/ModbusProtocal.cs @@ -61,7 +61,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.ReadCoilStatus; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); GetCount = getCount; } @@ -133,7 +133,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.ReadInputStatus; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); GetCount = getCount; } @@ -200,7 +200,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.ReadHoldRegister; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); GetCount = getCount; } @@ -326,7 +326,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.ReadInputRegister; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); GetCount = getCount; } @@ -388,7 +388,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.WriteOneCoil; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); WriteValue = writeValue; } @@ -449,7 +449,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.WriteOneRegister; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); WriteValue = writeValue; } public byte BelongAddress { get; private set; } @@ -509,7 +509,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.WriteMultiCoil; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); WriteCount = (ushort)writeValue.Length; WriteByteCount = WriteCount % 8 > 0 ? (byte)(WriteCount / 8 + 1) : (byte)(WriteCount / 8); WriteValue = new byte[WriteByteCount]; @@ -587,7 +587,7 @@ namespace ModBus.Net { BelongAddress = belongAddress; FunctionCode = (int)ModbusProtocalReg.WriteMultiRegister; - StartAddress = AddressTranslatorNA200H.GetInstance().AddressTranslate(startAddress); + StartAddress = _addressTranslator.AddressTranslate(startAddress); WriteCount = (ushort)writeValue.Length; WriteByteCount = (byte)(WriteCount * 2); WriteValue = writeValue.Clone() as object[]; diff --git a/Modbus.Net/ModBus.Net/ProtocalUnit.cs b/Modbus.Net/ModBus.Net/ProtocalUnit.cs index 1b2f31d..5136404 100644 --- a/Modbus.Net/ModBus.Net/ProtocalUnit.cs +++ b/Modbus.Net/ModBus.Net/ProtocalUnit.cs @@ -7,6 +7,14 @@ namespace ModBus.Net { public abstract class ProtocalUnit : IProtocalFormatting { + protected static AddressTranslator _addressTranslator = new AddressTranslatorBase(); + + public ProtocalUnit SetAddressTranslator(AddressTranslator addressTranslator) + { + _addressTranslator = addressTranslator; + return this; + } + /// /// 格式化,将输入结构转换为字节数组 /// @@ -39,86 +47,7 @@ namespace ModBus.Net /// public static byte[] TranslateContent(params object[] contents) { - bool b = false; - //先查找传入的结构中有没有数组,有的话将其打开 - var newContentsList = new List(); - foreach (object content in contents) - { - string t = content.GetType().ToString(); - if (t.Substring(t.Length - 2, 2) == "[]") - { - b = true; - IEnumerable contentArray = - ArrayList.Adapter((Array)content).ToArray(typeof(object)).OfType(); - newContentsList.AddRange(contentArray); - } - else - { - newContentsList.Add(content); - } - } - //重新调用一边这个函数,这个传入的参数中一定没有数组。 - if (b) return TranslateContent(newContentsList.ToArray()); - //把参数一个一个翻译为相对应的字节,然后拼成一个队列 - var translateTarget = new List(); - foreach (object content in contents) - { - string t = content.GetType().ToString(); - switch (t) - { - case "System.Int16": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((short)content)); - break; - } - case "System.Int32": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((int)content)); - break; - } - case "System.Int64": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((long)content)); - break; - } - case "System.UInt16": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((ushort)content)); - break; - } - case "System.UInt32": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((uint)content)); - break; - } - case "System.UInt64": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((ulong)content)); - break; - } - case "System.Single": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((float)content)); - break; - } - case "System.Double": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((double)content)); - break; - } - case "System.Byte": - { - translateTarget.AddRange(ValueHelper.Instance.GetBytes((byte)content)); - break; - } - default: - { - throw new NotImplementedException("没有实现除整数以外的其它转换方式"); - } - } - } - //最后把队列转换为数组 - return translateTarget.ToArray(); + return ValueHelper.Instance.ObjectArrayToByteArray(contents); } } diff --git a/Modbus.Net/ModBus.Net/ValueHelper.cs b/Modbus.Net/ModBus.Net/ValueHelper.cs index 207e865..2d82f88 100644 --- a/Modbus.Net/ModBus.Net/ValueHelper.cs +++ b/Modbus.Net/ModBus.Net/ValueHelper.cs @@ -1,4 +1,7 @@ using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; namespace ModBus.Net { @@ -33,7 +36,7 @@ namespace ModBus.Net protected static ValueHelper _Instance = null; - internal static ValueHelper Instance + public static ValueHelper Instance { get { @@ -154,6 +157,105 @@ namespace ModBus.Net pos += 8; return t; } + + public byte[] ObjectArrayToByteArray(object[] contents) + { + bool b = false; + //先查找传入的结构中有没有数组,有的话将其打开 + var newContentsList = new List(); + foreach (object content in contents) + { + string t = content.GetType().ToString(); + if (t.Substring(t.Length - 2, 2) == "[]") + { + b = true; + IEnumerable contentArray = + ArrayList.Adapter((Array)content).ToArray(typeof(object)).OfType(); + newContentsList.AddRange(contentArray); + } + else + { + newContentsList.Add(content); + } + } + //重新调用一边这个函数,这个传入的参数中一定没有数组。 + if (b) return ObjectArrayToByteArray(newContentsList.ToArray()); + //把参数一个一个翻译为相对应的字节,然后拼成一个队列 + var translateTarget = new List(); + foreach (object content in contents) + { + string t = content.GetType().ToString(); + switch (t) + { + case "System.Int16": + { + translateTarget.AddRange(Instance.GetBytes((short)content)); + break; + } + case "System.Int32": + { + translateTarget.AddRange(Instance.GetBytes((int)content)); + break; + } + case "System.Int64": + { + translateTarget.AddRange(Instance.GetBytes((long)content)); + break; + } + case "System.UInt16": + { + translateTarget.AddRange(Instance.GetBytes((ushort)content)); + break; + } + case "System.UInt32": + { + translateTarget.AddRange(Instance.GetBytes((uint)content)); + break; + } + case "System.UInt64": + { + translateTarget.AddRange(Instance.GetBytes((ulong)content)); + break; + } + case "System.Single": + { + translateTarget.AddRange(Instance.GetBytes((float)content)); + break; + } + case "System.Double": + { + translateTarget.AddRange(Instance.GetBytes((double)content)); + break; + } + case "System.Byte": + { + translateTarget.AddRange(Instance.GetBytes((byte)content)); + break; + } + default: + { + throw new NotImplementedException("没有实现除整数以外的其它转换方式"); + } + } + } + //最后把队列转换为数组 + return translateTarget.ToArray(); + } + + public int GetBit(ushort number, int pos) + { + + if (pos < 0 && pos > 15) throw new IndexOutOfRangeException(); + int ans = number % 2; + int i = 15; + while (i >= pos) + { + ans = number%2; + number /= 2; + i--; + } + return ans; + } } internal class LittleEndianValueHelper : ValueHelper