diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs index f2c757d..1668e08 100644 --- a/S7.Net/PLCHelpers.cs +++ b/S7.Net/PLCHelpers.cs @@ -1,4 +1,5 @@ using S7.Net.Helper; +using S7.Net.Protocol.S7; using S7.Net.Types; using System; using System.Collections.Generic; @@ -14,7 +15,7 @@ namespace S7.Net /// /// /// - private void BuildHeaderPackage(System.IO.MemoryStream stream, int amount = 1) + private static void BuildHeaderPackage(System.IO.MemoryStream stream, int amount = 1) { //header size = 19 bytes stream.WriteByteArray(new byte[] { 0x03, 0x00 }); @@ -37,7 +38,7 @@ namespace S7.Net /// Start address of the byte /// Number of bytes to be read /// - private void BuildReadDataRequestPackage(System.IO.MemoryStream stream, DataType dataType, int db, int startByteAdr, int count = 1) + private static void BuildReadDataRequestPackage(System.IO.MemoryStream stream, DataType dataType, int db, int startByteAdr, int count = 1) { //single data req = 12 stream.WriteByteArray(new byte[] { 0x12, 0x0a, 0x10 }); @@ -176,7 +177,7 @@ namespace S7.Net /// /// /// Byte lenght of variable - private int VarTypeToByteLength(VarType varType, int varCount = 1) + internal static int VarTypeToByteLength(VarType varType, int varCount = 1) { switch (varType) { @@ -242,5 +243,20 @@ namespace S7.Net offset++; } } + + private static byte[] BuildReadRequestPackage(IList dataItems) + { + int packageSize = 19 + (dataItems.Count * 12); + var package = new System.IO.MemoryStream(packageSize); + + BuildHeaderPackage(package, dataItems.Count); + + foreach (var dataItem in dataItems) + { + BuildReadDataRequestPackage(package, dataItem.DataType, dataItem.DB, dataItem.StartByteAddress, dataItem.ByteLength); + } + + return package.ToArray(); + } } } diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs index fd3e6fd..b6b49c6 100644 --- a/S7.Net/PlcAsynchronous.cs +++ b/S7.Net/PlcAsynchronous.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using S7.Net.Protocol; using System.IO; using System.Threading; +using S7.Net.Protocol.S7; namespace S7.Net { @@ -262,20 +263,10 @@ namespace S7.Net try { - // first create the header - int packageSize = 19 + (dataItems.Count * 12); - var package = new System.IO.MemoryStream(packageSize); - BuildHeaderPackage(package, dataItems.Count); - // package.Add(0x02); // datenart - foreach (var dataItem in dataItems) - { - BuildReadDataRequestPackage(package, dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, VarTypeToByteLength(dataItem.VarType, dataItem.Count)); - } - - var dataToSend = package.ToArray(); + var dataToSend = BuildReadRequestPackage(dataItems.Select(d => DataItem.GetDataItemAddress(d)).ToList()); await stream.WriteAsync(dataToSend, 0, dataToSend.Length); - var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken); //TODO use Async + var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken); ValidateResponseCode((ReadWriteErrorCode)s7data[14]); ParseDataIntoDataItems(s7data, dataItems); @@ -295,6 +286,7 @@ namespace S7.Net return dataItems; } + /// /// Write a number of bytes from a DB starting from a specified index. This handles more than 200 bytes with multiple requests. /// If the write was not successful, check LastErrorCode or LastErrorString. @@ -444,14 +436,7 @@ namespace S7.Net { var stream = GetStreamIfAvailable(); - // first create the header - int packageSize = 31; - var package = new System.IO.MemoryStream(packageSize); - BuildHeaderPackage(package); - // package.Add(0x02); // datenart - BuildReadDataRequestPackage(package, dataType, db, startByteAdr, count); - - var dataToSend = package.ToArray(); + var dataToSend = BuildReadRequestPackage(new [] { new DataItemAddress(dataType, db, startByteAdr, count)}); await stream.WriteAsync(dataToSend, 0, dataToSend.Length, cancellationToken); var s7data = await COTP.TSDU.ReadAsync(stream, cancellationToken); diff --git a/S7.Net/Protocol/S7/DataItemAddress.cs b/S7.Net/Protocol/S7/DataItemAddress.cs new file mode 100644 index 0000000..cf37382 --- /dev/null +++ b/S7.Net/Protocol/S7/DataItemAddress.cs @@ -0,0 +1,37 @@ +namespace S7.Net.Protocol.S7 +{ + /// + /// Represents an area of memory in the PLC + /// + internal class DataItemAddress + { + public DataItemAddress(DataType dataType, int db, int startByteAddress, int byteLength) + { + DataType = dataType; + DB = db; + StartByteAddress = startByteAddress; + ByteLength = byteLength; + } + + + /// + /// Memory area to read + /// + public DataType DataType { get; } + + /// + /// Address of memory area to read (example: for DB1 this value is 1, for T45 this value is 45) + /// + public int DB { get; } + + /// + /// Address of the first byte to read + /// + public int StartByteAddress { get; } + + /// + /// Length of data to read + /// + public int ByteLength { get; } + } +} diff --git a/S7.Net/Types/DataItem.cs b/S7.Net/Types/DataItem.cs index c944ffa..254eab3 100644 --- a/S7.Net/Types/DataItem.cs +++ b/S7.Net/Types/DataItem.cs @@ -1,4 +1,5 @@ -using System; +using S7.Net.Protocol.S7; +using System; namespace S7.Net.Types { @@ -94,5 +95,10 @@ namespace S7.Net.Types return dataItem; } + + internal static DataItemAddress GetDataItemAddress(DataItem dataItem) + { + return new DataItemAddress(dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, Plc.VarTypeToByteLength(dataItem.VarType, dataItem.Count)); + } } }