diff --git a/S7.Net/PLC.cs b/S7.Net/PLC.cs
index ba4276b..f546dcb 100644
--- a/S7.Net/PLC.cs
+++ b/S7.Net/PLC.cs
@@ -306,53 +306,31 @@ namespace S7.Net
LastErrorString = exc.Message;
}
}
-
+
///
- /// Reads up to 200 bytes from the plc and returns an array of bytes. You must specify the memory area type, memory are address, byte start address and bytes count.
+ /// Reads a number of bytes from a DB starting from a specified index. This handles more than 200 bytes with multiple requests.
/// If the read was not successful, check LastErrorCode or LastErrorString.
///
/// Data type of the memory area, can be DB, Timer, Counter, Merker(Memory), Input, Output.
/// Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.
/// Start byte address. If you want to read DB1.DBW200, this is 200.
- /// Byte count, if you want to read 120 bytes, set this to 120. This parameter can't be higher than 200. If you need more, use recursion.
+ /// Byte count, if you want to read 120 bytes, set this to 120.
/// Returns the bytes in an array
public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
{
- byte[] bytes = new byte[count];
-
- try
+ List resultBytes = new List();
+ int index = startByteAdr;
+ while (count > 0)
{
- // first create the header
- int packageSize = 31;
- Types.ByteArray package = new ByteArray(packageSize);
- package.Add(ReadHeaderPackage());
- // package.Add(0x02); // datenart
- package.Add(CreateReadDataRequestPackage(dataType, db, startByteAdr, count));
-
- _mSocket.Send(package.array, package.array.Length, SocketFlags.None);
-
- byte[] bReceive = new byte[512];
- int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
- if (bReceive[21] != 0xff)
- throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
-
- for (int cnt = 0; cnt < count; cnt++)
- bytes[cnt] = bReceive[cnt + 25];
-
- return bytes;
- }
- catch (SocketException socketException)
- {
- LastErrorCode = ErrorCode.WriteData;
- LastErrorString = socketException.Message;
- return null;
- }
- catch(Exception exc)
- {
- LastErrorCode = ErrorCode.WriteData;
- LastErrorString = exc.Message;
- return null;
+ var maxToRead = (int)Math.Min(count, 200);
+ byte[] bytes = ReadBytesWithASingleRequest(dataType, db, index, maxToRead);
+ if (bytes == null)
+ return resultBytes.ToArray();
+ resultBytes.AddRange(bytes);
+ count -= maxToRead;
+ index += maxToRead;
}
+ return resultBytes.ToArray();
}
///
@@ -617,10 +595,10 @@ namespace S7.Net
{
int numBytes = Types.Struct.GetStructSize(structType);
// now read the package
- List resultBytes = ReadMultipleBytes(numBytes, db, startByteAdr);
+ var resultBytes = ReadBytes(DataType.DataBlock, db, startByteAdr, numBytes);
// and decode it
- return Types.Struct.FromBytes(structType, resultBytes.ToArray());
+ return Types.Struct.FromBytes(structType, resultBytes);
}
///
@@ -635,9 +613,9 @@ namespace S7.Net
Type classType = sourceClass.GetType();
int numBytes = Types.Class.GetClassSize(classType);
// now read the package
- List resultBytes = ReadMultipleBytes(numBytes, db, startByteAdr);
+ var resultBytes = ReadBytes(DataType.DataBlock, db, startByteAdr, numBytes);
// and decode it
- Types.Class.FromBytes(sourceClass, classType, resultBytes.ToArray());
+ Types.Class.FromBytes(sourceClass, classType, resultBytes);
}
@@ -1004,30 +982,6 @@ namespace S7.Net
return errCode;
}
- ///
- /// Reads a number of bytes from a DB starting from a specified index. This handles more than 200 bytes with multiple requests.
- ///
- /// Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.
- /// Start byte address. If you want to read DB1.DBW200, this is 200.
- /// Byte count, if you want to read 120 bytes, set this to 120. This parameter can't be higher than 200. If you need more, use recursion.
- /// Returns the bytes in a list
- private List ReadMultipleBytes(int numBytes, int db, int startByteAdr = 0)
- {
- List resultBytes = new List();
- int index = startByteAdr;
- while (numBytes > 0)
- {
- var maxToRead = (int)Math.Min(numBytes, 200);
- byte[] bytes = ReadBytes(DataType.DataBlock, db, index, maxToRead);
- if (bytes == null)
- return new List();
- resultBytes.AddRange(bytes);
- numBytes -= maxToRead;
- index += maxToRead;
- }
- return resultBytes;
- }
-
///
/// Creates the header to read bytes from the plc
///
@@ -1094,6 +1048,45 @@ namespace S7.Net
return package;
}
+ private byte[] ReadBytesWithASingleRequest(DataType dataType, int db, int startByteAdr, int count)
+ {
+ byte[] bytes = new byte[count];
+
+ try
+ {
+ // first create the header
+ int packageSize = 31;
+ Types.ByteArray package = new ByteArray(packageSize);
+ package.Add(ReadHeaderPackage());
+ // package.Add(0x02); // datenart
+ package.Add(CreateReadDataRequestPackage(dataType, db, startByteAdr, count));
+
+ _mSocket.Send(package.array, package.array.Length, SocketFlags.None);
+
+ byte[] bReceive = new byte[512];
+ int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
+ if (bReceive[21] != 0xff)
+ throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
+
+ for (int cnt = 0; cnt < count; cnt++)
+ bytes[cnt] = bReceive[cnt + 25];
+
+ return bytes;
+ }
+ catch (SocketException socketException)
+ {
+ LastErrorCode = ErrorCode.WriteData;
+ LastErrorString = socketException.Message;
+ return null;
+ }
+ catch (Exception exc)
+ {
+ LastErrorCode = ErrorCode.WriteData;
+ LastErrorString = exc.Message;
+ return null;
+ }
+ }
+
#region IDisposable members
public void Dispose()