/// <summary> /// Create the bytes-package to request data from the PLC. You have to specify the memory type (dataType), /// the address of the memory, the address of the byte and the bytes count. /// </summary> /// <param name="dataType">MemoryType (DB, Timer, Counter, etc.)</param> /// <param name="db">Address of the memory to be read</param> /// <param name="startByteAdr">Start address of the byte</param> /// <param name="count">Number of bytes to be read</param> /// <returns></returns> private ByteArray CreateReadDataRequestPackage(DataType dataType, int db, int startByteAdr, int count = 1) { //single data req = 12 var package = new Types.ByteArray(12); package.Add(new byte[] { 0x12, 0x0a, 0x10 }); switch (dataType) { case DataType.Timer: case DataType.Counter: package.Add((byte)dataType); break; default: package.Add(0x02); break; } package.Add(Word.ToByteArray((ushort)(count))); package.Add(Word.ToByteArray((ushort)(db))); package.Add((byte)dataType); var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191 package.Add((byte)overflow); switch (dataType) { case DataType.Timer: case DataType.Counter: package.Add(Types.Word.ToByteArray((ushort)(startByteAdr))); break; default: package.Add(Types.Word.ToByteArray((ushort)((startByteAdr) * 8))); break; } return(package); }
/// <summary> /// Creates the header to read bytes from the PLC /// </summary> /// <param name="amount"></param> /// <returns></returns> private ByteArray ReadHeaderPackage(int amount = 1) { //header size = 19 bytes var package = new Types.ByteArray(19); package.Add(new byte[] { 0x03, 0x00 }); //complete package size package.Add(Types.Int.ToByteArray((short)(19 + (12 * amount)))); package.Add(new byte[] { 0x02, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00 }); //data part size package.Add(Types.Word.ToByteArray((ushort)(2 + (amount * 12)))); package.Add(new byte[] { 0x00, 0x00, 0x04 }); //amount of requests package.Add((byte)amount); return(package); }
private async Task WriteBitWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue) { 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); 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); Thread.Sleep(100); var s7data = await COTP.TSDU.ReadAsync(stream); if (s7data == null || s7data[14] != 0xff) { Logger.E($"WrongNumberReceivedBytes if (s7data({s7data}) == null || s7data[14] != 0xff)"); throw new PlcException(ErrorCode.WrongNumberReceivedBytes); } } catch (Exception exc) { Logger.E(exc); //throw new PlcException(ErrorCode.WriteData, exc); } }