From e1cb42a49958424fad2734dbe498c7d11d4ea937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E5=9C=A3?= Date: Mon, 29 Aug 2016 17:15:29 +0800 Subject: [PATCH] Add GetBit (SubAddress and typeof(bool)) Support --- .../AddressFormaterModbus.cs | 10 ++++ .../AddressTranslatorModbus.cs | 26 ++++++++++ .../Modbus.Net.OPC/AddressFormaterOpc.cs | 5 ++ .../AddressFormaterSiemens.cs | 16 ++----- .../AddressTranslatorSiemens.cs | 48 +++++++------------ Modbus.Net/Modbus.Net/AddressCombiner.cs | 12 ++--- Modbus.Net/Modbus.Net/AddressFormater.cs | 9 +++- Modbus.Net/Modbus.Net/AddressTranslator.cs | 29 ++++++++--- Modbus.Net/Modbus.Net/BaseMachine.cs | 17 ++++--- 9 files changed, 106 insertions(+), 66 deletions(-) diff --git a/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs b/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs index 677c6c8..52efd63 100644 --- a/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs +++ b/Modbus.Net/Modbus.Net.Modbus/AddressFormaterModbus.cs @@ -12,6 +12,11 @@ namespace Modbus.Net.Modbus { return area + " " + address; } + + public override string FormatAddress(string area, int address, int subAddress) + { + return area + " " + address + "." + subAddress; + } } public class AddressFormaterModbus : AddressFormater @@ -20,5 +25,10 @@ namespace Modbus.Net.Modbus { return area + " " + address; } + + public override string FormatAddress(string area, int address, int subAddress) + { + return area + " " + address + "." + subAddress; + } } } diff --git a/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs b/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs index bb156bc..77ca974 100644 --- a/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs +++ b/Modbus.Net/Modbus.Net.Modbus/AddressTranslatorModbus.cs @@ -60,16 +60,29 @@ namespace Modbus.Net.Modbus string[] splitString = address.Split(' '); string head = splitString[0]; string tail = splitString[1]; + string sub; + if (tail.Contains('.')) + { + string[] splitString2 = tail.Split('.'); + sub = splitString2[1]; + tail = splitString2[0]; + } + else + { + sub = "0"; + } return isRead ? new AddressDef() { Area = ReadFunctionCodeDictionary[head].Code, Address = TransDictionary[head] + int.Parse(tail) - 1, + SubAddress = int.Parse(sub), } : new AddressDef() { Area = WriteFunctionCodeDictionary[head].Code, Address = TransDictionary[head] + int.Parse(tail) - 1, + SubAddress = int.Parse(sub), }; } @@ -109,16 +122,29 @@ namespace Modbus.Net.Modbus string[] splitString = address.Split(' '); string head = splitString[0]; string tail = splitString[1]; + string sub; + if (tail.Contains('.')) + { + string[] splitString2 = tail.Split('.'); + sub = splitString2[1]; + tail = splitString2[0]; + } + else + { + sub = "0"; + } return isRead ? new AddressDef() { Area = ReadFunctionCodeDictionary[head].Code, Address = int.Parse(tail) - 1, + SubAddress = int.Parse(sub), } : new AddressDef() { Area = WriteFunctionCodeDictionary[head].Code, Address = int.Parse(tail) - 1, + SubAddress = int.Parse(sub), }; } diff --git a/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs b/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs index ec97edd..b572775 100644 --- a/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs +++ b/Modbus.Net/Modbus.Net.OPC/AddressFormaterOpc.cs @@ -30,5 +30,10 @@ namespace Modbus.Net.OPC ans = ans.Substring(0, ans.Length - 1); return ans; } + + public override string FormatAddress(string area, int address, int subAddress) + { + return FormatAddress(area, address); + } } } diff --git a/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs b/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs index e3926c0..1ea429e 100644 --- a/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs +++ b/Modbus.Net/Modbus.Net.Siemens/AddressFormaterSiemens.cs @@ -10,18 +10,12 @@ namespace Modbus.Net.Siemens { public override string FormatAddress(string area, int address) { - /* - if (area.Length > 1 && - area.ToUpper().Substring(0, 2) == "DB") - { - return area.ToUpper() + "." + "DB" + address; - } - else - { - return area.ToUpper() + address; - } - */ return area + " " + address; } + + public override string FormatAddress(string area, int address, int subAddress) + { + return area + " " + address + "." + subAddress; + } } } diff --git a/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs b/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs index 970a4d0..3882ed3 100644 --- a/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs +++ b/Modbus.Net/Modbus.Net.Siemens/AddressTranslatorSiemens.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Modbus.Net.Siemens { @@ -28,54 +29,37 @@ namespace Modbus.Net.Siemens public override AddressDef AddressTranslate(string address, bool isRead) { - /* address = address.ToUpper(); - if (address.Substring(0, 2) == "DB") - { - var addressSplit = address.Split('.'); - if (addressSplit.Length != 2) throw new FormatException(); - addressSplit[0] = addressSplit[0].Substring(2); - if (addressSplit[1].Substring(0, 2) == "DB") - addressSplit[1] = addressSplit[1].Substring(2); - return new AddressDef() - { - Area = int.Parse(addressSplit[0])*256 + AreaCodeDictionary["DB"], - Address = int.Parse(addressSplit[1]) - }; - } - int i = 0; - int t; - while (!int.TryParse(address[i].ToString(), out t) && i < address.Length) - { - i++; - } - if (i == 0 || i >= address.Length) throw new FormatException(); - string head = address.Substring(0, i); - string tail = address.Substring(i); - return - new AddressDef() - { - Area = AreaCodeDictionary[head], - Address = int.Parse(tail) - }; - */ string[] splitString = address.Split(' '); string head = splitString[0]; string tail = splitString[1]; + string sub; + if (tail.Contains('.')) + { + string[] splitString2 = tail.Split('.'); + sub = splitString2[1]; + tail = splitString2[0]; + } + else + { + sub = "0"; + } if (head.Length > 1 && head.Substring(0, 2) == "DB") { head = head.Substring(2); return new AddressDef() { Area = int.Parse(head)*256 + AreaCodeDictionary["DB"], - Address = int.Parse(tail) + Address = int.Parse(tail), + SubAddress = int.Parse(sub), }; } return new AddressDef() { Area = AreaCodeDictionary[head], - Address = int.Parse(tail) + Address = int.Parse(tail), + SubAddress = int.Parse(sub), }; } diff --git a/Modbus.Net/Modbus.Net/AddressCombiner.cs b/Modbus.Net/Modbus.Net/AddressCombiner.cs index 011ed2f..fd0b3f8 100644 --- a/Modbus.Net/Modbus.Net/AddressCombiner.cs +++ b/Modbus.Net/Modbus.Net/AddressCombiner.cs @@ -27,7 +27,7 @@ namespace Modbus.Net public override IEnumerable Combine(IEnumerable addresses) { var groupedAddresses = from address in addresses - orderby address.Address + orderby address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)) group address by address.Area into grouped select grouped; @@ -41,18 +41,18 @@ namespace Modbus.Net double getCount = 0; double byteCount = 0; List originalAddresses = new List(); - foreach (var address in groupedAddress.OrderBy(address => address.Address)) + foreach (var address in groupedAddress.OrderBy(address => address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)))) { if (initNum < 0) { - initNum = address.Address + (address.SubAddress + 1) * 0.125; + initNum = address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)); getCount = BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName] / AddressTranslator.GetAreaByteLength(address.Area); byteCount = BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]; originalAddresses.Add(address); } else { - if (address.Address > preNum + (int) (BigEndianValueHelper.Instance.ByteLength[preType.FullName] / AddressTranslator.GetAreaByteLength(address.Area))) + if (address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)) > preNum + BigEndianValueHelper.Instance.ByteLength[preType.FullName] / AddressTranslator.GetAreaByteLength(address.Area)) { ans.Add(new CommunicationUnit() { @@ -70,12 +70,12 @@ namespace Modbus.Net } else { - getCount += BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]/ AddressTranslator.GetAreaByteLength(address.Area); + getCount += BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName] / AddressTranslator.GetAreaByteLength(address.Area); byteCount += BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]; originalAddresses.Add(address); } } - preNum = address.Address; + preNum = address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area)); preType = address.DataType; } ans.Add(new CommunicationUnit() diff --git a/Modbus.Net/Modbus.Net/AddressFormater.cs b/Modbus.Net/Modbus.Net/AddressFormater.cs index 4795cd9..18cef1c 100644 --- a/Modbus.Net/Modbus.Net/AddressFormater.cs +++ b/Modbus.Net/Modbus.Net/AddressFormater.cs @@ -7,13 +7,15 @@ namespace Modbus.Net /// public abstract class AddressFormater { + public abstract string FormatAddress(string area, int address); /// /// 编码地址 /// /// 地址所在的数据区域 /// 地址 + /// 子地址 /// 编码后的地址 - public abstract string FormatAddress(string area, int address); + public abstract string FormatAddress(string area, int address, int subAddress); } /// @@ -25,5 +27,10 @@ namespace Modbus.Net { return area + ":" + address; } + + public override string FormatAddress(string area, int address, int subAddress) + { + return area + ":" + address + ":" + subAddress; + } } } diff --git a/Modbus.Net/Modbus.Net/AddressTranslator.cs b/Modbus.Net/Modbus.Net/AddressTranslator.cs index a42ec12..3a97fca 100644 --- a/Modbus.Net/Modbus.Net/AddressTranslator.cs +++ b/Modbus.Net/Modbus.Net/AddressTranslator.cs @@ -7,6 +7,7 @@ namespace Modbus.Net { public int Area { get; set; } public int Address { get; set; } + public int SubAddress { get; set; } } public class AreaOutputDef @@ -38,16 +39,30 @@ namespace Modbus.Net { public override AddressDef AddressTranslate(string address, bool isRead) { - int num1,num2; + int num1,num2,num3; string[] split = address.Split(':'); - if (split.Length != 2) throw new FormatException(); - if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2)) + if (split.Length == 2) { - return new AddressDef() + if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2)) { - Area = num1, - Address = num2 - }; + return new AddressDef() + { + Area = num1, + Address = num2 + }; + } + } + else if (split.Length == 3) + { + if (int.TryParse(split[0], out num1) && int.TryParse(split[1], out num2) && int.TryParse(split[3], out num3)) + { + return new AddressDef() + { + Area = num1, + Address = num2, + SubAddress = num3, + }; + } } throw new FormatException(); } diff --git a/Modbus.Net/Modbus.Net/BaseMachine.cs b/Modbus.Net/Modbus.Net/BaseMachine.cs index 98201be..de6d175 100644 --- a/Modbus.Net/Modbus.Net/BaseMachine.cs +++ b/Modbus.Net/Modbus.Net/BaseMachine.cs @@ -163,7 +163,7 @@ namespace Modbus.Net var datasReturn = await BaseUtility.GetDatasAsync(2, 0, - AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address), + AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0), (int) Math.Ceiling(communicateAddress.GetCount* BigEndianValueHelper.Instance.ByteLength[ @@ -181,7 +181,7 @@ namespace Modbus.Net datas = datasReturn.ReturnValue; //如果没有数据,终止 - if (datas == null || datas.Length == 0 || datas.Length != + if (datas == null || datas.Length == 0 || datas.Length < (int) Math.Ceiling(communicateAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[ @@ -191,8 +191,8 @@ namespace Modbus.Net foreach (var address in communicateAddress.OriginalAddresses) { - var localPos = ((address.Address - communicateAddress.Address)*8 + address.SubAddress)* - AddressTranslator.GetAreaByteLength(communicateAddress.Area)/8.0; + var localPos = (address.Address - communicateAddress.Address)* + AddressTranslator.GetAreaByteLength(communicateAddress.Area)+address.SubAddress/8.0; var localMainPos = (int) localPos; var localSubPos = (int) ((localPos - localMainPos)*8); @@ -206,7 +206,7 @@ namespace Modbus.Net } case MachineGetDataType.Address: { - key = AddressFormater.FormatAddress(address.Area, address.Address); + key = AddressFormater.FormatAddress(address.Area, address.Address, address.SubAddress); break; } default: @@ -231,13 +231,12 @@ namespace Modbus.Net new ReturnUnit { PlcValue = - Double.Parse( + Convert.ToDouble( datasReturn.IsLittleEndian ? ValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos, address.DataType) .ToString() : BigEndianValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos, - address.DataType) - .ToString()) * address.Zoom, + address.DataType)) * address.Zoom, UnitExtend = address.UnitExtend }); } @@ -304,7 +303,7 @@ namespace Modbus.Net case MachineSetDataType.Address: { address = - GetAddresses.SingleOrDefault(p => AddressFormater.FormatAddress(p.Area, p.Address) == value.Key); + GetAddresses.SingleOrDefault(p => AddressFormater.FormatAddress(p.Area, p.Address, p.SubAddress) == value.Key || (p.DataType != typeof(bool) && AddressFormater.FormatAddress(p.Area, p.Address) == value.Key)); break; } case MachineSetDataType.CommunicationTag: