DeviceId Change Support

This commit is contained in:
罗圣
2016-09-01 15:16:31 +08:00
parent a465d5b6ea
commit 0f0da2d585
22 changed files with 222 additions and 146 deletions

View File

@@ -17,7 +17,7 @@ namespace CrossLampControl.WebApi.Controllers
public CrossLampController()
{
_utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.241", SiemensMachineModel.S7_200);
_utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.241", SiemensMachineModel.S7_200, 2, 0);
_utility.AddressTranslator = new AddressTranslatorSiemens();
}
@@ -25,7 +25,7 @@ namespace CrossLampControl.WebApi.Controllers
public Lamp GetLamp()
{
Lamp light = new Lamp();
object[] lampsbyte = _utility.GetDatas(2, 0, "Q 0", new KeyValuePair<Type, int>(typeof(bool), 7));
object[] lampsbyte = _utility.GetDatas("Q 0", new KeyValuePair<Type, int>(typeof(bool), 7));
bool[] lamps =
BigEndianValueHelper.Instance.ObjectArrayToDestinationArray<bool>(
lampsbyte);

View File

@@ -11,11 +11,11 @@ namespace Modbus.Net.Modbus
/// </summary>
public class ModbusAsciiProtocal : ModbusProtocal
{
public ModbusAsciiProtocal() : this(ConfigurationManager.COM)
public ModbusAsciiProtocal(byte belongAddress, byte masterAddress) : this(ConfigurationManager.COM, belongAddress, masterAddress)
{
}
public ModbusAsciiProtocal(string com)
public ModbusAsciiProtocal(string com, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ProtocalLinker = new ModbusAsciiProtocalLinker(com);
}

View File

@@ -5,17 +5,20 @@ namespace Modbus.Net.Modbus
public class ModbusMachine : BaseMachine
{
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(getAddresses, keepConnect)
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress)
: base(getAddresses, keepConnect)
{
BaseUtility = new ModbusUtility(connectionType, connectionString);
BaseUtility = new ModbusUtility(connectionType, connectionString, slaveAddress, masterAddress);
SlaveAddress = slaveAddress;
MasterAddress = masterAddress;
AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
}
public ModbusMachine(ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses)
: this(connectionType, connectionString, getAddresses, false)
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress)
: this(connectionType, connectionString, getAddresses, false, slaveAddress, masterAddress)
{
}
}

View File

@@ -50,6 +50,10 @@ namespace Modbus.Net.Modbus
{
return await ProtocalLinker.ConnectAsync();
}
protected ModbusProtocal(byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
}
}
#region PLC数据

View File

@@ -5,11 +5,11 @@
/// </summary>
public class ModbusRtuProtocal : ModbusProtocal
{
public ModbusRtuProtocal() : this(ConfigurationManager.COM)
public ModbusRtuProtocal(byte belongAddress, byte masterAddress) : this(ConfigurationManager.COM, belongAddress, masterAddress)
{
}
public ModbusRtuProtocal(string com)
public ModbusRtuProtocal(string com, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ProtocalLinker = new ModbusRtuProtocalLinker(com);
}

View File

@@ -5,16 +5,16 @@
/// </summary>
public class ModbusTcpProtocal : ModbusProtocal
{
public ModbusTcpProtocal() : this(ConfigurationManager.IP)
public ModbusTcpProtocal(byte belongAddress, byte masterAddress) : this(ConfigurationManager.IP, belongAddress, masterAddress)
{
}
public ModbusTcpProtocal(string ip)
public ModbusTcpProtocal(string ip, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ProtocalLinker = new ModbusTcpProtocalLinker(ip);
}
public ModbusTcpProtocal(string ip, int port)
public ModbusTcpProtocal(string ip, int port, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ProtocalLinker = new ModbusTcpProtocalLinker(ip, port);
}

View File

@@ -70,31 +70,31 @@ namespace Modbus.Net.Modbus
{
case ModbusType.Rtu:
{
Wrapper = ConnectionString == null ? new ModbusRtuProtocal() : new ModbusRtuProtocal(ConnectionString);
Wrapper = ConnectionString == null ? new ModbusRtuProtocal(BelongAddress, MasterAddress) : new ModbusRtuProtocal(ConnectionString, BelongAddress, MasterAddress);
break;
}
case ModbusType.Tcp:
{
Wrapper = ConnectionString == null ? new ModbusTcpProtocal() : (ConnectionStringPort == null ? new ModbusTcpProtocal(ConnectionString) : new ModbusTcpProtocal(ConnectionStringIp,ConnectionStringPort.Value));
Wrapper = ConnectionString == null ? new ModbusTcpProtocal(BelongAddress, MasterAddress) : (ConnectionStringPort == null ? new ModbusTcpProtocal(ConnectionString, BelongAddress, MasterAddress) : new ModbusTcpProtocal(ConnectionStringIp,ConnectionStringPort.Value, BelongAddress, MasterAddress));
break;
}
case ModbusType.Ascii:
{
Wrapper = ConnectionString == null ? new ModbusAsciiProtocal() : new ModbusAsciiProtocal(ConnectionString);
Wrapper = ConnectionString == null ? new ModbusAsciiProtocal(BelongAddress, MasterAddress) : new ModbusAsciiProtocal(ConnectionString, BelongAddress, MasterAddress);
break;
}
}
}
}
public ModbusUtility(int connectionType)
public ModbusUtility(int connectionType, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ConnectionString = null;
ModbusType = (ModbusType)connectionType;
AddressTranslator = new AddressTranslatorModbus();
}
public ModbusUtility(ModbusType connectionType, string connectionString)
public ModbusUtility(ModbusType connectionType, string connectionString, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ConnectionString = connectionString;
ModbusType = connectionType;
@@ -106,11 +106,11 @@ namespace Modbus.Net.Modbus
ModbusType = (ModbusType) connectionType;
}
public override async Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
public override async Task<byte[]> GetDatasAsync(string startAddress, int getByteCount)
{
try
{
var inputStruct = new ReadDataModbusInputStruct(belongAddress, startAddress,
var inputStruct = new ReadDataModbusInputStruct(BelongAddress, startAddress,
getByteCount%2 == 0 ? (ushort) (getByteCount/2) : (ushort) (getByteCount/2 + 1), AddressTranslator);
var outputStruct = await
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadDataModbusProtocal)], inputStruct) as
@@ -123,11 +123,11 @@ namespace Modbus.Net.Modbus
}
}
public override async Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents)
public override async Task<bool> SetDatasAsync(string startAddress, object[] setContents)
{
try
{
var inputStruct = new WriteDataModbusInputStruct(belongAddress, startAddress, setContents,
var inputStruct = new WriteDataModbusInputStruct(BelongAddress, startAddress, setContents,
AddressTranslator);
var outputStruct = await
Wrapper.SendReceiveAsync(Wrapper[typeof (WriteDataModbusProtocal)], inputStruct) as
@@ -141,11 +141,11 @@ namespace Modbus.Net.Modbus
}
/*
public override DateTime GetTime(byte belongAddress)
public override DateTime GetTime()
{
try
{
var inputStruct = new GetSystemTimeModbusInputStruct(belongAddress);
var inputStruct = new GetSystemTimeModbusInputStruct(BelongAddress);
var outputStruct =
Wrapper.SendReceive(Wrapper[typeof(GetSystemTimeModbusProtocal)], inputStruct) as
GetSystemTimeModbusOutputStruct;
@@ -157,11 +157,11 @@ namespace Modbus.Net.Modbus
}
}
public override bool SetTime(byte belongAddress, DateTime setTime)
public override bool SetTime(DateTime setTime)
{
try
{
var inputStruct = new SetSystemTimeModbusInputStruct(belongAddress, setTime);
var inputStruct = new SetSystemTimeModbusInputStruct(BelongAddress, setTime);
var outputStruct =
Wrapper.SendReceive(Wrapper[typeof(SetSystemTimeModbusProtocal)], inputStruct) as
SetSystemTimeModbusOutputStruct;

View File

@@ -11,7 +11,7 @@ namespace Modbus.Net.OPC
public override bool GetLittleEndian => Wrapper[typeof (ReadRequestOpcProtocal)].IsLittleEndian;
public override bool SetLittleEndian => Wrapper[typeof (WriteRequestOpcProtocal)].IsLittleEndian;
public OpcDaUtility(string connectionString)
public OpcDaUtility(string connectionString) : base(0,0)
{
ConnectionString = connectionString;
AddressTranslator = null;
@@ -22,7 +22,7 @@ namespace Modbus.Net.OPC
{
}
public override async Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
public override async Task<byte[]> GetDatasAsync(string startAddress, int getByteCount)
{
try
{
@@ -38,7 +38,7 @@ namespace Modbus.Net.OPC
}
}
public override async Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents)
public override async Task<bool> SetDatasAsync(string startAddress, object[] setContents)
{
try
{

View File

@@ -8,7 +8,9 @@ namespace Modbus.Net.OPC
{
public abstract class OpcProtocal : BaseProtocal
{
protected OpcProtocal() : base(0, 0)
{
}
}
public class ReadRequestOpcInputStruct : InputStruct

View File

@@ -5,17 +5,18 @@ namespace Modbus.Net.Siemens
public class SiemensMachine : BaseMachine
{
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(getAddresses, keepConnect)
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress)
: base(getAddresses, keepConnect, slaveAddress, masterAddress)
{
BaseUtility = new SiemensUtility(connectionType, connectionString, model);
BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress);
AddressFormater = new AddressFormaterSiemens();
AddressCombiner = new AddressCombinerContinus(AddressTranslator);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator);
}
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses)
: this(connectionType, connectionString, model, getAddresses, false)
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress)
: this(connectionType, connectionString, model, getAddresses, false, slaveAddress, masterAddress)
{
}
}

View File

@@ -9,16 +9,14 @@ namespace Modbus.Net.Siemens
public class SiemensPpiProtocal : SiemensProtocal
{
private readonly string _com;
private int _connectTryCount;
public SiemensPpiProtocal() : this( ConfigurationManager.COM)
public SiemensPpiProtocal(byte belongAddress, byte masterAddress) : this( ConfigurationManager.COM, belongAddress, masterAddress)
{
}
public SiemensPpiProtocal(string com)
public SiemensPpiProtocal(string com, byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
_com = com;
_connectTryCount = 0;
}
public override byte[] SendReceive(bool isLittleEndian, params object[] content)
@@ -26,15 +24,6 @@ namespace Modbus.Net.Siemens
return AsyncHelper.RunSync(() => SendReceiveAsync(isLittleEndian, content));
}
public override async Task<byte[]> SendReceiveAsync(bool isLittleEndian, params object[] content)
{
if (ProtocalLinker == null || !ProtocalLinker.IsConnected)
{
await ConnectAsync();
}
return await base.SendReceiveAsync(isLittleEndian, content);
}
private async Task<OutputStruct> ForceSendReceiveAsync(ProtocalUnit unit, InputStruct content)
{
return await base.SendReceiveAsync(unit, content);
@@ -42,13 +31,13 @@ namespace Modbus.Net.Siemens
public override bool Connect()
{
return AsyncHelper.RunSync(ConnectAsync);
return AsyncHelper.RunSync(()=>ConnectAsync());
}
public override async Task<bool> ConnectAsync()
{
ProtocalLinker = new SiemensPpiProtocalLinker(_com);
var inputStruct = new ComCreateReferenceSiemensInputStruct();
var inputStruct = new ComCreateReferenceSiemensInputStruct(BelongAddress, MasterAddress);
var outputStruct =
await await
ForceSendReceiveAsync(this[typeof (ComCreateReferenceSiemensProtocal)],
@@ -56,11 +45,11 @@ namespace Modbus.Net.Siemens
ContinueWith(async answer =>
{
if (!ProtocalLinker.IsConnected) return false;
var inputStruct2 = new ComEstablishAssociationSiemensInputStruct();
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(BelongAddress, MasterAddress);
var outputStruct2 =
(ComConfirmSiemensOutputStruct)
(ComConfirmMessageSiemensOutputStruct)
await
ForceSendReceiveAsync(this[typeof(ComEstablishAssociationSiemensProtocal)],
ForceSendReceiveAsync(this[typeof(ComConfirmMessageSiemensProtocal)],
inputStruct2);
return outputStruct2 != null;
});

View File

@@ -16,31 +16,47 @@ namespace Modbus.Net.Siemens
byte[] extBytes = BytesExtend(content);
if (extBytes[6] == 0x7c)
{
var inputStruct2 = new ComEstablishAssociationSiemensInputStruct();
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(content[4], content[5]);
var receiveBytes2 =
await SendReceiveWithoutExtAndDecAsync(
new ComEstablishAssociationSiemensProtocal().Format(inputStruct2));
new ComConfirmMessageSiemensProtocal().Format(inputStruct2));
}
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
while (receiveBytes.Length == 1 && receiveBytes[0] == 0xf9)
{
Thread.Sleep(500);
var inputStruct2 = new ComEstablishAssociationSiemensInputStruct();
receiveBytes =
await SendReceiveWithoutExtAndDecAsync(
new ComEstablishAssociationSiemensProtocal().Format(inputStruct2));
}
if (content.Length > 6 && receiveBytes.Length == 1 && receiveBytes[0] == 0xe5)
{
var inputStruct2 = new ComEstablishAssociationSiemensInputStruct();
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(content[4], content[5]);
var receiveBytes2 =
await SendReceiveWithoutExtAndDecAsync(
new ComEstablishAssociationSiemensProtocal().Format(inputStruct2));
new ComConfirmMessageSiemensProtocal().Format(inputStruct2));
return BytesDecact(receiveBytes2);
}
return BytesDecact(receiveBytes);
}
public override async Task<byte[]> SendReceiveWithoutExtAndDecAsync(byte[] content)
{
var ans = await base.SendReceiveWithoutExtAndDecAsync(content);
while (ans.Length == 1 && ans[0] == 0xf9)
{
Thread.Sleep(500);
if (content.Length <= 6)
{
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(content[1], content[2]);
ans =
await SendReceiveWithoutExtAndDecAsync(
new ComConfirmMessageSiemensProtocal().Format(inputStruct2));
}
else
{
var inputStruct2 = new ComConfirmMessageSiemensInputStruct(content[4], content[5]);
ans =
await SendReceiveWithoutExtAndDecAsync(
new ComConfirmMessageSiemensProtocal().Format(inputStruct2));
}
}
return ans;
}
public override bool? CheckRight(byte[] content)
{
if (!base.CheckRight(content).Value) return false;

View File

@@ -34,17 +34,35 @@ namespace Modbus.Net.Siemens
public abstract class SiemensProtocal : BaseProtocal
{
protected SiemensProtocal(byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
}
}
internal class ComCreateReferenceSiemensInputStruct : InputStruct
{
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
public ComCreateReferenceSiemensInputStruct(byte belongAddress, byte masterAddress)
{
BelongAddress = belongAddress;
MasterAddress = masterAddress;
}
}
internal class ComCreateReferenceSiemensOutputStruct : OutputStruct
{
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
public byte ConfirmMessage { get; set; }
public ComCreateReferenceSiemensOutputStruct(byte belongAddress, byte masterAddress, byte confirmMessage)
{
BelongAddress = belongAddress;
MasterAddress = masterAddress;
ConfirmMessage = confirmMessage;
}
}
internal class ComCreateReferenceSiemensProtocal : SpecialProtocalUnit
@@ -52,12 +70,17 @@ namespace Modbus.Net.Siemens
public override byte[] Format(InputStruct message)
{
var r_message = (ComCreateReferenceSiemensInputStruct) message;
return Format((byte)0x10, (byte)0x02, (byte)0x00, (byte)0x49, (byte)0x4B, (byte)0x16);
var crc = (r_message.BelongAddress + r_message.MasterAddress + 0x49)%256;
return Format((byte)0x10, r_message.BelongAddress, r_message.MasterAddress, (byte)0x49, (byte)crc, (byte)0x16);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
return new ComCreateReferenceSiemensOutputStruct();
pos = 1;
var masterAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var belongAddress = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
var confirmMessage = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
return new ComCreateReferenceSiemensOutputStruct(belongAddress, masterAddress, confirmMessage);
}
}
@@ -143,13 +166,21 @@ namespace Modbus.Net.Siemens
}
}
internal class ComEstablishAssociationSiemensInputStruct : InputStruct
public class ComConfirmMessageSiemensInputStruct : InputStruct
{
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
public ComConfirmMessageSiemensInputStruct(byte belongAddress, byte masterAddress)
{
BelongAddress = belongAddress;
MasterAddress = masterAddress;
}
}
internal class ComConfirmSiemensOutputStruct : OutputStruct
public class ComConfirmMessageSiemensOutputStruct : OutputStruct
{
public ComConfirmSiemensOutputStruct(byte confirmByte)
public ComConfirmMessageSiemensOutputStruct(byte confirmByte)
{
ConfirmByte = confirmByte;
}
@@ -157,21 +188,19 @@ namespace Modbus.Net.Siemens
public byte ConfirmByte { get; set; }
}
internal class ComEstablishAssociationSiemensProtocal : SpecialProtocalUnit
public class ComConfirmMessageSiemensProtocal : SpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ComEstablishAssociationSiemensInputStruct)message;
return Format((byte)0x10, (byte)0x02, (byte)0x00, (byte)0x5c, (byte)0x5e, (byte)0x16);
var r_message = (ComConfirmMessageSiemensInputStruct)message;
var crc = r_message.BelongAddress + r_message.MasterAddress + 0x5c%256;
return Format((byte)0x10, r_message.BelongAddress, r_message.MasterAddress, (byte)0x5c, (byte)crc, (byte)0x16);
}
public override OutputStruct Unformat(byte[] messageBytes, ref int pos)
{
//if (messageBytes.Length == 1)
//{
var confirmByte = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
return new ComConfirmSiemensOutputStruct(confirmByte);
//}
var confirmByte = BigEndianValueHelper.Instance.GetByte(messageBytes, ref pos);
return new ComConfirmMessageSiemensOutputStruct(confirmByte);
}
}
@@ -241,8 +270,10 @@ namespace Modbus.Net.Siemens
public class ReadRequestSiemensInputStruct : InputStruct
{
public ReadRequestSiemensInputStruct(ushort pduRef, SiemensTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator)
public ReadRequestSiemensInputStruct(byte belongAddress, byte masterAddress, ushort pduRef, SiemensTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
MasterAddress = masterAddress;
PduRef = pduRef;
TypeCode = (byte) getType;
var address = addressTranslator.AddressTranslate(startAddress, true);
@@ -253,6 +284,8 @@ namespace Modbus.Net.Siemens
NumberOfElements = getCount;
}
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
public ushort PduRef { get; private set; }
public byte TypeCode { get; private set; }
public ushort NumberOfElements { get; private set; }
@@ -284,6 +317,8 @@ namespace Modbus.Net.Siemens
public override byte[] Format(InputStruct message)
{
var r_message = (ReadRequestSiemensInputStruct) message;
byte belongAddress = r_message.BelongAddress;
byte masterAddress = r_message.MasterAddress;
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
@@ -301,7 +336,7 @@ namespace Modbus.Net.Siemens
byte area = r_message.Area;
int offsetBit = r_message.Offset*8;
byte[] offsetBitBytes = BigEndianValueHelper.Instance.GetBytes(offsetBit);
return Format(new byte[6], (byte)0x6c, protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
return Format(new byte[4], belongAddress, masterAddress, (byte)0x6c, protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
, variableSpec, vAddrLg, syntaxId, type, numberOfElements, dbBlock, area,
offsetBitBytes.Skip(1).ToArray());
}
@@ -324,8 +359,10 @@ namespace Modbus.Net.Siemens
public class WriteRequestSiemensInputStruct : InputStruct
{
public WriteRequestSiemensInputStruct(ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
public WriteRequestSiemensInputStruct(byte belongAddress, byte masterAddress, ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
{
BelongAddress = belongAddress;
MasterAddress = masterAddress;
PduRef = pduRef;
var address = addressTranslator.AddressTranslate(startAddress, true);
Offset = address.Address;
@@ -335,6 +372,8 @@ namespace Modbus.Net.Siemens
WriteValue = writeValue;
}
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
public ushort PduRef { get; private set; }
public ushort DbBlock { get; private set; }
public byte Area { get; private set; }
@@ -361,6 +400,8 @@ namespace Modbus.Net.Siemens
{
var r_message = (WriteRequestSiemensInputStruct) message;
byte[] valueBytes = BigEndianValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue);
byte belongAddress = r_message.BelongAddress;
byte masterAddress = r_message.MasterAddress;
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
@@ -381,7 +422,7 @@ namespace Modbus.Net.Siemens
const byte reserved = 0x00;
const byte type = (byte)SiemensDataType.OtherAccess;
ushort numberOfWriteBits = (ushort)(valueBytes.Length*8);
return Format(new byte[6], (byte)0x7c, protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
return Format(new byte[4], belongAddress, masterAddress, (byte)0x7c, protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
, variableSpec, vAddrLg, syntaxId, typeR, numberOfElements, dbBlock, area,
offsetBitBytes.Skip(1).ToArray(), reserved, type, numberOfWriteBits, valueBytes);
}

View File

@@ -25,7 +25,7 @@ namespace Modbus.Net.Siemens
{
byte[] newContent = new byte[content.Length + 2];
Array.Copy(content, 0, newContent, 0, content.Length);
Array.Copy(new byte[] { 0x68, (byte)(content.Length - 4), (byte)(content.Length - 4), 0x68, 0x02, 0x00 }, 0, newContent, 0, 6);
Array.Copy(new byte[] { 0x68, (byte)(content.Length - 4), (byte)(content.Length - 4), 0x68 }, 0, newContent, 0, 4);
int check = 0;
for (int i = 4; i < newContent.Length - 2; i++)
{

View File

@@ -25,7 +25,7 @@ namespace Modbus.Net.Siemens
}
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip, int port)
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip, int port) : base (0, 0)
{
_taspSrc = tsapSrc;
_tsapDst = tsapDst;

View File

@@ -75,7 +75,7 @@ namespace Modbus.Net.Siemens
{
case SiemensType.Ppi:
{
Wrapper = ConnectionString == null ? new SiemensPpiProtocal() : new SiemensPpiProtocal(ConnectionString);
Wrapper = ConnectionString == null ? new SiemensPpiProtocal(BelongAddress, MasterAddress) : new SiemensPpiProtocal(ConnectionString, BelongAddress, MasterAddress);
break;
}
//case SiemensType.Mpi:
@@ -91,7 +91,8 @@ namespace Modbus.Net.Siemens
}
}
public SiemensUtility(SiemensType connectionType, string connectionString, SiemensMachineModel model)
public SiemensUtility(SiemensType connectionType, string connectionString, SiemensMachineModel model,
byte belongAddress, byte masterAddress) : base(belongAddress, masterAddress)
{
ConnectionString = connectionString;
switch (model)
@@ -144,7 +145,7 @@ namespace Modbus.Net.Siemens
}
}
ConnectionType = connectionType;
AddressTranslator = new AddressTranslatorSiemens();
AddressTranslator = new AddressTranslatorSiemens();
}
public override void SetConnectionType(int connectionType)
@@ -152,11 +153,11 @@ namespace Modbus.Net.Siemens
ConnectionType = (SiemensType) connectionType;
}
public override async Task<byte[]> GetDatasAsync(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
public override async Task<byte[]> GetDatasAsync(string startAddress, int getByteCount)
{
try
{
var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(0xd3c7, SiemensTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(BelongAddress, MasterAddress, 0xd3c7, SiemensTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSiemensOutputStruct =
await
Wrapper.SendReceiveAsync(Wrapper[typeof (ReadRequestSiemensProtocal)],
@@ -169,11 +170,11 @@ namespace Modbus.Net.Siemens
}
}
public override async Task<bool> SetDatasAsync(byte belongAddress, byte materAddress, string startAddress, object[] setContents)
public override async Task<bool> SetDatasAsync(string startAddress, object[] setContents)
{
try
{
var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(BelongAddress, MasterAddress, 0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSiemensOutputStruct =
await
Wrapper.SendReceiveAsync(Wrapper[typeof (WriteRequestSiemensProtocal)],

View File

@@ -104,6 +104,16 @@ namespace Modbus.Net
/// </summary>
public bool KeepConnect { get; set; }
/// <summary>
/// 从站号
/// </summary>
public byte SlaveAddress { get; set; } = 2;
/// <summary>
/// 主站号
/// </summary>
public byte MasterAddress { get; set; } = 0;
/// <summary>
/// 设备的连接器
/// </summary>
@@ -129,6 +139,19 @@ namespace Modbus.Net
KeepConnect = keepConnect;
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
protected BaseMachine(IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress) : this(getAddresses, keepConnect)
{
SlaveAddress = slaveAddress;
MasterAddress = masterAddress;
}
/// <summary>
/// 读取数据
/// </summary>
@@ -162,7 +185,7 @@ namespace Modbus.Net
//获取数据
var datas =
await
BaseUtility.GetDatasAsync(2, 0,
BaseUtility.GetDatasAsync(
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
(int)
Math.Ceiling(communicateAddress.GetCount*
@@ -330,7 +353,7 @@ namespace Modbus.Net
var addressStart = AddressFormater.FormatAddress(communicateAddress.Area,
communicateAddress.Address);
var datasReturn = await BaseUtility.GetDatasAsync(2, 0,
var datasReturn = await BaseUtility.GetDatasAsync(
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
(int)
Math.Ceiling(communicateAddress.GetCount*
@@ -401,7 +424,7 @@ namespace Modbus.Net
}
//写入数据
await
BaseUtility.SetDatasAsync(2, 0, addressStart,
BaseUtility.SetDatasAsync(addressStart,
valueHelper.ByteArrayToObjectArray(datas,
new KeyValuePair<Type, int>(typeof (byte), datas.Length)));
}

View File

@@ -10,6 +10,9 @@ namespace Modbus.Net
/// </summary>
public abstract class BaseProtocal
{
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
/// <summary>
/// 协议的连接器
/// </summary>
@@ -18,9 +21,11 @@ namespace Modbus.Net
/// <summary>
/// 构造器
/// </summary>
protected BaseProtocal()
protected BaseProtocal(byte belongAddress, byte masterAddress)
{
Protocals = new Dictionary<string, ProtocalUnit>();
BelongAddress = belongAddress;
MasterAddress = masterAddress;
}
/// <summary>

View File

@@ -13,6 +13,9 @@ namespace Modbus.Net
protected BaseProtocal Wrapper;
protected string ConnectionString { get; set; }
public byte BelongAddress { get; set; }
public byte MasterAddress { get; set; }
/// <summary>
/// 获取协议是否遵循小端格式
/// </summary>
@@ -40,8 +43,10 @@ namespace Modbus.Net
/// <summary>
/// 构造器
/// </summary>
protected BaseUtility()
protected BaseUtility(byte belongAddress, byte masterAddress)
{
BelongAddress = belongAddress;
MasterAddress = masterAddress;
AddressTranslator = new AddressTranslatorBase();
}
@@ -54,25 +59,21 @@ namespace Modbus.Net
/// <summary>
/// 获取数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取字节数个数</param>
/// <returns>接收到的byte数据</returns>
public virtual byte[] GetDatas(byte belongAddress, byte masterAddress, string startAddress, int getByteCount)
public virtual byte[] GetDatas(string startAddress, int getByteCount)
{
return AsyncHelper.RunSync(() => GetDatasAsync(belongAddress, masterAddress, startAddress, getByteCount));
return AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getByteCount));
}
/// <summary>
/// 获取数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取字节数个数</param>
/// <returns>接收到的byte数据</returns>
public abstract Task<byte[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, int getByteCount);
public abstract Task<byte[]> GetDatasAsync(string startAddress, int getByteCount);
/// <summary>
/// 获取数据
@@ -82,10 +83,10 @@ namespace Modbus.Net
/// <param name="startAddress">开始地址</param>
/// <param name="getTypeAndCount">获取类型和个数</param>
/// <returns>接收到的对应的类型和数据</returns>
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
public virtual object[] GetDatas(string startAddress,
KeyValuePair<Type, int> getTypeAndCount)
{
return AsyncHelper.RunSync(() => GetDatasAsync(belongAddress, masterAddress, startAddress, getTypeAndCount));
return AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getTypeAndCount));
}
/// <summary>
@@ -96,14 +97,14 @@ namespace Modbus.Net
/// <param name="startAddress">开始地址</param>
/// <param name="getTypeAndCount">获取类型和个数</param>
/// <returns>接收到的对应的类型和数据</returns>
public virtual async Task<object[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress,
public virtual async Task<object[]> GetDatasAsync(string startAddress,
KeyValuePair<Type, int> getTypeAndCount)
{
try
{
string typeName = getTypeAndCount.Key.FullName;
double bCount = BigEndianValueHelper.Instance.ByteLength[typeName];
var getReturnValue = await GetDatasAsync(belongAddress, masterAddress, startAddress,
var getReturnValue = await GetDatasAsync(startAddress,
(int)Math.Ceiling(bCount * getTypeAndCount.Value));
var getBytes = getReturnValue;
return GetLittleEndian
@@ -125,10 +126,10 @@ namespace Modbus.Net
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取字节数个数</param>
/// <returns>接收到的对应的类型和数据</returns>
public virtual T[] GetDatas<T>(byte belongAddress, byte masterAddress, string startAddress,
public virtual T[] GetDatas<T>(string startAddress,
int getByteCount)
{
return AsyncHelper.RunSync(() => GetDatasAsync<T>(belongAddress, masterAddress, startAddress, getByteCount));
return AsyncHelper.RunSync(() => GetDatasAsync<T>(startAddress, getByteCount));
}
/// <summary>
@@ -140,12 +141,12 @@ namespace Modbus.Net
/// <param name="startAddress">开始地址</param>
/// <param name="getByteCount">获取字节数个数</param>
/// <returns>接收到的对应的类型和数据</returns>
public virtual async Task<T[]> GetDatasAsync<T>(byte belongAddress, byte masterAddress, string startAddress,
public virtual async Task<T[]> GetDatasAsync<T>(string startAddress,
int getByteCount)
{
try
{
var getBytes = await GetDatasAsync(belongAddress, masterAddress, startAddress,
var getBytes = await GetDatasAsync(startAddress,
new KeyValuePair<Type, int>(typeof(T), getByteCount));
return BigEndianValueHelper.Instance.ObjectArrayToDestinationArray<T>(getBytes);
}
@@ -158,26 +159,22 @@ namespace Modbus.Net
/// <summary>
/// 获取数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="getTypeAndCountList">获取类型和个数的队列</param>
/// <returns>获取数据的对象数组,请强制转换成相应类型</returns>
public virtual object[] GetDatas(byte belongAddress, byte masterAddress, string startAddress,
public virtual object[] GetDatas(string startAddress,
IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList)
{
return
AsyncHelper.RunSync(() => GetDatasAsync(belongAddress, masterAddress, startAddress, getTypeAndCountList));
AsyncHelper.RunSync(() => GetDatasAsync(startAddress, getTypeAndCountList));
}
/// <summary>
/// 获取数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="getTypeAndCountList">获取类型和个数的队列</param>
public virtual async Task<object[]> GetDatasAsync(byte belongAddress, byte masterAddress, string startAddress,
public virtual async Task<object[]> GetDatasAsync(string startAddress,
IEnumerable<KeyValuePair<Type, int>> getTypeAndCountList)
{
try
@@ -189,7 +186,7 @@ namespace Modbus.Net
let typeName = getTypeAndCount.Key.FullName
let bCount = BigEndianValueHelper.Instance.ByteLength[typeName]
select (int) Math.Ceiling(bCount*getTypeAndCount.Value)).Sum();
var getReturnValue = await GetDatasAsync(belongAddress, masterAddress, startAddress, bAllCount);
var getReturnValue = await GetDatasAsync(startAddress, bAllCount);
byte[] getBytes = getReturnValue;
return GetLittleEndian
? ValueHelper.Instance.ByteArrayToObjectArray(getBytes, translateTypeAndCount)
@@ -204,41 +201,35 @@ namespace Modbus.Net
/// <summary>
/// 设置数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="setContents">设置数据</param>
/// <returns>是否设置成功</returns>
public virtual bool SetDatas(byte belongAddress, byte masterAddress, string startAddress, object[] setContents)
public virtual bool SetDatas(string startAddress, object[] setContents)
{
return AsyncHelper.RunSync(() => SetDatasAsync(belongAddress, masterAddress, startAddress, setContents));
return AsyncHelper.RunSync(() => SetDatasAsync(startAddress, setContents));
}
/// <summary>
/// 设置数据
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
/// <param name="startAddress">开始地址</param>
/// <param name="setContents">设置数据</param>
/// <returns>是否设置成功</returns>
public abstract Task<bool> SetDatasAsync(byte belongAddress, byte masterAddress, string startAddress, object[] setContents);
public abstract Task<bool> SetDatasAsync(string startAddress, object[] setContents);
/*
/// <summary>
/// 获取PLC时间
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <returns>PLC时间</returns>
public abstract DateTime GetTime(byte belongAddress);
public abstract DateTime GetTime();
/// <summary>
/// 设置PLC时间
/// </summary>
/// <param name="belongAddress">从站地址</param>
/// <param name="setTime">设置PLC时间</param>
/// <returns>设置是否成功</returns>
public abstract bool SetTime(byte belongAddress, DateTime setTime);
public abstract bool SetTime(DateTime setTime);
*/
/// <summary>

View File

@@ -17,7 +17,7 @@ namespace NA200H.UI.ConsoleApp
{
string ip = "192.168.3.191";
//先初始化一个协议转换器这里构造Modbus/Tcp协议。
//BaseProtocal wrapper = new ModbusTcpProtocal(ip);
BaseProtocal wrapper = new ModbusTcpProtocal(ip, 2, 0);
/*
try
@@ -26,7 +26,7 @@ namespace NA200H.UI.ConsoleApp
//第一步先生成一个输入信息的object数组
object[] inputObjects = new object[] {(byte) 0x02, (byte) 0x01, (short) 0x4e20, (short) 0x0004};
//第二步:向仪器发送这个信息,并接收信息
byte[] outputBytes = wrapper.SendReceive(inputObjects);
byte[] outputBytes = wrapper.SendReceive(false, inputObjects);
//第三步:输出信息
for (int i = 0; i < outputBytes.Length; i++)
{
@@ -46,7 +46,7 @@ namespace NA200H.UI.ConsoleApp
//第一步先生成一个输入信息的object数组
object[] inputObjects = new object[]{(byte)0x02,(byte)0x01,(short)0x4e20,(short)0x0004};
//第二步:向仪器发送这个信息,并接收信息
byte[] outputBytes = wrapper.SendReceive(inputObjects);
byte[] outputBytes = wrapper.SendReceive(false, inputObjects);
//第三步:输出信息
for (int i = 0; i < outputBytes.Length; i++)
{
@@ -126,7 +126,7 @@ namespace NA200H.UI.ConsoleApp
if (!wrapper.ProtocalLinker.IsConnected) return;
AddressTranslator addressTranslator = new AddressTranslatorSiemens();
var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(0xaacc, SiemensTypeCode.Byte, "V 0", 4, addressTranslator);
var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(2, 0, 0xaacc, SiemensTypeCode.Byte, "V 0", 4, addressTranslator);
var readRequestSiemensOutputStruct =
(ReadRequestSiemensOutputStruct)
wrapper.SendReceive(wrapper[typeof(ReadRequestSiemensProtocal)], readRequestSiemensInputStruct);
@@ -141,7 +141,7 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(0xaadd, "V 100",
var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(2, 0, 0xaadd, "V 100",
new object[] { (ushort)280, (ushort)12, (ushort)56, (ushort)72, (ushort)88, (ushort)525, (ushort)477, (ushort)151, (ushort)52 }, addressTranslator);
var writeRequestSiemensOutputStruct =
(WriteRequestSiemensOutputStruct)

View File

@@ -31,13 +31,13 @@ namespace NA200H.UI.WPF
{
if (utility == null)
{
utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.12");
utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.12", 2, 0);
utility.AddressTranslator = new AddressTranslatorNA200H();
//utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.11", SiemensMachineModel.S7_300);
//utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.11", SiemensMachineModel.S7_300, 2, 0);
//utility.AddressTranslator = new AddressTranslatorSiemens();
}
object[] getNum = utility.GetDatas(0x02, 0x00, "NW 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
//object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
object[] getNum = utility.GetDatas("NW 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
//object[] getNum = utility.GetDatas("V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = BigEndianValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
SetValue(getNumUshorts);
}
@@ -52,7 +52,7 @@ namespace NA200H.UI.WPF
//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},
//});
//}, 2, 0);
//machine.AddressFormater = new AddressFormaterNA200H();
//machine.AddressTranslator = new AddressTranslatorNA200H();
//machine.AddressCombiner = new AddressCombinerContinus(machine.AddressTranslator);
@@ -63,7 +63,7 @@ namespace NA200H.UI.WPF
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}
});
}, 2, 0);
machine.AddressCombiner = new AddressCombinerContinus(machine.AddressTranslator);
machine.AddressCombinerSet = new AddressCombinerContinus(machine.AddressTranslator);
}
@@ -92,8 +92,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("NW 1", new object[] { add1, add2, add3 });
utility.SetDatas("V 1", new object[] { add1, add2, add3 });
Thread.Sleep(100);
GetUtilityEnter();
}

View File

@@ -37,7 +37,7 @@ namespace Siemens_S7_200.UI.WPF.TaskTest
TaskManager task = new TaskManager(300, true);
//向任务管理器中添加设备
task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.11",SiemensMachineModel.S7_300, addressUnits,
true));
true, 2, 0));
//增加值返回时的处理函数
task.ReturnValues += (returnValues) =>
{