diff --git a/S7.Net.UnitTest/Helpers/TestSmallClass.cs b/S7.Net.UnitTest/Helpers/TestSmallClass.cs new file mode 100644 index 0000000..de2a9d2 --- /dev/null +++ b/S7.Net.UnitTest/Helpers/TestSmallClass.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace S7.UnitTest.Helpers +{ + class TestSmallClass + { + public bool Bool1 { get; set; } + } +} diff --git a/S7.Net.UnitTest/S7.Net.UnitTest.csproj b/S7.Net.UnitTest/S7.Net.UnitTest.csproj index 5aca96b..75329b1 100644 --- a/S7.Net.UnitTest/S7.Net.UnitTest.csproj +++ b/S7.Net.UnitTest/S7.Net.UnitTest.csproj @@ -70,6 +70,7 @@ + @@ -118,4 +119,4 @@ --> - \ No newline at end of file + diff --git a/S7.Net.UnitTest/S7NetTestsSync.cs b/S7.Net.UnitTest/S7NetTestsSync.cs index 8535852..6889a16 100644 --- a/S7.Net.UnitTest/S7NetTestsSync.cs +++ b/S7.Net.UnitTest/S7NetTestsSync.cs @@ -397,19 +397,51 @@ namespace S7.Net.UnitTest { Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor."); - ushort val = 16384; - plc.Write("DB2.DBW16384", val); - ushort result = (ushort)plc.Read("DB2.DBW16384"); - Assert.AreEqual(val, result, "A ushort goes from 0 to 64512"); + bool val = true; + plc.Write("DB2.DBX0.5", val); + bool result = (bool)plc.Read("DB2.DBX0.5"); + Assert.AreEqual(val, result); - ushort val2 = 129; - plc.Write("DB2.DBW16", val2); - ushort result2 = (ushort)plc.Read("DB2.DBW16"); - Assert.AreEqual(val2, result2, "A ushort goes from 0 to 64512"); + ushort val1 = 16384; + plc.Write("DB2.DBW16384", val1); + ushort result1 = (ushort)plc.Read("DB2.DBW16384"); + Assert.AreEqual(val1, result1, "A ushort goes from 0 to 64512"); + + bool val2 = true; + plc.Write("DB2.DBX8192.7", val2); + bool result2 = (bool)plc.Read("DB2.DBX8192.7"); + Assert.AreEqual(val2, result2); + + ushort val3 = 129; + plc.Write("DB2.DBW16", val3); + ushort result3 = (ushort)plc.Read("DB2.DBW16"); + Assert.AreEqual(val3, result3, "A ushort goes from 0 to 64512"); + + byte[] val4 = new byte[] { 0x12, 0x34 }; + plc.Write("DB2.DBB2048", val4[0]); + plc.Write("DB2.DBB2049", val4[1]); + byte result4b0 = (byte)plc.Read("DB2.DBB2048"); + byte result4b1 = (byte)plc.Read("DB2.DBB2049"); + Assert.AreEqual(val4[0], result4b0); + Assert.AreEqual(val4[1], result4b1); + + bool val6 = true; + plc.Write("DB2.DBX16384.6", val6); + bool result6 = (bool)plc.Read("DB2.DBX16384.6"); + Assert.AreEqual(val6, result6); var dataItems = new List() { new DataItem + { + Count = 1, + DataType = DataType.DataBlock, + DB = 2, + StartByteAdr = 0, + BitAdr = 5, + VarType = VarType.Bit + } + ,new DataItem { Count = 1, DataType = DataType.DataBlock, @@ -418,19 +450,61 @@ namespace S7.Net.UnitTest VarType = VarType.Word }, new DataItem + { + Count = 1, + DataType = DataType.DataBlock, + DB = 2, + StartByteAdr = 8192, + BitAdr = 7, + VarType = VarType.Bit + }, + new DataItem { Count = 1, DataType = DataType.DataBlock, DB = 2, StartByteAdr = 16, VarType = VarType.Word - } + }, + // single byte + new DataItem + { + Count = 1, + DataType = DataType.DataBlock, + DB = 2, + StartByteAdr = 2048, + VarType = VarType.Byte + }, + // multiple bytes + new DataItem + { + Count = 2, + DataType = DataType.DataBlock, + DB = 2, + StartByteAdr = 2048, + VarType = VarType.Byte + }, + new DataItem + { + Count = 1, + DataType = DataType.DataBlock, + DB = 2, + StartByteAdr = 16384, + BitAdr = 6, + VarType = VarType.Bit + }, }; plc.ReadMultipleVars(dataItems); Assert.AreEqual(dataItems[0].Value, val); - Assert.AreEqual(dataItems[1].Value, val2); + Assert.AreEqual(dataItems[1].Value, val1); + Assert.AreEqual(dataItems[2].Value, val2); + Assert.AreEqual(dataItems[3].Value, val3); + Assert.AreEqual(dataItems[4].Value, val4[0]); + Assert.AreEqual(((byte[])dataItems[5].Value)[0], val4[0]); //dataItem[5].Value should be byte[2] + Assert.AreEqual(((byte[])dataItems[5].Value)[1], val4[1]); + Assert.AreEqual(dataItems[6].Value, val6); } /// @@ -829,6 +903,20 @@ namespace S7.Net.UnitTest } } + [TestMethod] + public void T28_ReadClass_DoesntCrash_When_ReadingLessThan1Byte() + { + Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor."); + + var tc = new TestSmallClass(); + tc.Bool1 = true; + + plc.WriteClass(tc, DB2); + var tc2 = plc.ReadClass(DB2); + + Assert.AreEqual(tc.Bool1, tc2.Bool1); + } + #endregion #region Private methods diff --git a/S7.Net/Types/Class.cs b/S7.Net/Types/Class.cs index 794b469..26f4742 100644 --- a/S7.Net/Types/Class.cs +++ b/S7.Net/Types/Class.cs @@ -99,6 +99,10 @@ namespace S7.Net.Types numBytes = GetIncreasedNumberOfBytes(numBytes, property.PropertyType); } } + // enlarge numBytes to next even number because S7-Structs in a DB always will be resized to an even byte count + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; return (int)numBytes; } diff --git a/S7.Net/Types/DataItem.cs b/S7.Net/Types/DataItem.cs index 454497f..5f48586 100644 --- a/S7.Net/Types/DataItem.cs +++ b/S7.Net/Types/DataItem.cs @@ -25,6 +25,11 @@ /// public int StartByteAdr { get; set; } + /// + /// Addess of bit to read from StartByteAdr + /// + public byte BitAdr { get; set; } + /// /// Number of variables to read ///