From bb0b57c57482d6ae5d2c95f0bad2a6b217f2fe95 Mon Sep 17 00:00:00 2001 From: Serge Camille Date: Mon, 17 Aug 2020 21:29:44 +0200 Subject: [PATCH] Add method BuildWriteBitPackage Merges data creation between sync and async for writing bit values. --- S7.Net/PlcAsynchronous.cs | 32 +++---------------- S7.Net/PlcSynchronous.cs | 67 +++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 56 deletions(-) diff --git a/S7.Net/PlcAsynchronous.cs b/S7.Net/PlcAsynchronous.cs index 4074ba9..61727ae 100644 --- a/S7.Net/PlcAsynchronous.cs +++ b/S7.Net/PlcAsynchronous.cs @@ -461,41 +461,17 @@ namespace S7.Net { var stream = GetStreamIfAvailable(); - byte[] bReceive = new byte[513]; - int varCount = 0; - try { - var value = new[] {bitValue ? (byte) 1 : (byte) 0}; - varCount = value.Length; - // first create the header - int packageSize = 35 + value.Length; - ByteArray package = new Types.ByteArray(packageSize); + var dataToSend = BuildWriteBitPackage(dataType, db, startByteAdr, bitValue, bitAdr); - package.Add(new byte[] { 3, 0, 0 }); - package.Add((byte)packageSize); - package.Add(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); - package.Add(Word.ToByteArray((ushort)(varCount - 1))); - package.Add(new byte[] { 0, 0x0e }); - package.Add(Word.ToByteArray((ushort)(varCount + 4))); - package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x01 }); //ending 0x01 is used for writing a sinlge bit - package.Add(Word.ToByteArray((ushort)varCount)); - package.Add(Word.ToByteArray((ushort)(db))); - package.Add((byte)dataType); - int overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 - package.Add((byte)overflow); - package.Add(Word.ToByteArray((ushort)(startByteAdr * 8 + bitAdr))); - package.Add(new byte[] { 0, 0x03 }); //ending 0x03 is used for writing a sinlge bit - package.Add(Word.ToByteArray((ushort)(varCount))); - - // now join the header and the data - package.Add(value); - - await stream.WriteAsync(package.Array, 0, package.Array.Length); + await stream.WriteAsync(dataToSend, 0, dataToSend.Length); var s7data = await COTP.TSDU.ReadAsync(stream); if (s7data == null || s7data[14] != 0xff) + { throw new PlcException(ErrorCode.WrongNumberReceivedBytes); + } } catch (Exception exc) { diff --git a/S7.Net/PlcSynchronous.cs b/S7.Net/PlcSynchronous.cs index 5106fe9..367c572 100644 --- a/S7.Net/PlcSynchronous.cs +++ b/S7.Net/PlcSynchronous.cs @@ -414,7 +414,7 @@ namespace S7.Net { int varCount = count; // first create the header - int packageSize = 35 + count; + int packageSize = 35 + varCount; var package = new MemoryStream(new byte[packageSize]); package.WriteByte(3); @@ -441,43 +441,54 @@ namespace S7.Net return package.ToArray(); } + private byte[] BuildWriteBitPackage(DataType dataType, int db, int startByteAdr, bool bitValue, int bitAdr) + { + var stream = GetStreamIfAvailable(); + var value = new[] { bitValue ? (byte)1 : (byte)0 }; + int varCount = 1; + // first create the header + int packageSize = 35 + varCount; + var package = new MemoryStream(new byte[packageSize]); + + package.WriteByte(3); + package.WriteByte(0); + //complete package size + package.WriteByteArray(Int.ToByteArray((short)packageSize)); + package.WriteByteArray(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); + package.WriteByteArray(Word.ToByteArray((ushort)(varCount - 1))); + package.WriteByteArray(new byte[] { 0, 0x0e }); + package.WriteByteArray(Word.ToByteArray((ushort)(varCount + 4))); + package.WriteByteArray(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x01 }); //ending 0x01 is used for writing a sinlge bit + package.WriteByteArray(Word.ToByteArray((ushort)varCount)); + package.WriteByteArray(Word.ToByteArray((ushort)(db))); + package.WriteByte((byte)dataType); + var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 + package.WriteByte((byte)overflow); + package.WriteByteArray(Word.ToByteArray((ushort)(startByteAdr * 8 + bitAdr))); + package.WriteByteArray(new byte[] { 0, 0x03 }); //ending 0x03 is used for writing a sinlge bit + package.WriteByteArray(Word.ToByteArray((ushort)(varCount))); + + // now join the header and the data + package.WriteByteArray(value); + + return package.ToArray(); + } + + private void WriteBitWithASingleRequest(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue) { var stream = GetStreamIfAvailable(); - int varCount = 0; - try { - var value = new[] {bitValue ? (byte) 1 : (byte) 0}; - varCount = value.Length; - // first create the header - int packageSize = 35 + value.Length; - ByteArray package = new ByteArray(packageSize); + var dataToSend = BuildWriteBitPackage(dataType, db, startByteAdr, bitValue, bitAdr); - package.Add(new byte[] { 3, 0, 0 }); - package.Add((byte)packageSize); - package.Add(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); - package.Add(Word.ToByteArray((ushort)(varCount - 1))); - package.Add(new byte[] { 0, 0x0e }); - package.Add(Word.ToByteArray((ushort)(varCount + 4))); - package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x01 }); //ending 0x01 is used for writing a sinlge bit - package.Add(Word.ToByteArray((ushort)varCount)); - package.Add(Word.ToByteArray((ushort)(db))); - package.Add((byte)dataType); - int overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 - package.Add((byte)overflow); - package.Add(Word.ToByteArray((ushort)(startByteAdr * 8 + bitAdr))); - package.Add(new byte[] { 0, 0x03 }); //ending 0x03 is used for writing a sinlge bit - package.Add(Word.ToByteArray((ushort)(varCount))); - - // now join the header and the data - package.Add(value); - - stream.Write(package.Array, 0, package.Array.Length); + stream.Write(dataToSend, 0, dataToSend.Length); var s7data = COTP.TSDU.Read(stream); if (s7data == null || s7data[14] != 0xff) + { throw new PlcException(ErrorCode.WrongNumberReceivedBytes); + } } catch (Exception exc) {