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
{
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;
}
}
}

View File

@@ -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,

View File

@@ -78,5 +78,10 @@ namespace Modbus.Net.Siemens
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);
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,

View File

@@ -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
{

View File

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

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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; }

View File

@@ -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为1false为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)

View File

@@ -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();
}