Area Width Support (not complete)

This commit is contained in:
罗圣
2016-08-26 16:02:06 +08:00
parent c4e2116192
commit c5e7f36e59
11 changed files with 266 additions and 193 deletions

View File

@@ -12,8 +12,8 @@ namespace Modbus.Net.Modbus
public class AddressTranslatorNA200H : AddressTranslator public class AddressTranslatorNA200H : AddressTranslator
{ {
protected Dictionary<string, int> TransDictionary; protected Dictionary<string, int> TransDictionary;
protected Dictionary<string, int> ReadFunctionCodeDictionary; protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
protected Dictionary<string, int> WriteFunctionCodeDictionary; protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
public AddressTranslatorNA200H() public AddressTranslatorNA200H()
{ {
@@ -30,27 +30,27 @@ namespace Modbus.Net.Modbus
{"QW", 20000}, {"QW", 20000},
{"NW", 21000}, {"NW", 21000},
}; };
ReadFunctionCodeDictionary = new Dictionary<string, int> ReadFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
{ {
{"Q", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus}, {"Q", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}},
{"M", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus}, {"M", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}},
{"N", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus}, {"N", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}},
{"I", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus}, {"I", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus, AreaWidth = 0.125}},
{"S", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus}, {"S", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus, AreaWidth = 0.125}},
{"IW", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister}, {"IW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2}},
{"SW", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister}, {"SW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2}},
{"MW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister}, {"MW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}},
{"NW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister}, {"NW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}},
{"QW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister}, {"QW", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}},
}; };
WriteFunctionCodeDictionary = new Dictionary<string, int> WriteFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
{ {
{"Q", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil}, {"Q", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}},
{"M", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil}, {"M", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}},
{"N", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil}, {"N", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}},
{"MW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister}, {"MW", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}},
{"NW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister}, {"NW", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}},
{"QW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister}, {"QW", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}},
}; };
} }
@@ -63,15 +63,20 @@ namespace Modbus.Net.Modbus
return isRead return isRead
? new AddressDef() ? new AddressDef()
{ {
Area = ReadFunctionCodeDictionary[head], Area = ReadFunctionCodeDictionary[head].Code,
Address = TransDictionary[head] + int.Parse(tail) - 1, Address = TransDictionary[head] + int.Parse(tail) - 1,
} }
: new AddressDef() : new AddressDef()
{ {
Area = WriteFunctionCodeDictionary[head], Area = WriteFunctionCodeDictionary[head].Code,
Address = TransDictionary[head] + int.Parse(tail) - 1, Address = TransDictionary[head] + int.Parse(tail) - 1,
}; };
} }
public override double GetAreaByteLength(string area)
{
return ReadFunctionCodeDictionary[area].AreaWidth;
}
} }
/// <summary> /// <summary>
@@ -79,22 +84,22 @@ namespace Modbus.Net.Modbus
/// </summary> /// </summary>
public class AddressTranslatorModbus : AddressTranslator public class AddressTranslatorModbus : AddressTranslator
{ {
protected Dictionary<string, int> ReadFunctionCodeDictionary; protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
protected Dictionary<string, int> WriteFunctionCodeDictionary; protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
public AddressTranslatorModbus() public AddressTranslatorModbus()
{ {
ReadFunctionCodeDictionary = new Dictionary<string, int> ReadFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
{ {
{"0X", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus}, {"0X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus, AreaWidth = 0.125}},
{"1X", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus}, {"1X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus, AreaWidth = 0.125}},
{"3X", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister}, {"3X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister, AreaWidth = 2}},
{"4X", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister}, {"4X", new AreaOutputDef {Code = (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister, AreaWidth = 2}},
}; };
WriteFunctionCodeDictionary = new Dictionary<string, int> WriteFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
{ {
{"0X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil}, {"0X", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}},
{"4X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister}, {"4X", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}},
}; };
} }
@@ -107,14 +112,19 @@ namespace Modbus.Net.Modbus
return isRead return isRead
? new AddressDef() ? new AddressDef()
{ {
Area = ReadFunctionCodeDictionary[head], Area = ReadFunctionCodeDictionary[head].Code,
Address = int.Parse(tail) - 1, Address = int.Parse(tail) - 1,
} }
: new AddressDef() : new AddressDef()
{ {
Area = WriteFunctionCodeDictionary[head], Area = WriteFunctionCodeDictionary[head].Code,
Address = int.Parse(tail) - 1, Address = int.Parse(tail) - 1,
}; };
} }
public override double GetAreaByteLength(string area)
{
return ReadFunctionCodeDictionary[area].AreaWidth;
}
} }
} }

View File

@@ -9,8 +9,8 @@ namespace Modbus.Net.Modbus
{ {
BaseUtility = new ModbusUtility(connectionType, connectionString); BaseUtility = new ModbusUtility(connectionType, connectionString);
AddressFormater = new AddressFormaterModbus(); AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus(); AddressCombiner = new AddressCombinerContinus(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(); AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
} }
public ModbusMachine(ModbusType connectionType, string connectionString, public ModbusMachine(ModbusType connectionType, string connectionString,

View File

@@ -78,5 +78,10 @@ namespace Modbus.Net.Siemens
Address = int.Parse(tail) Address = int.Parse(tail)
}; };
} }
public override double GetAreaByteLength(string area)
{
return 1;
}
} }
} }

View File

@@ -9,8 +9,8 @@ namespace Modbus.Net.Siemens
{ {
BaseUtility = new SiemensUtility(connectionType, connectionString, model); BaseUtility = new SiemensUtility(connectionType, connectionString, model);
AddressFormater = new AddressFormaterSiemens(); AddressFormater = new AddressFormaterSiemens();
AddressCombiner = new AddressCombinerContinus(); AddressCombiner = new AddressCombinerContinus(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(); AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
} }
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model, public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,

View File

@@ -340,6 +340,7 @@ namespace Modbus.Net.Siemens
} }
} }
/*
public class ReadTimeSiemensInputStruct : InputStruct public class ReadTimeSiemensInputStruct : InputStruct
{ {
public ReadTimeSiemensInputStruct(ushort pduRef) public ReadTimeSiemensInputStruct(ushort pduRef)
@@ -415,6 +416,7 @@ namespace Modbus.Net.Siemens
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
*/
public class SiemensProtocalErrorException : ProtocalErrorException public class SiemensProtocalErrorException : ProtocalErrorException
{ {

View File

@@ -1,4 +1,4 @@
namespace Modbus.Net.Siemens /*namespace Modbus.Net.Siemens
{ {
public struct TodClockStatus public struct TodClockStatus
{ {
@@ -88,3 +88,4 @@
public ushort TodValue { get; set; } public ushort TodValue { get; set; }
} }
} }
*/

View File

@@ -22,6 +22,8 @@ namespace Modbus.Net
/// </summary> /// </summary>
public class AddressCombinerContinus : AddressCombiner public class AddressCombinerContinus : AddressCombiner
{ {
protected AddressTranslator AddressTranslator { get; set; }
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses) public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
{ {
var groupedAddresses = from address in addresses var groupedAddresses = from address in addresses
@@ -33,34 +35,44 @@ namespace Modbus.Net
foreach (var groupedAddress in groupedAddresses) foreach (var groupedAddress in groupedAddresses)
{ {
string area = groupedAddress.Key; string area = groupedAddress.Key;
int initNum = -1; double initNum = -1;
int preNum = -1; double preNum = -1;
Type preType = null; Type preType = null;
int getCount = 0; double getCount = 0;
double byteCount = 0;
List<AddressUnit> originalAddresses = new List<AddressUnit>();
foreach (var address in groupedAddress.OrderBy(address => address.Address)) foreach (var address in groupedAddress.OrderBy(address => address.Address))
{ {
if (initNum < 0) if (initNum < 0)
{ {
initNum = address.Address; initNum = address.Address + (address.SubAddress + 1) * 0.125;
getCount = (int) BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]; getCount = BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName] / AddressTranslator.GetAreaByteLength(address.Area);
byteCount = BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName];
originalAddresses.Add(address);
} }
else else
{ {
if (address.Address > preNum + BigEndianValueHelper.Instance.ByteLength[preType.FullName]) if (address.Address > preNum + (int) (BigEndianValueHelper.Instance.ByteLength[preType.FullName] / AddressTranslator.GetAreaByteLength(address.Area)))
{ {
ans.Add(new CommunicationUnit() ans.Add(new CommunicationUnit()
{ {
Area = area, Area = area,
Address = initNum, Address = (int)Math.Floor(initNum),
GetCount = getCount, GetCount = (int)Math.Ceiling(byteCount),
DataType = typeof (byte) DataType = typeof (byte),
OriginalAddresses = originalAddresses.ToList(),
}); });
initNum = address.Address; initNum = address.Address;
getCount = (int) BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]; getCount = BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName] / AddressTranslator.GetAreaByteLength(address.Area);
byteCount = BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName];
originalAddresses.Clear();
originalAddresses.Add(address);
} }
else else
{ {
getCount += (int) BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]; 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;
@@ -69,13 +81,19 @@ namespace Modbus.Net
ans.Add(new CommunicationUnit() ans.Add(new CommunicationUnit()
{ {
Area = area, Area = area,
Address = initNum, Address = (int)Math.Floor(initNum),
GetCount = getCount, GetCount = (int)Math.Ceiling(byteCount),
DataType = typeof (byte) DataType = typeof (byte),
OriginalAddresses = originalAddresses.ToList()
}); });
} }
return ans; return ans;
} }
public AddressCombinerContinus(AddressTranslator addressTranslator)
{
AddressTranslator = addressTranslator;
}
} }
public class AddressCombinerSingle : AddressCombiner public class AddressCombinerSingle : AddressCombiner
@@ -90,7 +108,8 @@ namespace Modbus.Net
Area = address.Area, Area = address.Area,
Address = address.Address, Address = address.Address,
DataType = address.DataType, DataType = address.DataType,
GetCount = 1 GetCount = 1,
OriginalAddresses = new List<AddressUnit>() {address}
}).ToList(); }).ToList();
} }
} }
@@ -101,18 +120,18 @@ namespace Modbus.Net
public int GapNumber { get; set; } public int GapNumber { get; set; }
} }
public class AddressCombinerNumericJump : AddressCombiner public class AddressCombinerNumericJump : AddressCombinerContinus
{ {
private int JumpNumber { get; } private int JumpNumber { get; }
public AddressCombinerNumericJump(int jumpNumber) public AddressCombinerNumericJump(int jumpByteCount, AddressTranslator addressTranslator) : base(addressTranslator)
{ {
JumpNumber = jumpNumber; JumpNumber = jumpByteCount;
} }
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses) public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
{ {
var continusAddresses = new AddressCombinerContinus().Combine(addresses).ToList(); var continusAddresses = base.Combine(addresses).ToList();
List<CommunicationUnitGap> addressesGaps = new List<CommunicationUnitGap>(); List<CommunicationUnitGap> addressesGaps = new List<CommunicationUnitGap>();
CommunicationUnit preCommunicationUnit = null; CommunicationUnit preCommunicationUnit = null;
foreach (var continusAddress in continusAddresses) foreach (var continusAddress in continusAddresses)
@@ -127,7 +146,7 @@ namespace Modbus.Net
var gap = new CommunicationUnitGap() var gap = new CommunicationUnitGap()
{ {
EndUnit = continusAddress, EndUnit = continusAddress,
GapNumber = continusAddress.Address - preCommunicationUnit.Address - (int)(preCommunicationUnit.GetCount * BigEndianValueHelper.Instance.ByteLength[preCommunicationUnit.DataType.FullName]) GapNumber = (int)Math.Ceiling((continusAddress.Address - preCommunicationUnit.Address) * AddressTranslator.GetAreaByteLength(continusAddress.Area) - preCommunicationUnit.GetCount * BigEndianValueHelper.Instance.ByteLength[preCommunicationUnit.DataType.FullName])
}; };
addressesGaps.Add(gap); addressesGaps.Add(gap);
} }
@@ -155,7 +174,8 @@ namespace Modbus.Net
orderedGap.GapNumber + orderedGap.GapNumber +
(int) (int)
(nowAddress.GetCount*BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName]), (nowAddress.GetCount*BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName]),
DataType = typeof (byte) DataType = typeof (byte),
OriginalAddresses = preAddress.OriginalAddresses.ToList().Union(nowAddress.OriginalAddresses)
}; };
continusAddresses.Insert(index, newAddress); continusAddresses.Insert(index, newAddress);
} }
@@ -163,13 +183,13 @@ namespace Modbus.Net
} }
} }
public class AddressCombinerPercentageJump : AddressCombiner public class AddressCombinerPercentageJump : AddressCombinerContinus
{ {
private double Percentage { get; } private double Percentage { get; }
public AddressCombinerPercentageJump(double percentage) public AddressCombinerPercentageJump(double percentage, AddressTranslator addressTranslator) :base (addressTranslator)
{ {
if (percentage < 0 || percentage > 100) throw new ArgumentException(); if (percentage < 0) percentage = 0;
Percentage = percentage; Percentage = percentage;
} }
@@ -177,7 +197,7 @@ namespace Modbus.Net
{ {
var addressUnits = addresses as IList<AddressUnit> ?? addresses.ToList(); var addressUnits = addresses as IList<AddressUnit> ?? addresses.ToList();
double count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]); double count = addressUnits.Sum(address => BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName]);
return new AddressCombinerNumericJump((int)(count * Percentage / 100.0)).Combine(addressUnits); return new AddressCombinerNumericJump((int)(count * Percentage / 100.0), AddressTranslator).Combine(addressUnits);
} }
} }
} }

View File

@@ -9,6 +9,12 @@ namespace Modbus.Net
public int Address { get; set; } public int Address { get; set; }
} }
public class AreaOutputDef
{
public int Code { get; set; }
public double AreaWidth { get; set; }
}
/// <summary> /// <summary>
/// 地址翻译器 /// 地址翻译器
/// </summary> /// </summary>
@@ -21,6 +27,8 @@ namespace Modbus.Net
/// <param name="isRead">是否为读取,是为读取,否为写入</param> /// <param name="isRead">是否为读取,是为读取,否为写入</param>
/// <returns>Key为转换后的地址Value为辅助码</returns> /// <returns>Key为转换后的地址Value为辅助码</returns>
public abstract AddressDef AddressTranslate(string address, bool isRead); public abstract AddressDef AddressTranslate(string address, bool isRead);
public abstract double GetAreaByteLength(string area);
} }
/// <summary> /// <summary>
@@ -43,5 +51,10 @@ namespace Modbus.Net
} }
throw new FormatException(); throw new FormatException();
} }
public override double GetAreaByteLength(string area)
{
return 1;
}
} }
} }

View File

@@ -185,69 +185,61 @@ namespace Modbus.Net
(int) (int)
Math.Ceiling(communicateAddress.GetCount * Math.Ceiling(communicateAddress.GetCount *
BigEndianValueHelper.Instance.ByteLength[ BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName])) return null; communicateAddress.DataType.FullName]))
return null;
} }
int pos = 0; foreach (var address in communicateAddress.OriginalAddresses)
//解码数据
while (pos < communicateAddress.GetCount)
{ {
//获取地址 var localPos = ((address.Address - communicateAddress.Address)*8 + address.SubAddress)*
var address = AddressTranslator.GetAreaByteLength(communicateAddress.Area)/8.0;
GetAddresses.SingleOrDefault( var localMainPos = (int) localPos;
p => p.Area == communicateAddress.Area && p.Address == pos + communicateAddress.Address); var localSubPos = (int) ((localPos - localMainPos)*8);
if (address != null)
{
string key;
switch (getDataType)
{
case MachineGetDataType.CommunicationTag:
{
key = address.CommunicationTag;
break;
}
case MachineGetDataType.Address:
{
key = AddressFormater.FormatAddress(address.Area, address.Address);
break;
}
default:
{
key = address.CommunicationTag;
break;
}
}
if (datas == null) string key;
{ switch (getDataType)
ans.Add(key, new ReturnUnit {
case MachineGetDataType.CommunicationTag:
{ {
PlcValue = null, key = address.CommunicationTag;
UnitExtend = address.UnitExtend break;
}); }
pos += (int)ValueHelper.Instance.ByteLength[address.DataType.ToString()]; case MachineGetDataType.Address:
} {
else key = AddressFormater.FormatAddress(address.Area, address.Address);
break;
}
default:
{
key = address.CommunicationTag;
break;
}
}
if (datas == null)
{
ans.Add(key, new ReturnUnit
{ {
//将获取的数据和对应的通讯标识对应 PlcValue = null,
ans.Add(key, UnitExtend = address.UnitExtend
new ReturnUnit });
{
PlcValue =
Double.Parse(
datasReturn.IsLittleEndian
? ValueHelper.Instance.GetValue(datas, ref pos, address.DataType)
.ToString()
: BigEndianValueHelper.Instance.GetValue(datas, ref pos,
address.DataType)
.ToString())*address.Zoom,
UnitExtend = address.UnitExtend
});
}
} }
else else
{ {
pos++; //将获取的数据和对应的通讯标识对应
ans.Add(key,
new ReturnUnit
{
PlcValue =
Double.Parse(
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,
UnitExtend = address.UnitExtend
});
} }
} }
} }
@@ -340,26 +332,28 @@ namespace Modbus.Net
{ {
List<object> datasList = new List<object>(); List<object> datasList = new List<object>();
//需要设置的字节数,计数 //需要设置的字节数,计数
var setCount = (int) var setCount =
Math.Ceiling(communicateAddress.GetCount* communicateAddress.GetCount*
BigEndianValueHelper.Instance.ByteLength[ BigEndianValueHelper.Instance.ByteLength[communicateAddress.DataType.FullName];
communicateAddress.DataType.FullName]);
//总数 //总数
var allBytes = setCount; var allBytes = setCount;
//编码开始地址 //编码开始地址
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area, var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
communicateAddress.Address); communicateAddress.Address);
while (setCount > 0)
while (setCount > 0.001)
{ {
var localPos = (allBytes - setCount) / AddressTranslator.GetAreaByteLength(communicateAddress.Area);
//编码当前地址 //编码当前地址
var address = AddressFormater.FormatAddress(communicateAddress.Area, var address = AddressFormater.FormatAddress(communicateAddress.Area,
communicateAddress.Address + allBytes - setCount); communicateAddress.Address + (int) localPos);
//找到对应的描述地址 //找到对应的描述地址
var addressUnit = var addressUnit =
GetAddresses.SingleOrDefault( GetAddresses.SingleOrDefault(
p => p =>
p.Area == communicateAddress.Area && p.Area == communicateAddress.Area &&
p.Address == communicateAddress.Address + allBytes - setCount); p.Address == communicateAddress.Address + (int) localPos &&
p.SubAddress == (int) ((localPos - (int) localPos)/0.125));
//如果没有相应地址,跳过 //如果没有相应地址,跳过
if (addressUnit == null) continue; if (addressUnit == null) continue;
//获取写入类型 //获取写入类型
@@ -381,7 +375,7 @@ namespace Modbus.Net
break; break;
} }
} }
setCount -= (int) BigEndianValueHelper.Instance.ByteLength[dataType.FullName]; setCount -= BigEndianValueHelper.Instance.ByteLength[dataType.FullName];
} }
//写入数据 //写入数据
await BaseUtility.SetDatasAsync(2, 0, addressStart, datasList.ToArray()); await BaseUtility.SetDatasAsync(2, 0, addressStart, datasList.ToArray());
@@ -469,6 +463,10 @@ namespace Modbus.Net
/// 数据类型 /// 数据类型
/// </summary> /// </summary>
public Type DataType { get; set; } public Type DataType { get; set; }
/// <summary>
/// 原始的地址
/// </summary>
public IEnumerable<AddressUnit> OriginalAddresses { get; set; }
} }
/// <summary> /// <summary>
@@ -509,6 +507,10 @@ namespace Modbus.Net
/// </summary> /// </summary>
public int Address { get; set; } public int Address { get; set; }
/// <summary> /// <summary>
/// bit位地址
/// </summary>
public int SubAddress { get; set; } = 0;
/// <summary>
/// 数据类型 /// 数据类型
/// </summary> /// </summary>
public Type DataType { get; set; } public Type DataType { get; set; }

View File

@@ -205,9 +205,10 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="pos"></param> /// <param name="pos"></param>
/// <param name="subPos"></param>
/// <param name="t"></param> /// <param name="t"></param>
/// <returns></returns> /// <returns></returns>
public virtual object GetValue(byte[] data, ref int pos, Type t) public virtual object GetValue(byte[] data, ref int pos, ref int subPos, Type t)
{ {
switch (t.FullName) switch (t.FullName)
{ {
@@ -256,6 +257,11 @@ namespace Modbus.Net
byte value = _Instance.GetByte(data, ref pos); byte value = _Instance.GetByte(data, ref pos);
return value; return value;
} }
case "System.Boolean":
{
bool value = Instance.GetBit(data, ref pos, ref subPos);
return value;
}
default: default:
{ {
throw new NotImplementedException("没有实现除整数以外的其它转换方式"); throw new NotImplementedException("没有实现除整数以外的其它转换方式");
@@ -399,6 +405,38 @@ namespace Modbus.Net
return t; return t;
} }
/// <summary>
/// 获取一个byte中相对应的bit数组展开中第n个位置中的bit元素。
/// </summary>
/// <param name="number">byte数字</param>
/// <param name="pos">bit数组中的对应位置</param>
/// <param name="subPos">小数位</param>
/// <returns>对应位置的bit元素</returns>
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 = 7;
while (i >= subPos)
{
ans = number % 2;
number /= 2;
i--;
}
subPos += 1;
if (subPos >= 8)
{
pos++;
subPos = 0;
}
return ans > 0;
}
public virtual bool GetBit(byte[] number, ref int pos, ref int subPos)
{
return GetBit(number[pos], ref pos, ref subPos);
}
/// <summary> /// <summary>
/// 将待转换的对象数组转换为需要发送的byte数组 /// 将待转换的对象数组转换为需要发送的byte数组
/// </summary> /// </summary>
@@ -538,6 +576,13 @@ namespace Modbus.Net
return ByteArrayToObjectArray(contents, new List<KeyValuePair<Type, int>>() {translateTypeAndCount}); return ByteArrayToObjectArray(contents, new List<KeyValuePair<Type, int>>() {translateTypeAndCount});
} }
public virtual T[] ByteArrayToDestinationArray<T>(byte[] contents, int getCount)
{
var objectArray = _Instance.ByteArrayToObjectArray(contents,
new KeyValuePair<Type, int>(typeof (T), getCount));
return _Instance.ObjectArrayToDestinationArray<T>(objectArray);
}
/// <summary> /// <summary>
/// 将byte数组转换为用户指定类型的数组通过object数组的方式返回用户需要再把object转换为自己需要的类型或调用ObjectArrayToDestinationArray返回单一类型的目标数组。 /// 将byte数组转换为用户指定类型的数组通过object数组的方式返回用户需要再把object转换为自己需要的类型或调用ObjectArrayToDestinationArray返回单一类型的目标数组。
/// </summary> /// </summary>
@@ -652,41 +697,14 @@ namespace Modbus.Net
return array; return array;
} }
/// <summary>
/// 获取一个byte中相对应的bit数组展开中第n个位置中的bit元素。
/// </summary>
/// <param name="number">byte数字</param>
/// <param name="pos">bit数组中的对应位置</param>
/// <returns>对应位置的bit元素</returns>
public bool GetBit(byte number, ref int pos)
{
if (pos < 0 && pos > 8) throw new IndexOutOfRangeException();
int ans = number % 2;
int i = 7;
while (i >= pos)
{
ans = number%2;
number /= 2;
i--;
}
pos += 1;
return ans > 0;
}
public virtual bool GetBit(byte[] number, ref int pos)
{
var tpos = pos%8;
return GetBit(number[pos++/8], ref tpos);
}
/// <summary> /// <summary>
/// 设置对应数字中相应位置的bit的值 /// 设置对应数字中相应位置的bit的值
/// </summary> /// </summary>
/// <param name="number">byte数子</param> /// <param name="number">byte数子</param>
/// <param name="pos">设置位置</param> /// <param name="subPos">设置位置</param>
/// <param name="setBit">设置bit大小true为1false为0</param> /// <param name="setBit">设置bit大小true为1false为0</param>
/// <returns></returns> /// <returns></returns>
public byte SetBit(byte number, int pos, bool setBit) public byte SetBit(byte number, int subPos, bool setBit)
{ {
int creation = 0; int creation = 0;
if (setBit) if (setBit)
@@ -694,7 +712,7 @@ namespace Modbus.Net
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
creation *= 2; creation *= 2;
if (i == pos) creation++; if (i == subPos) creation++;
} }
return (byte) (number | creation); return (byte) (number | creation);
} }
@@ -703,17 +721,16 @@ namespace Modbus.Net
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
creation *= 2; creation *= 2;
if (i != pos) creation++; if (i != subPos) creation++;
} }
return (byte) (number & creation); return (byte) (number & creation);
} }
} }
public virtual ushort SetBit(byte[] number, int pos, bool setBit) public virtual byte SetBit(byte[] number, int pos, int subPos, bool setBit)
{ {
SetBit(number[pos / 8], pos % 8, setBit); SetBit(number[pos], subPos, setBit);
var tpos = 0; return GetByte(number, ref pos);
return GetUShort(number, ref tpos);
} }
} }
@@ -836,10 +853,12 @@ namespace Modbus.Net
return t; return t;
} }
public override bool GetBit(byte[] number, ref int pos) public override bool GetBit(byte[] number, ref int pos, ref int subPos)
{ {
var tpos = pos % 8; var tpos = 7 - subPos;
return base.GetBit(number[number.Length - 1 - (pos++ / 8)], ref tpos); var bit = base.GetBit(number[pos], ref pos, ref tpos);
subPos = tpos - 7;
return bit;
} }
public override bool[] GetBits(byte[] data, ref int pos) public override bool[] GetBits(byte[] data, ref int pos)
@@ -855,10 +874,10 @@ namespace Modbus.Net
return t; return t;
} }
public override ushort SetBit(byte[] number, int pos, bool setBit) public override byte SetBit(byte[] number, int pos, int subPos, bool setBit)
{ {
Array.Reverse(number); Array.Reverse(number);
return base.SetBit(number, pos, setBit); return base.SetBit(number, pos, subPos, setBit);
} }
private Byte[] Reverse(Byte[] data) private Byte[] Reverse(Byte[] data)

View File

@@ -29,36 +29,37 @@ namespace NA200H.UI.WPF
private void GetUtilityEnter() private void GetUtilityEnter()
{ {
//utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.12"); utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.12");
//utility.AddressTranslator = new AddressTranslatorNA200H(); utility.AddressTranslator = new AddressTranslatorNA200H();
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW 1", new KeyValuePair<Type, int>(typeof(ushort), 4)); object[] getNum = utility.GetDatas(0x02, 0x00, "NW 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.11", SiemensMachineModel.S7_300); //utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.11", SiemensMachineModel.S7_300);
utility.AddressTranslator = new AddressTranslatorSiemens(); //utility.AddressTranslator = new AddressTranslatorSiemens();
object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4)); //object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = BigEndianValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum); ushort[] getNumUshorts = BigEndianValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
SetValue(getNumUshorts); SetValue(getNumUshorts);
} }
private void GetMachineEnter() private void GetMachineEnter()
{ {
//machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.12", new List<AddressUnit>() machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.12", new List<AddressUnit>()
//{
//new AddressUnit() {Id = 1, Area = "NW", Address = 1, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
//new AddressUnit() {Id = 2, Area = "NW", Address = 3, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
//new AddressUnit() {Id = 3, Area = "NW", Address = 5, CommunicationTag = "Add3", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
//new AddressUnit() {Id = 4, Area = "NW", Address = 7, CommunicationTag = "Ans", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}
//});
//machine.AddressFormater = new AddressFormaterNA200H();
//machine.AddressTranslator = new AddressTranslatorNA200H();
//machine.AddressCombiner = new AddressCombinerContinus();
machine = new SiemensMachine(SiemensType.Tcp, "192.168.3.11:102", SiemensMachineModel.S7_300, new List<AddressUnit>()
{ {
new AddressUnit() {Id = "1", Area = "V", Address = 0, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "1", Area = "MW", Address = 1, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
new AddressUnit() {Id = "2", Area = "V", Address = 2, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "2", Area = "MW", Address = 2, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
new AddressUnit() {Id = "3", Area = "V", Address = 4, CommunicationTag = "Add3", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "3", Area = "MW", Address = 3, CommunicationTag = "Add3", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
new AddressUnit() {Id = "4", Area = "V", Address = 6, CommunicationTag = "Ans", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0} new AddressUnit() {Id = "4", Area = "MW", Address = 4, CommunicationTag = "Ans", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
}); });
machine.AddressCombiner = new AddressCombinerContinus(); machine.AddressFormater = new AddressFormaterNA200H();
machine.AddressTranslator = new AddressTranslatorNA200H();
machine.AddressCombiner = new AddressCombinerContinus(machine.AddressTranslator);
machine.AddressCombinerSet = new AddressCombinerContinus(machine.AddressTranslator);
//machine = new SiemensMachine(SiemensType.Tcp, "192.168.3.11:102", SiemensMachineModel.S7_300, new List<AddressUnit>()
//{
//new AddressUnit() {Id = "1", Area = "V", Address = 0, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
//new AddressUnit() {Id = "2", Area = "V", Address = 2, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
//new AddressUnit() {Id = "3", Area = "V", Address = 4, CommunicationTag = "Add3", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
//new AddressUnit() {Id = "4", Area = "V", Address = 6, CommunicationTag = "Ans", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}
//});
//machine.AddressCombiner = new AddressCombinerContinus();
var result = machine.GetDatas(MachineGetDataType.CommunicationTag); var result = machine.GetDatas(MachineGetDataType.CommunicationTag);
var resultFormat = BaseMachine.MapGetValuesToSetValues(result); var resultFormat = BaseMachine.MapGetValuesToSetValues(result);
SetValue(new ushort[4] {(ushort)resultFormat["Add1"], (ushort)resultFormat["Add2"], (ushort)resultFormat["Add3"], (ushort)resultFormat["Ans"]}); SetValue(new ushort[4] {(ushort)resultFormat["Add1"], (ushort)resultFormat["Add2"], (ushort)resultFormat["Add3"], (ushort)resultFormat["Ans"]});
@@ -84,8 +85,8 @@ namespace NA200H.UI.WPF
ushort.TryParse(Add1.Text, out add1); ushort.TryParse(Add1.Text, out add1);
ushort.TryParse(Add2.Text, out add2); ushort.TryParse(Add2.Text, out add2);
ushort.TryParse(Add3.Text, out add3); ushort.TryParse(Add3.Text, out add3);
//utility.SetDatas(0x02, 0x00, "NW 1", new object[] { add1, add2, add3 }); utility.SetDatas(0x02, 0x00, "NW 1", new object[] { add1, add2, add3 });
utility.SetDatas(0x02, 0x00, "V 1", new object[] { add1, add2, add3 }); //utility.SetDatas(0x02, 0x00, "V 1", new object[] { add1, add2, add3 });
Thread.Sleep(100); Thread.Sleep(100);
GetUtilityEnter(); GetUtilityEnter();
} }