SetBit Support (not test)
This commit is contained in:
@@ -124,7 +124,7 @@ namespace Modbus.Net.Modbus
|
|||||||
var translateAddress = addressTranslator.AddressTranslate(startAddress, false);
|
var translateAddress = addressTranslator.AddressTranslate(startAddress, false);
|
||||||
FunctionCode = (byte)translateAddress.Area;
|
FunctionCode = (byte)translateAddress.Area;
|
||||||
StartAddress = (ushort)translateAddress.Address;
|
StartAddress = (ushort)translateAddress.Address;
|
||||||
WriteCount = (ushort)writeValue.Length;
|
WriteCount = (ushort)Math.Ceiling(writeValue.Length / 2.0);
|
||||||
WriteByteCount = 0;
|
WriteByteCount = 0;
|
||||||
WriteValue = writeValue;
|
WriteValue = writeValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
{
|
{
|
||||||
class ModbusRtuProtocalLinker : ComProtocalLinker
|
class ModbusRtuProtocalLinker : ComProtocalLinker
|
||||||
{
|
{
|
||||||
public override bool CheckRight(byte[] content)
|
public override bool? CheckRight(byte[] content)
|
||||||
{
|
{
|
||||||
if (!base.CheckRight(content)) return false;
|
if (!base.CheckRight(content).Value) return false;
|
||||||
//CRC校验失败
|
//CRC校验失败
|
||||||
if (!Crc16.GetInstance().CrcEfficacy(content))
|
if (!Crc16.GetInstance().CrcEfficacy(content))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
{
|
{
|
||||||
public class ModbusTcpProtocalLinker : TcpProtocalLinker
|
public class ModbusTcpProtocalLinker : TcpProtocalLinker
|
||||||
{
|
{
|
||||||
public override bool CheckRight(byte[] content)
|
public override bool? CheckRight(byte[] content)
|
||||||
{
|
{
|
||||||
if (!base.CheckRight(content)) return false;
|
if (!base.CheckRight(content).Value) return false;
|
||||||
//长度校验失败
|
//长度校验失败
|
||||||
if (content[5] != content.Length - 6)
|
if (content[5] != content.Length - 6)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ namespace Modbus.Net.Modbus
|
|||||||
{
|
{
|
||||||
private ModbusType _modbusType;
|
private ModbusType _modbusType;
|
||||||
|
|
||||||
|
public override bool GetLittleEndian => Wrapper[typeof (ReadDataModbusProtocal)].IsLittleEndian;
|
||||||
|
public override bool SetLittleEndian => Wrapper[typeof (WriteDataModbusProtocal)].IsLittleEndian;
|
||||||
|
|
||||||
protected string ConnectionStringIp
|
protected string ConnectionStringIp
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -94,7 +97,7 @@ namespace Modbus.Net.Modbus
|
|||||||
ModbusType = (ModbusType) connectionType;
|
ModbusType = (ModbusType) connectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<GetDataReturnDef> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
|
public override async Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -103,11 +106,7 @@ namespace Modbus.Net.Modbus
|
|||||||
var outputStruct = await
|
var outputStruct = await
|
||||||
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadDataModbusProtocal)], inputStruct) as
|
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadDataModbusProtocal)], inputStruct) as
|
||||||
ReadDataModbusOutputStruct;
|
ReadDataModbusOutputStruct;
|
||||||
return new GetDataReturnDef()
|
return outputStruct?.DataValue;
|
||||||
{
|
|
||||||
ReturnValue = outputStruct?.DataValue,
|
|
||||||
IsLittleEndian = Wrapper[typeof(ReadDataModbusProtocal)].IsLittleEndian,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,7 +95,13 @@ namespace Modbus.Net.OPC
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string tag = Encoding.UTF8.GetString(message);
|
var pos = 0;
|
||||||
|
var protocal = BigEndianValueHelper.Instance.GetByte(message, ref pos);
|
||||||
|
if (protocal == 0)
|
||||||
|
{
|
||||||
|
byte[] tagBytes = new byte[message.Length - 1];
|
||||||
|
Array.Copy(message, 1, tagBytes, 0, tagBytes.Length);
|
||||||
|
string tag = Encoding.UTF8.GetString(tagBytes);
|
||||||
var result = await _daClient.ReadAsync(tag);
|
var result = await _daClient.ReadAsync(tag);
|
||||||
if (result.QualityGood)
|
if (result.QualityGood)
|
||||||
{
|
{
|
||||||
@@ -106,13 +112,49 @@ namespace Modbus.Net.OPC
|
|||||||
return Encoding.ASCII.GetBytes("NoData");
|
return Encoding.ASCII.GetBytes("NoData");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 1; i < message.Length - 3; i++)
|
||||||
|
{
|
||||||
|
if (message[i] == 0x00 && message[i + 1] == 0xff && message[i + 2] == 0xff &&
|
||||||
|
message[i + 3] == 0x00)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int index2 = 0;
|
||||||
|
for (int i = index + 4; i < message.Length - 3; i++)
|
||||||
|
{
|
||||||
|
if (message[i] == 0x00 && message[i + 1] == 0xff && message[i + 2] == 0xff &&
|
||||||
|
message[i + 3] == 0x00)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
byte[] tagBytes = new byte[index - 1];
|
||||||
|
Array.Copy(message, 1, tagBytes, 0, tagBytes.Length);
|
||||||
|
string tag = Encoding.UTF8.GetString(tagBytes);
|
||||||
|
byte[] typeBytes = new byte[index2 - index - 4];
|
||||||
|
Array.Copy(message, index + 4, typeBytes, 0, typeBytes.Length);
|
||||||
|
Type type = Type.GetType(Encoding.UTF8.GetString(typeBytes));
|
||||||
|
byte[] valueBytes = new byte[message.Length - index2 - 4];
|
||||||
|
Array.Copy(message, index2 + 4, valueBytes, 0, valueBytes.Length);
|
||||||
|
int mainpos = 0, subpos = 0;
|
||||||
|
object value = BigEndianValueHelper.Instance.GetValue(valueBytes, ref mainpos, ref subpos, type);
|
||||||
|
await _daClient.WriteAsync(tag, value);
|
||||||
|
return new byte[] {1};
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
//AddInfo("opc client exception:" + e);
|
//AddInfo("opc client exception:" + e);
|
||||||
return Encoding.ASCII.GetBytes("NoData");
|
return Encoding.ASCII.GetBytes("NoData");
|
||||||
//return null;
|
//return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddInfo(string message)
|
private void AddInfo(string message)
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ namespace Modbus.Net.OPC
|
|||||||
_baseConnector = OpcDaConnector.Instance(host);
|
_baseConnector = OpcDaConnector.Instance(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CheckRight(byte[] content)
|
public override bool? CheckRight(byte[] content)
|
||||||
{
|
{
|
||||||
if (content != null && content.Length == 6 && Encoding.ASCII.GetString(content) == "NoData")
|
if (content != null && content.Length == 6 && Encoding.ASCII.GetString(content) == "NoData")
|
||||||
{
|
{
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
return base.CheckRight(content);
|
return base.CheckRight(content);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ namespace Modbus.Net.OPC
|
|||||||
{
|
{
|
||||||
public class OpcDaUtility : BaseUtility
|
public class OpcDaUtility : BaseUtility
|
||||||
{
|
{
|
||||||
|
public override bool GetLittleEndian => Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian;
|
||||||
|
public override bool SetLittleEndian => Wrapper[typeof (WriteRequestOpcProtocal)].IsLittleEndian;
|
||||||
|
|
||||||
public OpcDaUtility(string connectionString)
|
public OpcDaUtility(string connectionString)
|
||||||
{
|
{
|
||||||
ConnectionString = connectionString;
|
ConnectionString = connectionString;
|
||||||
@@ -19,19 +22,15 @@ namespace Modbus.Net.OPC
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<GetDataReturnDef> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
|
public override async Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var readRequestOpcInputStruct = new ReadRequestOpcInputStruct(startAddress, getByteCount);
|
var readRequestOpcInputStruct = new ReadRequestOpcInputStruct(startAddress);
|
||||||
var readRequestOpcOutputStruct =
|
var readRequestOpcOutputStruct =
|
||||||
await
|
await
|
||||||
Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestOpcProtocal)], readRequestOpcInputStruct) as ReadRequestOpcOutputStruct;
|
Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestOpcProtocal)], readRequestOpcInputStruct) as ReadRequestOpcOutputStruct;
|
||||||
return new GetDataReturnDef()
|
return readRequestOpcOutputStruct?.GetValue;
|
||||||
{
|
|
||||||
ReturnValue = readRequestOpcOutputStruct?.GetValue,
|
|
||||||
IsLittleEndian = Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@@ -39,9 +38,20 @@ namespace Modbus.Net.OPC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents)
|
public override async Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
try
|
||||||
|
{
|
||||||
|
var writeRequestOpcInputStruct = new WriteRequestOpcInputStruct(startAddress, setContents[0]);
|
||||||
|
var writeRequestOpcOutputStruct =
|
||||||
|
await
|
||||||
|
Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestOpcProtocal)], writeRequestOpcInputStruct) as WriteRequestOpcOutputStruct;
|
||||||
|
return writeRequestOpcOutputStruct?.WriteResult == true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,12 @@ namespace Modbus.Net.OPC
|
|||||||
|
|
||||||
public class ReadRequestOpcInputStruct : InputStruct
|
public class ReadRequestOpcInputStruct : InputStruct
|
||||||
{
|
{
|
||||||
public ReadRequestOpcInputStruct(string tag, int getCount)
|
public ReadRequestOpcInputStruct(string tag)
|
||||||
{
|
{
|
||||||
Tag = tag;
|
Tag = tag;
|
||||||
GetCount = getCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Tag { get; private set; }
|
public string Tag { get; private set; }
|
||||||
public int GetCount { get; private set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ReadRequestOpcOutputStruct : OutputStruct
|
public class ReadRequestOpcOutputStruct : OutputStruct
|
||||||
@@ -38,7 +36,7 @@ namespace Modbus.Net.OPC
|
|||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
{
|
{
|
||||||
var r_message = (ReadRequestOpcInputStruct) message;
|
var r_message = (ReadRequestOpcInputStruct) message;
|
||||||
return Format(Encoding.UTF8.GetBytes(r_message.Tag));
|
return Format((byte)0x00, Encoding.UTF8.GetBytes(r_message.Tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
|
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
|
||||||
@@ -47,77 +45,43 @@ namespace Modbus.Net.OPC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public class WriteRequestSiemensInputStruct : InputStruct
|
public class WriteRequestOpcInputStruct : InputStruct
|
||||||
{
|
{
|
||||||
public WriteRequestSiemensInputStruct(ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
|
public WriteRequestOpcInputStruct(string tag, object setValue)
|
||||||
{
|
{
|
||||||
PduRef = pduRef;
|
Tag = tag;
|
||||||
var address = addressTranslator.AddressTranslate(startAddress, true);
|
SetValue = setValue;
|
||||||
Offset = address.Key;
|
|
||||||
int area = address.Value;
|
|
||||||
Area = (byte)(area % 256);
|
|
||||||
DbBlock = Area == 0x84 ? (ushort)(area / 256) : (ushort)0;
|
|
||||||
WriteValue = writeValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ushort PduRef { get; private set; }
|
public string Tag { get; private set; }
|
||||||
public ushort DbBlock { get; private set; }
|
public object SetValue { get; private set; }
|
||||||
public byte Area { get; private set; }
|
|
||||||
public int Offset { get; private set; }
|
|
||||||
public object[] WriteValue { get; private set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WriteRequestSiemensOutputStruct : OutputStruct
|
public class WriteRequestOpcOutputStruct : OutputStruct
|
||||||
{
|
{
|
||||||
public WriteRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult)
|
public WriteRequestOpcOutputStruct(bool writeResult)
|
||||||
{
|
{
|
||||||
PduRef = pduRef;
|
WriteResult = writeResult;
|
||||||
AccessResult = accessResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ushort PduRef { get; private set; }
|
public bool WriteResult { get; private set; }
|
||||||
public SiemensAccessResult AccessResult { get; private set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WriteRequestSiemensProtocal : ProtocalUnit
|
public class WriteRequestOpcProtocal : ProtocalUnit
|
||||||
{
|
{
|
||||||
public override byte[] Format(InputStruct message)
|
public override byte[] Format(InputStruct message)
|
||||||
{
|
{
|
||||||
var r_message = (WriteRequestSiemensInputStruct)message;
|
var r_message = (WriteRequestOpcInputStruct)message;
|
||||||
byte[] valueBytes = BigEndianValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue);
|
byte[] tag = Encoding.UTF8.GetBytes(r_message.Tag);
|
||||||
const byte protoId = 0x32;
|
return Format((byte)0x00, tag, (int)0x00ffff00, r_message.SetValue.GetType().FullName, (int)0x00ffff00, r_message.SetValue);
|
||||||
const byte rosctr = 0x01;
|
|
||||||
const ushort redId = 0x0000;
|
|
||||||
ushort pduRef = r_message.PduRef;
|
|
||||||
const ushort parLg = 14; // 参数字节数(2+12的倍数),目前仅为14
|
|
||||||
ushort datLg = (ushort)(4 + valueBytes.Length); // 数据字节数
|
|
||||||
const byte serviceId = 0x05;
|
|
||||||
const byte numberOfVariables = 1;
|
|
||||||
const byte variableSpec = 0x12;
|
|
||||||
const byte vAddrLg = 0x0A;
|
|
||||||
const byte syntaxId = 0x10;
|
|
||||||
const byte typeR = (byte)SiemensTypeCode.Byte;
|
|
||||||
ushort numberOfElements = (ushort)valueBytes.Length;
|
|
||||||
ushort dbBlock = r_message.DbBlock;
|
|
||||||
byte area = r_message.Area;
|
|
||||||
int offsetBit = r_message.Offset * 8;
|
|
||||||
byte[] offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit);
|
|
||||||
const byte reserved = 0x00;
|
|
||||||
const byte type = (byte)SiemensDataType.OtherAccess;
|
|
||||||
ushort numberOfWriteBits = (ushort)(valueBytes.Length * 8);
|
|
||||||
return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
|
|
||||||
, variableSpec, vAddrLg, syntaxId, typeR, numberOfElements, dbBlock, area,
|
|
||||||
offsetBitBytes.Skip(1).ToArray(), reserved, type, numberOfWriteBits, valueBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
|
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
|
||||||
{
|
{
|
||||||
pos = 4;
|
var ansByte = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
|
||||||
ushort pduRef = BigEndianValueHelper.Instance.GetUShort(messageBytes, ref pos);
|
var ans = ansByte != 0;
|
||||||
pos = 14;
|
return new WriteRequestOpcOutputStruct(ans);
|
||||||
byte accessResult = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
|
}
|
||||||
return new WriteRequestSiemensOutputStruct(pduRef, (SiemensAccessResult)accessResult);
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ namespace Modbus.Net.Siemens
|
|||||||
{
|
{
|
||||||
public class SiemensTcpProtocalLinker : TcpProtocalLinker
|
public class SiemensTcpProtocalLinker : TcpProtocalLinker
|
||||||
{
|
{
|
||||||
public override bool CheckRight(byte[] content)
|
public override bool? CheckRight(byte[] content)
|
||||||
{
|
{
|
||||||
if (!base.CheckRight(content)) return false;
|
if (!base.CheckRight(content).Value) return false;
|
||||||
switch (content[5])
|
switch (content[5])
|
||||||
{
|
{
|
||||||
case 0xd0:
|
case 0xd0:
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ namespace Modbus.Net.Siemens
|
|||||||
private readonly ushort _maxCalled;
|
private readonly ushort _maxCalled;
|
||||||
private readonly ushort _maxPdu;
|
private readonly ushort _maxPdu;
|
||||||
|
|
||||||
|
public override bool GetLittleEndian => Wrapper[typeof (ReadRequestSiemensProtocal)].IsLittleEndian;
|
||||||
|
public override bool SetLittleEndian => Wrapper[typeof (WriteRequestSiemensProtocal)].IsLittleEndian;
|
||||||
|
|
||||||
protected string ConnectionStringIp
|
protected string ConnectionStringIp
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -148,7 +151,7 @@ namespace Modbus.Net.Siemens
|
|||||||
ConnectionType = (SiemensType) connectionType;
|
ConnectionType = (SiemensType) connectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<GetDataReturnDef> GetDatasAsync(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
|
public override async Task<byte[]> GetDatasAsync(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -157,11 +160,7 @@ namespace Modbus.Net.Siemens
|
|||||||
await
|
await
|
||||||
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadRequestSiemensProtocal)],
|
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadRequestSiemensProtocal)],
|
||||||
readRequestSiemensInputStruct) as ReadRequestSiemensOutputStruct;
|
readRequestSiemensInputStruct) as ReadRequestSiemensOutputStruct;
|
||||||
return new GetDataReturnDef()
|
return readRequestSiemensOutputStruct?.GetValue;
|
||||||
{
|
|
||||||
ReturnValue = readRequestSiemensOutputStruct?.GetValue,
|
|
||||||
IsLittleEndian = Wrapper[typeof (ReadRequestSiemensProtocal)].IsLittleEndian
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,12 @@ namespace Modbus.Net
|
|||||||
double getCount = 0;
|
double getCount = 0;
|
||||||
double byteCount = 0;
|
double byteCount = 0;
|
||||||
List<AddressUnit> originalAddresses = new List<AddressUnit>();
|
List<AddressUnit> originalAddresses = new List<AddressUnit>();
|
||||||
foreach (var address in groupedAddress.OrderBy(address => address.Address + address.SubAddress * (0.125 / AddressTranslator.GetAreaByteLength(address.Area))))
|
var orderedAddresses =
|
||||||
|
groupedAddress.OrderBy(
|
||||||
|
address =>
|
||||||
|
address.Address +
|
||||||
|
address.SubAddress*(0.125/AddressTranslator.GetAreaByteLength(address.Area)));
|
||||||
|
foreach (var address in orderedAddresses)
|
||||||
{
|
{
|
||||||
if (initNum < 0)
|
if (initNum < 0)
|
||||||
{
|
{
|
||||||
@@ -70,7 +75,7 @@ namespace Modbus.Net
|
|||||||
{
|
{
|
||||||
Area = area,
|
Area = area,
|
||||||
Address = (int) Math.Floor(initNum),
|
Address = (int) Math.Floor(initNum),
|
||||||
GetCount = (int) Math.Ceiling(byteCount),
|
GetCount = (int)Math.Ceiling(((int)Math.Floor(preNum) - (int)Math.Floor(initNum) + 1) * AddressTranslator.GetAreaByteLength(address.Area)),
|
||||||
DataType = typeof (byte),
|
DataType = typeof (byte),
|
||||||
OriginalAddresses = originalAddresses.ToList(),
|
OriginalAddresses = originalAddresses.ToList(),
|
||||||
});
|
});
|
||||||
@@ -96,7 +101,7 @@ namespace Modbus.Net
|
|||||||
{
|
{
|
||||||
Area = area,
|
Area = area,
|
||||||
Address = (int)Math.Floor(initNum),
|
Address = (int)Math.Floor(initNum),
|
||||||
GetCount = (int)Math.Ceiling(byteCount),
|
GetCount = (int)Math.Ceiling(((int)Math.Floor(preNum) - (int)Math.Floor(initNum) + 1) * AddressTranslator.GetAreaByteLength(area)),
|
||||||
DataType = typeof (byte),
|
DataType = typeof (byte),
|
||||||
OriginalAddresses = originalAddresses.ToList()
|
OriginalAddresses = originalAddresses.ToList()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ namespace Modbus.Net
|
|||||||
foreach (var communicateAddress in CommunicateAddresses)
|
foreach (var communicateAddress in CommunicateAddresses)
|
||||||
{
|
{
|
||||||
//获取数据
|
//获取数据
|
||||||
var datasReturn =
|
var datas =
|
||||||
await
|
await
|
||||||
BaseUtility.GetDatasAsync(2, 0,
|
BaseUtility.GetDatasAsync(2, 0,
|
||||||
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
|
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
|
||||||
@@ -169,30 +169,21 @@ namespace Modbus.Net
|
|||||||
BigEndianValueHelper.Instance.ByteLength[
|
BigEndianValueHelper.Instance.ByteLength[
|
||||||
communicateAddress.DataType.FullName]));
|
communicateAddress.DataType.FullName]));
|
||||||
|
|
||||||
byte[] datas;
|
|
||||||
|
|
||||||
//如果设备本身能获取到数据但是没有数据
|
|
||||||
if (datasReturn == null)
|
|
||||||
{
|
|
||||||
datas = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
datas = datasReturn.ReturnValue;
|
|
||||||
|
|
||||||
//如果没有数据,终止
|
//如果没有数据,终止
|
||||||
if (datas == null || datas.Length == 0 || datas.Length <
|
if (datas == null || (datas.Length != 0 && datas.Length <
|
||||||
(int)
|
(int)
|
||||||
Math.Ceiling(communicateAddress.GetCount*
|
Math.Ceiling(communicateAddress.GetCount*
|
||||||
BigEndianValueHelper.Instance.ByteLength[
|
BigEndianValueHelper.Instance.ByteLength[
|
||||||
communicateAddress.DataType.FullName]))
|
communicateAddress.DataType.FullName])))
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var address in communicateAddress.OriginalAddresses)
|
foreach (var address in communicateAddress.OriginalAddresses)
|
||||||
{
|
{
|
||||||
var localPos = (address.Address - communicateAddress.Address)*
|
var localPos = (address.Address - communicateAddress.Address)*
|
||||||
AddressTranslator.GetAreaByteLength(communicateAddress.Area)+address.SubAddress/8.0;
|
AddressTranslator.GetAreaByteLength(communicateAddress.Area) +
|
||||||
|
address.SubAddress/8.0;
|
||||||
var localMainPos = (int) localPos;
|
var localMainPos = (int) localPos;
|
||||||
var localSubPos = (int) ((localPos - localMainPos)*8);
|
var localSubPos = (int) ((localPos - localMainPos)*8);
|
||||||
|
|
||||||
@@ -216,7 +207,7 @@ namespace Modbus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (datas == null)
|
if (datas.Length == 0)
|
||||||
{
|
{
|
||||||
ans.Add(key, new ReturnUnit
|
ans.Add(key, new ReturnUnit
|
||||||
{
|
{
|
||||||
@@ -232,10 +223,12 @@ namespace Modbus.Net
|
|||||||
{
|
{
|
||||||
PlcValue =
|
PlcValue =
|
||||||
Convert.ToDouble(
|
Convert.ToDouble(
|
||||||
datasReturn.IsLittleEndian
|
BaseUtility.GetLittleEndian
|
||||||
? ValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos, address.DataType)
|
? ValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos,
|
||||||
|
address.DataType)
|
||||||
.ToString()
|
.ToString()
|
||||||
: BigEndianValueHelper.Instance.GetValue(datas, ref localMainPos, ref localSubPos,
|
: BigEndianValueHelper.Instance.GetValue(datas, ref localMainPos,
|
||||||
|
ref localSubPos,
|
||||||
address.DataType))*address.Zoom,
|
address.DataType))*address.Zoom,
|
||||||
UnitExtend = address.UnitExtend
|
UnitExtend = address.UnitExtend
|
||||||
});
|
});
|
||||||
@@ -303,7 +296,11 @@ namespace Modbus.Net
|
|||||||
case MachineSetDataType.Address:
|
case MachineSetDataType.Address:
|
||||||
{
|
{
|
||||||
address =
|
address =
|
||||||
GetAddresses.SingleOrDefault(p => AddressFormater.FormatAddress(p.Area, p.Address, p.SubAddress) == value.Key || (p.DataType != typeof(bool) && AddressFormater.FormatAddress(p.Area, p.Address) == value.Key));
|
GetAddresses.SingleOrDefault(
|
||||||
|
p =>
|
||||||
|
AddressFormater.FormatAddress(p.Area, p.Address, p.SubAddress) == value.Key ||
|
||||||
|
(p.DataType != typeof (bool) &&
|
||||||
|
AddressFormater.FormatAddress(p.Area, p.Address) == value.Key));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineSetDataType.CommunicationTag:
|
case MachineSetDataType.CommunicationTag:
|
||||||
@@ -324,42 +321,57 @@ namespace Modbus.Net
|
|||||||
}
|
}
|
||||||
addresses.Add(address);
|
addresses.Add(address);
|
||||||
}
|
}
|
||||||
//将地址编码成与实际设备通讯的地址,注意这个地址必须是连续的
|
//将地址编码成与实际设备通讯的地址
|
||||||
var communcationUnits = AddressCombinerSet.Combine(addresses);
|
var communcationUnits = AddressCombinerSet.Combine(addresses);
|
||||||
//遍历每条通讯的连续地址
|
//遍历每条通讯的连续地址
|
||||||
foreach (var communicateAddress in communcationUnits)
|
foreach (var communicateAddress in communcationUnits)
|
||||||
{
|
{
|
||||||
List<object> datasList = new List<object>();
|
|
||||||
//需要设置的字节数,计数
|
|
||||||
var setCount =
|
|
||||||
communicateAddress.GetCount*
|
|
||||||
BigEndianValueHelper.Instance.ByteLength[communicateAddress.DataType.FullName];
|
|
||||||
//总数
|
|
||||||
var allBytes = setCount;
|
|
||||||
//编码开始地址
|
//编码开始地址
|
||||||
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
|
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
|
||||||
communicateAddress.Address);
|
communicateAddress.Address);
|
||||||
|
|
||||||
while (setCount > 0)
|
var datasReturn = await BaseUtility.GetDatasAsync(2, 0,
|
||||||
|
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
|
||||||
|
(int)
|
||||||
|
Math.Ceiling(communicateAddress.GetCount*
|
||||||
|
BigEndianValueHelper.Instance.ByteLength[
|
||||||
|
communicateAddress.DataType.FullName]));
|
||||||
|
|
||||||
|
var valueHelper = BaseUtility.SetLittleEndian
|
||||||
|
? ValueHelper.Instance
|
||||||
|
: BigEndianValueHelper.Instance;
|
||||||
|
//如果设备本身能获取到数据但是没有数据
|
||||||
|
var datas = datasReturn;
|
||||||
|
|
||||||
|
//如果没有数据,终止
|
||||||
|
if (datas == null || datas.Length <
|
||||||
|
(int)
|
||||||
|
Math.Ceiling(communicateAddress.GetCount*
|
||||||
|
BigEndianValueHelper.Instance.ByteLength[
|
||||||
|
communicateAddress.DataType.FullName]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var addressUnit in communicateAddress.OriginalAddresses)
|
||||||
{
|
{
|
||||||
var localPos = (allBytes - setCount) / AddressTranslator.GetAreaByteLength(communicateAddress.Area);
|
var byteCount = (addressUnit.Address - communicateAddress.Address +
|
||||||
|
addressUnit.SubAddress*0.125/
|
||||||
|
AddressTranslator.GetAreaByteLength(communicateAddress.Area)) *
|
||||||
|
AddressTranslator.GetAreaByteLength(communicateAddress.Area);
|
||||||
|
var mainByteCount = (int) byteCount;
|
||||||
|
var localByteCount = (int) ((byteCount - (int) byteCount)*8);
|
||||||
|
|
||||||
|
var localPos = byteCount/AddressTranslator.GetAreaByteLength(communicateAddress.Area);
|
||||||
//编码当前地址
|
//编码当前地址
|
||||||
var subPos = (int)((localPos - (int)localPos) / (0.125 / AddressTranslator.GetAreaByteLength(communicateAddress.Area)));
|
var subPos =
|
||||||
|
(int)
|
||||||
|
((localPos - (int) localPos)/
|
||||||
|
(0.125/AddressTranslator.GetAreaByteLength(communicateAddress.Area)));
|
||||||
var address = AddressFormater.FormatAddress(communicateAddress.Area,
|
var address = AddressFormater.FormatAddress(communicateAddress.Area,
|
||||||
communicateAddress.Address + (int) localPos, subPos);
|
communicateAddress.Address + (int) localPos, subPos);
|
||||||
var address2 = subPos != 0
|
var address2 = subPos != 0
|
||||||
? null
|
? null
|
||||||
: AddressFormater.FormatAddress(communicateAddress.Area,
|
: AddressFormater.FormatAddress(communicateAddress.Area,
|
||||||
communicateAddress.Address + (int) localPos);
|
communicateAddress.Address + (int) localPos);
|
||||||
//找到对应的描述地址
|
|
||||||
var addressUnit =
|
|
||||||
GetAddresses.SingleOrDefault(
|
|
||||||
p =>
|
|
||||||
p.Area == communicateAddress.Area &&
|
|
||||||
p.Address == communicateAddress.Address + (int) localPos &&
|
|
||||||
p.SubAddress == subPos);
|
|
||||||
//如果没有相应地址,跳过
|
|
||||||
if (addressUnit == null) continue;
|
|
||||||
//获取写入类型
|
//获取写入类型
|
||||||
Type dataType = addressUnit.DataType;
|
Type dataType = addressUnit.DataType;
|
||||||
switch (setDataType)
|
switch (setDataType)
|
||||||
@@ -367,22 +379,31 @@ namespace Modbus.Net
|
|||||||
case MachineSetDataType.Address:
|
case MachineSetDataType.Address:
|
||||||
{
|
{
|
||||||
//获取要写入的值
|
//获取要写入的值
|
||||||
var value = values.SingleOrDefault(p => p.Key == address || (address2 != null && p.Key == address2));
|
var value =
|
||||||
|
values.SingleOrDefault(
|
||||||
|
p => p.Key == address || (address2 != null && p.Key == address2));
|
||||||
//将要写入的值加入队列
|
//将要写入的值加入队列
|
||||||
datasList.Add(Convert.ChangeType(value.Value / addressUnit.Zoom, dataType));
|
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
|
||||||
|
|
||||||
|
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachineSetDataType.CommunicationTag:
|
case MachineSetDataType.CommunicationTag:
|
||||||
{
|
{
|
||||||
var value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
|
var value = values.SingleOrDefault(p => p.Key == addressUnit.CommunicationTag);
|
||||||
datasList.Add(Convert.ChangeType(value.Value / addressUnit.Zoom, dataType));
|
var data = Convert.ChangeType(value.Value/addressUnit.Zoom, dataType);
|
||||||
|
if (!valueHelper.SetValue(datas, mainByteCount, localByteCount, data))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCount -= BigEndianValueHelper.Instance.ByteLength[dataType.FullName];
|
|
||||||
}
|
}
|
||||||
//写入数据
|
//写入数据
|
||||||
await BaseUtility.SetDatasAsync(2, 0, addressStart, datasList.ToArray());
|
await
|
||||||
|
BaseUtility.SetDatasAsync(2, 0, addressStart,
|
||||||
|
valueHelper.ByteArrayToObjectArray(datas,
|
||||||
|
new KeyValuePair<Type, int>(typeof (byte), datas.Length)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -5,12 +5,6 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Modbus.Net
|
namespace Modbus.Net
|
||||||
{
|
{
|
||||||
public class GetDataReturnDef
|
|
||||||
{
|
|
||||||
public byte[] ReturnValue { get; set; }
|
|
||||||
public bool IsLittleEndian { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class BaseUtility
|
public abstract class BaseUtility
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -19,6 +13,15 @@ namespace Modbus.Net
|
|||||||
protected BaseProtocal Wrapper;
|
protected BaseProtocal Wrapper;
|
||||||
protected string ConnectionString { get; set; }
|
protected string ConnectionString { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取协议是否遵循小端格式
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool GetLittleEndian { get; }
|
||||||
|
/// <summary>
|
||||||
|
/// 设置协议是否遵循小端格式
|
||||||
|
/// </summary>
|
||||||
|
public abstract bool SetLittleEndian { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备是否已经连接
|
/// 设备是否已经连接
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -56,7 +59,7 @@ namespace Modbus.Net
|
|||||||
/// <param name="startAddress">开始地址</param>
|
/// <param name="startAddress">开始地址</param>
|
||||||
/// <param name="getByteCount">获取字节数个数</param>
|
/// <param name="getByteCount">获取字节数个数</param>
|
||||||
/// <returns>接收到的byte数据</returns>
|
/// <returns>接收到的byte数据</returns>
|
||||||
public virtual GetDataReturnDef GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
|
public virtual byte[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
|
||||||
{
|
{
|
||||||
return AsyncHelper.RunSync(() => GetDatasAsync(belongAddress, masterAddress, startAddress, getByteCount));
|
return AsyncHelper.RunSync(() => GetDatasAsync(belongAddress, masterAddress, startAddress, getByteCount));
|
||||||
}
|
}
|
||||||
@@ -69,7 +72,7 @@ namespace Modbus.Net
|
|||||||
/// <param name="startAddress">开始地址</param>
|
/// <param name="startAddress">开始地址</param>
|
||||||
/// <param name="getByteCount">获取字节数个数</param>
|
/// <param name="getByteCount">获取字节数个数</param>
|
||||||
/// <returns>接收到的byte数据</returns>
|
/// <returns>接收到的byte数据</returns>
|
||||||
public abstract Task<GetDataReturnDef> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount);
|
public abstract Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取数据
|
/// 获取数据
|
||||||
@@ -102,8 +105,8 @@ namespace Modbus.Net
|
|||||||
double bCount = BigEndianValueHelper.Instance.ByteLength[typeName];
|
double bCount = BigEndianValueHelper.Instance.ByteLength[typeName];
|
||||||
var getReturnValue = await GetDatasAsync(belongAddress, masterAddress, startAddress,
|
var getReturnValue = await GetDatasAsync(belongAddress, masterAddress, startAddress,
|
||||||
(int)Math.Ceiling(bCount * getTypeAndCount.Value));
|
(int)Math.Ceiling(bCount * getTypeAndCount.Value));
|
||||||
var getBytes = getReturnValue.ReturnValue;
|
var getBytes = getReturnValue;
|
||||||
return getReturnValue.IsLittleEndian
|
return GetLittleEndian
|
||||||
? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount)
|
? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount)
|
||||||
: BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount);
|
: BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, getTypeAndCount);
|
||||||
}
|
}
|
||||||
@@ -187,8 +190,8 @@ namespace Modbus.Net
|
|||||||
let bCount = BigEndianValueHelper.Instance.ByteLength[typeName]
|
let bCount = BigEndianValueHelper.Instance.ByteLength[typeName]
|
||||||
select (int) Math.Ceiling(bCount*getTypeAndCount.Value)).Sum();
|
select (int) Math.Ceiling(bCount*getTypeAndCount.Value)).Sum();
|
||||||
var getReturnValue = await GetDatasAsync(belongAddress, masterAddress, startAddress, bAllCount);
|
var getReturnValue = await GetDatasAsync(belongAddress, masterAddress, startAddress, bAllCount);
|
||||||
byte[] getBytes = getReturnValue.ReturnValue;
|
byte[] getBytes = getReturnValue;
|
||||||
return getReturnValue.IsLittleEndian
|
return GetLittleEndian
|
||||||
? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount)
|
? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount)
|
||||||
: BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount);
|
: BigEndianValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace Modbus.Net
|
|||||||
{
|
{
|
||||||
byte[] extBytes = BytesExtend(content);
|
byte[] extBytes = BytesExtend(content);
|
||||||
byte[] receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
|
byte[] receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
|
||||||
return receiveBytes == null ? null : BytesDecact(receiveBytes);
|
return receiveBytes == null ? null : receiveBytes.Length == 0 ? receiveBytes : BytesDecact(receiveBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,7 +87,8 @@ namespace Modbus.Net
|
|||||||
//发送数据
|
//发送数据
|
||||||
byte[] receiveBytes = await _baseConnector.SendMsgAsync(content);
|
byte[] receiveBytes = await _baseConnector.SendMsgAsync(content);
|
||||||
//容错处理
|
//容错处理
|
||||||
return !CheckRight(receiveBytes) ? null : receiveBytes;
|
var checkRight = CheckRight(receiveBytes);
|
||||||
|
return checkRight == null ? new byte[0] : (!checkRight.Value ? null : receiveBytes);
|
||||||
//返回字符
|
//返回字符
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ namespace Modbus.Net
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="content">接收协议的内容</param>
|
/// <param name="content">接收协议的内容</param>
|
||||||
/// <returns>协议是否是正确的</returns>
|
/// <returns>协议是否是正确的</returns>
|
||||||
public virtual bool CheckRight(byte[] content)
|
public virtual bool? CheckRight(byte[] content)
|
||||||
{
|
{
|
||||||
if (content != null) return true;
|
if (content != null) return true;
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ namespace Modbus.Net
|
|||||||
}
|
}
|
||||||
case "System.Boolean":
|
case "System.Boolean":
|
||||||
{
|
{
|
||||||
bool value = Instance.GetBit(data, ref pos, ref subPos);
|
bool value = _Instance.GetBit(data, ref pos, ref subPos);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -414,7 +414,7 @@ namespace Modbus.Net
|
|||||||
/// <returns>对应位置的bit元素</returns>
|
/// <returns>对应位置的bit元素</returns>
|
||||||
public bool GetBit(byte number, ref int pos, ref int subPos)
|
public bool GetBit(byte number, ref int pos, ref int subPos)
|
||||||
{
|
{
|
||||||
if (subPos < 0 && subPos > 8) throw new IndexOutOfRangeException();
|
if (subPos < 0 && subPos >= 8) throw new IndexOutOfRangeException();
|
||||||
int ans = number % 2;
|
int ans = number % 2;
|
||||||
int i = 7;
|
int i = 7;
|
||||||
while (i >= subPos)
|
while (i >= subPos)
|
||||||
@@ -424,7 +424,7 @@ namespace Modbus.Net
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
subPos += 1;
|
subPos += 1;
|
||||||
if (subPos >= 8)
|
if (subPos < 0)
|
||||||
{
|
{
|
||||||
pos++;
|
pos++;
|
||||||
subPos = 0;
|
subPos = 0;
|
||||||
@@ -697,6 +697,90 @@ namespace Modbus.Net
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetValue(byte[] contents, int setPos, int subPos, object setValue)
|
||||||
|
{
|
||||||
|
var type = setValue.GetType();
|
||||||
|
|
||||||
|
switch (type.FullName)
|
||||||
|
{
|
||||||
|
case "System.Int16":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (short)setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.Int32":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (int) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.Int64":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (long) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.UInt16":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (ushort) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.UInt32":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (uint) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.UInt64":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (ulong) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.Single":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (float) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.Double":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (double) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.Byte":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetValue(contents, setPos, (byte) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
case "System.Boolean":
|
||||||
|
{
|
||||||
|
bool success = _Instance.SetBit(contents, setPos, subPos, (bool) setValue);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("没有实现除整数以外的其它转换方式");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将short值设置到byte数组中
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="contents">待设置的byte数组</param>
|
||||||
|
/// <param name="pos">设置的位置</param>
|
||||||
|
/// <param name="setValue">要设置的值</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual bool SetValue(byte[] contents, int pos, object setValue)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] datas = _Instance.GetBytes(setValue, setValue.GetType());
|
||||||
|
Array.Copy(datas, 0, contents, pos, datas.Length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置对应数字中相应位置的bit的值
|
/// 设置对应数字中相应位置的bit的值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -709,7 +793,7 @@ namespace Modbus.Net
|
|||||||
int creation = 0;
|
int creation = 0;
|
||||||
if (setBit)
|
if (setBit)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 7; i >= 0; i--)
|
||||||
{
|
{
|
||||||
creation *= 2;
|
creation *= 2;
|
||||||
if (i == subPos) creation++;
|
if (i == subPos) creation++;
|
||||||
@@ -718,7 +802,7 @@ namespace Modbus.Net
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 7; i >= 0; i--)
|
||||||
{
|
{
|
||||||
creation *= 2;
|
creation *= 2;
|
||||||
if (i != subPos) creation++;
|
if (i != subPos) creation++;
|
||||||
@@ -727,10 +811,25 @@ namespace Modbus.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual byte SetBit(byte[] number, int pos, int subPos, bool setBit)
|
/// <summary>
|
||||||
|
/// 设置一组数据中的一个bit
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="contents">待设置的字节数组</param>
|
||||||
|
/// <param name="pos">位置</param>
|
||||||
|
/// <param name="subPos">bit位置</param>
|
||||||
|
/// <param name="setValue">bit数</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual bool SetBit(byte[] contents, int pos, int subPos, bool setValue)
|
||||||
{
|
{
|
||||||
SetBit(number[pos], subPos, setBit);
|
try
|
||||||
return GetByte(number, ref pos);
|
{
|
||||||
|
contents[pos] = SetBit(contents[pos], subPos, setValue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,9 +954,16 @@ namespace Modbus.Net
|
|||||||
|
|
||||||
public override bool GetBit(byte[] number, ref int pos, ref int subPos)
|
public override bool GetBit(byte[] number, ref int pos, ref int subPos)
|
||||||
{
|
{
|
||||||
var tpos = 7 - subPos;
|
if (subPos < 0 && subPos > 7) throw new IndexOutOfRangeException();
|
||||||
var bit = base.GetBit(number[pos], ref pos, ref tpos);
|
var tspos = 7 - subPos;
|
||||||
subPos = tpos - 7;
|
var tpos = pos;
|
||||||
|
var bit = GetBit(number[pos], ref tpos, ref tspos);
|
||||||
|
subPos += 1;
|
||||||
|
if (subPos > 7)
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
subPos = 0;
|
||||||
|
}
|
||||||
return bit;
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,10 +980,9 @@ namespace Modbus.Net
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte SetBit(byte[] number, int pos, int subPos, bool setBit)
|
public override bool SetBit(byte[] number, int pos, int subPos, bool setBit)
|
||||||
{
|
{
|
||||||
Array.Reverse(number);
|
return base.SetBit(number, pos, 7 - subPos, setBit);
|
||||||
return base.SetBit(number, pos, subPos, setBit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Byte[] Reverse(Byte[] data)
|
private Byte[] Reverse(Byte[] data)
|
||||||
|
|||||||
Reference in New Issue
Block a user