Area Width Support (not complete)
This commit is contained in:
@@ -12,8 +12,8 @@ namespace Modbus.Net.Modbus
|
||||
public class AddressTranslatorNA200H : AddressTranslator
|
||||
{
|
||||
protected Dictionary<string, int> TransDictionary;
|
||||
protected Dictionary<string, int> ReadFunctionCodeDictionary;
|
||||
protected Dictionary<string, int> WriteFunctionCodeDictionary;
|
||||
protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
|
||||
protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
|
||||
|
||||
public AddressTranslatorNA200H()
|
||||
{
|
||||
@@ -30,27 +30,27 @@ namespace Modbus.Net.Modbus
|
||||
{"QW", 20000},
|
||||
{"NW", 21000},
|
||||
};
|
||||
ReadFunctionCodeDictionary = new Dictionary<string, int>
|
||||
ReadFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
|
||||
{
|
||||
{"Q", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
|
||||
{"M", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
|
||||
{"N", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
|
||||
{"I", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
|
||||
{"S", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
|
||||
{"IW", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
|
||||
{"SW", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
|
||||
{"MW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
|
||||
{"NW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
|
||||
{"QW", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
|
||||
{"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<string, int>
|
||||
WriteFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
|
||||
{
|
||||
{"Q", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
|
||||
{"M", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
|
||||
{"N", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
|
||||
{"MW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
|
||||
{"NW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
|
||||
{"QW", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
|
||||
{"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}},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,15 +63,20 @@ namespace Modbus.Net.Modbus
|
||||
return isRead
|
||||
? new AddressDef()
|
||||
{
|
||||
Area = ReadFunctionCodeDictionary[head],
|
||||
Area = ReadFunctionCodeDictionary[head].Code,
|
||||
Address = TransDictionary[head] + int.Parse(tail) - 1,
|
||||
}
|
||||
: new AddressDef()
|
||||
{
|
||||
Area = WriteFunctionCodeDictionary[head],
|
||||
Area = WriteFunctionCodeDictionary[head].Code,
|
||||
Address = TransDictionary[head] + int.Parse(tail) - 1,
|
||||
};
|
||||
}
|
||||
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return ReadFunctionCodeDictionary[area].AreaWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,22 +84,22 @@ namespace Modbus.Net.Modbus
|
||||
/// </summary>
|
||||
public class AddressTranslatorModbus : AddressTranslator
|
||||
{
|
||||
protected Dictionary<string, int> ReadFunctionCodeDictionary;
|
||||
protected Dictionary<string, int> WriteFunctionCodeDictionary;
|
||||
protected Dictionary<string, AreaOutputDef> ReadFunctionCodeDictionary;
|
||||
protected Dictionary<string, AreaOutputDef> WriteFunctionCodeDictionary;
|
||||
|
||||
public AddressTranslatorModbus()
|
||||
{
|
||||
ReadFunctionCodeDictionary = new Dictionary<string, int>
|
||||
ReadFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
|
||||
{
|
||||
{"0X", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
|
||||
{"1X", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
|
||||
{"3X", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
|
||||
{"4X", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
|
||||
{"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<string, int>
|
||||
WriteFunctionCodeDictionary = new Dictionary<string, AreaOutputDef>
|
||||
{
|
||||
{"0X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
|
||||
{"4X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
|
||||
{"0X", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil, AreaWidth = 0.125}},
|
||||
{"4X", new AreaOutputDef {Code = (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister, AreaWidth = 2}},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -107,14 +112,19 @@ namespace Modbus.Net.Modbus
|
||||
return isRead
|
||||
? new AddressDef()
|
||||
{
|
||||
Area = ReadFunctionCodeDictionary[head],
|
||||
Area = ReadFunctionCodeDictionary[head].Code,
|
||||
Address = int.Parse(tail) - 1,
|
||||
}
|
||||
: new AddressDef()
|
||||
{
|
||||
Area = WriteFunctionCodeDictionary[head],
|
||||
Area = WriteFunctionCodeDictionary[head].Code,
|
||||
Address = int.Parse(tail) - 1,
|
||||
};
|
||||
}
|
||||
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return ReadFunctionCodeDictionary[area].AreaWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ namespace Modbus.Net.Modbus
|
||||
{
|
||||
BaseUtility = new ModbusUtility(connectionType, connectionString);
|
||||
AddressFormater = new AddressFormaterModbus();
|
||||
AddressCombiner = new AddressCombinerContinus();
|
||||
AddressCombinerSet = new AddressCombinerContinus();
|
||||
AddressCombiner = new AddressCombinerContinus(AddressTranslator);
|
||||
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
|
||||
}
|
||||
|
||||
public ModbusMachine(ModbusType connectionType, string connectionString,
|
||||
|
||||
@@ -78,5 +78,10 @@ namespace Modbus.Net.Siemens
|
||||
Address = int.Parse(tail)
|
||||
};
|
||||
}
|
||||
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ namespace Modbus.Net.Siemens
|
||||
{
|
||||
BaseUtility = new SiemensUtility(connectionType, connectionString, model);
|
||||
AddressFormater = new AddressFormaterSiemens();
|
||||
AddressCombiner = new AddressCombinerContinus();
|
||||
AddressCombinerSet = new AddressCombinerContinus();
|
||||
AddressCombiner = new AddressCombinerContinus(AddressTranslator);
|
||||
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
|
||||
}
|
||||
|
||||
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
|
||||
@@ -340,6 +340,7 @@ namespace Modbus.Net.Siemens
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public class ReadTimeSiemensInputStruct : InputStruct
|
||||
{
|
||||
public ReadTimeSiemensInputStruct(ushort pduRef)
|
||||
@@ -415,6 +416,7 @@ namespace Modbus.Net.Siemens
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public class SiemensProtocalErrorException : ProtocalErrorException
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Modbus.Net.Siemens
|
||||
/*namespace Modbus.Net.Siemens
|
||||
{
|
||||
public struct TodClockStatus
|
||||
{
|
||||
@@ -88,3 +88,4 @@
|
||||
public ushort TodValue { get; set; }
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -22,6 +22,8 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public class AddressCombinerContinus : AddressCombiner
|
||||
{
|
||||
protected AddressTranslator AddressTranslator { get; set; }
|
||||
|
||||
public override IEnumerable<CommunicationUnit> Combine(IEnumerable<AddressUnit> addresses)
|
||||
{
|
||||
var groupedAddresses = from address in addresses
|
||||
@@ -33,34 +35,44 @@ namespace Modbus.Net
|
||||
foreach (var groupedAddress in groupedAddresses)
|
||||
{
|
||||
string area = groupedAddress.Key;
|
||||
int initNum = -1;
|
||||
int preNum = -1;
|
||||
double initNum = -1;
|
||||
double preNum = -1;
|
||||
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))
|
||||
{
|
||||
if (initNum < 0)
|
||||
{
|
||||
initNum = address.Address;
|
||||
getCount = (int) BigEndianValueHelper.Instance.ByteLength[address.DataType.FullName];
|
||||
initNum = address.Address + (address.SubAddress + 1) * 0.125;
|
||||
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 + BigEndianValueHelper.Instance.ByteLength[preType.FullName])
|
||||
if (address.Address > preNum + (int) (BigEndianValueHelper.Instance.ByteLength[preType.FullName] / AddressTranslator.GetAreaByteLength(address.Area)))
|
||||
{
|
||||
ans.Add(new CommunicationUnit()
|
||||
{
|
||||
Area = area,
|
||||
Address = initNum,
|
||||
GetCount = getCount,
|
||||
DataType = typeof (byte)
|
||||
Address = (int)Math.Floor(initNum),
|
||||
GetCount = (int)Math.Ceiling(byteCount),
|
||||
DataType = typeof (byte),
|
||||
OriginalAddresses = originalAddresses.ToList(),
|
||||
});
|
||||
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
|
||||
{
|
||||
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;
|
||||
@@ -69,13 +81,19 @@ namespace Modbus.Net
|
||||
ans.Add(new CommunicationUnit()
|
||||
{
|
||||
Area = area,
|
||||
Address = initNum,
|
||||
GetCount = getCount,
|
||||
DataType = typeof (byte)
|
||||
Address = (int)Math.Floor(initNum),
|
||||
GetCount = (int)Math.Ceiling(byteCount),
|
||||
DataType = typeof (byte),
|
||||
OriginalAddresses = originalAddresses.ToList()
|
||||
});
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
public AddressCombinerContinus(AddressTranslator addressTranslator)
|
||||
{
|
||||
AddressTranslator = addressTranslator;
|
||||
}
|
||||
}
|
||||
|
||||
public class AddressCombinerSingle : AddressCombiner
|
||||
@@ -90,7 +108,8 @@ namespace Modbus.Net
|
||||
Area = address.Area,
|
||||
Address = address.Address,
|
||||
DataType = address.DataType,
|
||||
GetCount = 1
|
||||
GetCount = 1,
|
||||
OriginalAddresses = new List<AddressUnit>() {address}
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
@@ -101,18 +120,18 @@ namespace Modbus.Net
|
||||
public int GapNumber { get; set; }
|
||||
}
|
||||
|
||||
public class AddressCombinerNumericJump : AddressCombiner
|
||||
public class AddressCombinerNumericJump : AddressCombinerContinus
|
||||
{
|
||||
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)
|
||||
{
|
||||
var continusAddresses = new AddressCombinerContinus().Combine(addresses).ToList();
|
||||
var continusAddresses = base.Combine(addresses).ToList();
|
||||
List<CommunicationUnitGap> addressesGaps = new List<CommunicationUnitGap>();
|
||||
CommunicationUnit preCommunicationUnit = null;
|
||||
foreach (var continusAddress in continusAddresses)
|
||||
@@ -127,7 +146,7 @@ namespace Modbus.Net
|
||||
var gap = new CommunicationUnitGap()
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -155,7 +174,8 @@ namespace Modbus.Net
|
||||
orderedGap.GapNumber +
|
||||
(int)
|
||||
(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);
|
||||
}
|
||||
@@ -163,13 +183,13 @@ namespace Modbus.Net
|
||||
}
|
||||
}
|
||||
|
||||
public class AddressCombinerPercentageJump : AddressCombiner
|
||||
public class AddressCombinerPercentageJump : AddressCombinerContinus
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -177,7 +197,7 @@ namespace Modbus.Net
|
||||
{
|
||||
var addressUnits = addresses as IList<AddressUnit> ?? addresses.ToList();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@ namespace Modbus.Net
|
||||
public int Address { get; set; }
|
||||
}
|
||||
|
||||
public class AreaOutputDef
|
||||
{
|
||||
public int Code { get; set; }
|
||||
public double AreaWidth { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 地址翻译器
|
||||
/// </summary>
|
||||
@@ -21,6 +27,8 @@ namespace Modbus.Net
|
||||
/// <param name="isRead">是否为读取,是为读取,否为写入</param>
|
||||
/// <returns>Key为转换后的地址,Value为辅助码</returns>
|
||||
public abstract AddressDef AddressTranslate(string address, bool isRead);
|
||||
|
||||
public abstract double GetAreaByteLength(string area);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,5 +51,10 @@ namespace Modbus.Net
|
||||
}
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
public override double GetAreaByteLength(string area)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,19 +185,17 @@ namespace Modbus.Net
|
||||
(int)
|
||||
Math.Ceiling(communicateAddress.GetCount *
|
||||
BigEndianValueHelper.Instance.ByteLength[
|
||||
communicateAddress.DataType.FullName])) return null;
|
||||
communicateAddress.DataType.FullName]))
|
||||
return null;
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
//解码数据
|
||||
while (pos < communicateAddress.GetCount)
|
||||
{
|
||||
//获取地址
|
||||
var address =
|
||||
GetAddresses.SingleOrDefault(
|
||||
p => p.Area == communicateAddress.Area && p.Address == pos + communicateAddress.Address);
|
||||
if (address != null)
|
||||
foreach (var address in communicateAddress.OriginalAddresses)
|
||||
{
|
||||
var localPos = ((address.Address - communicateAddress.Address)*8 + address.SubAddress)*
|
||||
AddressTranslator.GetAreaByteLength(communicateAddress.Area)/8.0;
|
||||
var localMainPos = (int) localPos;
|
||||
var localSubPos = (int) ((localPos - localMainPos)*8);
|
||||
|
||||
string key;
|
||||
switch (getDataType)
|
||||
{
|
||||
@@ -225,7 +223,6 @@ namespace Modbus.Net
|
||||
PlcValue = null,
|
||||
UnitExtend = address.UnitExtend
|
||||
});
|
||||
pos += (int)ValueHelper.Instance.ByteLength[address.DataType.ToString()];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -236,20 +233,15 @@ namespace Modbus.Net
|
||||
PlcValue =
|
||||
Double.Parse(
|
||||
datasReturn.IsLittleEndian
|
||||
? ValueHelper.Instance.GetValue(datas, ref pos, address.DataType)
|
||||
? ValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos, address.DataType)
|
||||
.ToString()
|
||||
: BigEndianValueHelper.Instance.GetValue(datas, ref pos,
|
||||
: BigEndianValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos,
|
||||
address.DataType)
|
||||
.ToString()) * address.Zoom,
|
||||
UnitExtend = address.UnitExtend
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//如果不保持连接,断开连接
|
||||
if (!KeepConnect)
|
||||
@@ -340,26 +332,28 @@ namespace Modbus.Net
|
||||
{
|
||||
List<object> datasList = new List<object>();
|
||||
//需要设置的字节数,计数
|
||||
var setCount = (int)
|
||||
Math.Ceiling(communicateAddress.GetCount*
|
||||
BigEndianValueHelper.Instance.ByteLength[
|
||||
communicateAddress.DataType.FullName]);
|
||||
var setCount =
|
||||
communicateAddress.GetCount*
|
||||
BigEndianValueHelper.Instance.ByteLength[communicateAddress.DataType.FullName];
|
||||
//总数
|
||||
var allBytes = setCount;
|
||||
//编码开始地址
|
||||
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
|
||||
communicateAddress.Address);
|
||||
while (setCount > 0)
|
||||
|
||||
while (setCount > 0.001)
|
||||
{
|
||||
var localPos = (allBytes - setCount) / AddressTranslator.GetAreaByteLength(communicateAddress.Area);
|
||||
//编码当前地址
|
||||
var address = AddressFormater.FormatAddress(communicateAddress.Area,
|
||||
communicateAddress.Address + allBytes - setCount);
|
||||
communicateAddress.Address + (int) localPos);
|
||||
//找到对应的描述地址
|
||||
var addressUnit =
|
||||
GetAddresses.SingleOrDefault(
|
||||
p =>
|
||||
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;
|
||||
//获取写入类型
|
||||
@@ -381,7 +375,7 @@ namespace Modbus.Net
|
||||
break;
|
||||
}
|
||||
}
|
||||
setCount -= (int) BigEndianValueHelper.Instance.ByteLength[dataType.FullName];
|
||||
setCount -= BigEndianValueHelper.Instance.ByteLength[dataType.FullName];
|
||||
}
|
||||
//写入数据
|
||||
await BaseUtility.SetDatasAsync(2, 0, addressStart, datasList.ToArray());
|
||||
@@ -469,6 +463,10 @@ namespace Modbus.Net
|
||||
/// 数据类型
|
||||
/// </summary>
|
||||
public Type DataType { get; set; }
|
||||
/// <summary>
|
||||
/// 原始的地址
|
||||
/// </summary>
|
||||
public IEnumerable<AddressUnit> OriginalAddresses { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -509,6 +507,10 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public int Address { get; set; }
|
||||
/// <summary>
|
||||
/// bit位地址
|
||||
/// </summary>
|
||||
public int SubAddress { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 数据类型
|
||||
/// </summary>
|
||||
public Type DataType { get; set; }
|
||||
|
||||
@@ -205,9 +205,10 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="subPos"></param>
|
||||
/// <param name="t"></param>
|
||||
/// <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)
|
||||
{
|
||||
@@ -256,6 +257,11 @@ namespace Modbus.Net
|
||||
byte value = _Instance.GetByte(data, ref pos);
|
||||
return value;
|
||||
}
|
||||
case "System.Boolean":
|
||||
{
|
||||
bool value = Instance.GetBit(data, ref pos, ref subPos);
|
||||
return value;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new NotImplementedException("没有实现除整数以外的其它转换方式");
|
||||
@@ -399,6 +405,38 @@ namespace Modbus.Net
|
||||
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>
|
||||
/// 将待转换的对象数组转换为需要发送的byte数组
|
||||
/// </summary>
|
||||
@@ -538,6 +576,13 @@ namespace Modbus.Net
|
||||
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>
|
||||
/// 将byte数组转换为用户指定类型的数组,通过object数组的方式返回,用户需要再把object转换为自己需要的类型,或调用ObjectArrayToDestinationArray返回单一类型的目标数组。
|
||||
/// </summary>
|
||||
@@ -652,41 +697,14 @@ namespace Modbus.Net
|
||||
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>
|
||||
/// 设置对应数字中相应位置的bit的值
|
||||
/// </summary>
|
||||
/// <param name="number">byte数子</param>
|
||||
/// <param name="pos">设置位置</param>
|
||||
/// <param name="subPos">设置位置</param>
|
||||
/// <param name="setBit">设置bit大小,true为1,false为0</param>
|
||||
/// <returns></returns>
|
||||
public byte SetBit(byte number, int pos, bool setBit)
|
||||
public byte SetBit(byte number, int subPos, bool setBit)
|
||||
{
|
||||
int creation = 0;
|
||||
if (setBit)
|
||||
@@ -694,7 +712,7 @@ namespace Modbus.Net
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
creation *= 2;
|
||||
if (i == pos) creation++;
|
||||
if (i == subPos) creation++;
|
||||
}
|
||||
return (byte) (number | creation);
|
||||
}
|
||||
@@ -703,17 +721,16 @@ namespace Modbus.Net
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
creation *= 2;
|
||||
if (i != pos) creation++;
|
||||
if (i != subPos) 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);
|
||||
var tpos = 0;
|
||||
return GetUShort(number, ref tpos);
|
||||
SetBit(number[pos], subPos, setBit);
|
||||
return GetByte(number, ref pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,10 +853,12 @@ namespace Modbus.Net
|
||||
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;
|
||||
return base.GetBit(number[number.Length - 1 - (pos++ / 8)], ref tpos);
|
||||
var tpos = 7 - subPos;
|
||||
var bit = base.GetBit(number[pos], ref pos, ref tpos);
|
||||
subPos = tpos - 7;
|
||||
return bit;
|
||||
}
|
||||
|
||||
public override bool[] GetBits(byte[] data, ref int pos)
|
||||
@@ -855,10 +874,10 @@ namespace Modbus.Net
|
||||
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);
|
||||
return base.SetBit(number, pos, setBit);
|
||||
return base.SetBit(number, pos, subPos, setBit);
|
||||
}
|
||||
|
||||
private Byte[] Reverse(Byte[] data)
|
||||
|
||||
@@ -29,36 +29,37 @@ namespace NA200H.UI.WPF
|
||||
|
||||
private void GetUtilityEnter()
|
||||
{
|
||||
//utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.12");
|
||||
//utility.AddressTranslator = new AddressTranslatorNA200H();
|
||||
//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.AddressTranslator = new AddressTranslatorSiemens();
|
||||
object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
|
||||
utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.12");
|
||||
utility.AddressTranslator = new AddressTranslatorNA200H();
|
||||
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.AddressTranslator = new AddressTranslatorSiemens();
|
||||
//object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
|
||||
ushort[] getNumUshorts = BigEndianValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
|
||||
SetValue(getNumUshorts);
|
||||
}
|
||||
|
||||
private void GetMachineEnter()
|
||||
{
|
||||
//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>()
|
||||
machine = new ModbusMachine(ModbusType.Tcp, "192.168.3.12", 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}
|
||||
new AddressUnit() {Id = "1", Area = "MW", Address = 1, CommunicationTag = "Add1", 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 = "MW", Address = 3, CommunicationTag = "Add3", 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 resultFormat = BaseMachine.MapGetValuesToSetValues(result);
|
||||
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(Add2.Text, out add2);
|
||||
ushort.TryParse(Add3.Text, out 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, "NW 1", new object[] { add1, add2, add3 });
|
||||
//utility.SetDatas(0x02, 0x00, "V 1", new object[] { add1, add2, add3 });
|
||||
Thread.Sleep(100);
|
||||
GetUtilityEnter();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user