diff --git a/S7.Net.UnitTest/Helpers/TestClass.cs b/S7.Net.UnitTest/Helpers/TestClass.cs
index 0c221e2..c810adc 100644
--- a/S7.Net.UnitTest/Helpers/TestClass.cs
+++ b/S7.Net.UnitTest/Helpers/TestClass.cs
@@ -35,12 +35,12 @@ namespace S7.Net.UnitTest.Helpers
///
/// DB1.DBD4
///
- public double RealVariableDouble { get; set; }
+ public double LRealVariable { get; set; }
///
/// DB1.DBD8
///
- public float RealVariableFloat { get; set; }
+ public float RealVariable { get; set; }
///
/// DB1.DBD12
diff --git a/S7.Net.UnitTest/Helpers/TestStruct.cs b/S7.Net.UnitTest/Helpers/TestStruct.cs
index 2b70374..c40c6f4 100644
--- a/S7.Net.UnitTest/Helpers/TestStruct.cs
+++ b/S7.Net.UnitTest/Helpers/TestStruct.cs
@@ -35,12 +35,12 @@ namespace S7.Net.UnitTest.Helpers
///
/// DB1.DBD4
///
- public double RealVariableDouble;
+ public double LRealVariable;
///
/// DB1.DBD8
///
- public float RealVariableFloat;
+ public float RealVariable;
///
/// DB1.DBD12
diff --git a/S7.Net.UnitTest/S7NetTestsAsync.cs b/S7.Net.UnitTest/S7NetTestsAsync.cs
index e03a490..47ff56c 100644
--- a/S7.Net.UnitTest/S7NetTestsAsync.cs
+++ b/S7.Net.UnitTest/S7NetTestsAsync.cs
@@ -101,20 +101,13 @@ namespace S7.Net.UnitTest
///
/// Read/Write a single REAL with a single request.
- /// Test that writing a double and reading it gives the correct value.
+ /// Test that writing a float and reading it gives the correct value.
///
[TestMethod]
public async Task Test_Async_WriteAndReadRealVariables()
{
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
- // Reading and writing a double is quite complicated, because it needs to be converted to DWord before the write,
- // then reconvert to double after the read.
- double val = 35.68729;
- await plc.WriteAsync("DB1.DBD40", val.ConvertToUInt());
- double result = ((uint)await plc.ReadAsync("DB1.DBD40")).ConvertToDouble();
- Assert.AreEqual(val, Math.Round(result, 5)); // float lose precision, so i need to round it
-
// Reading and writing a float is quite complicated, because it needs to be converted to DWord before the write,
// then reconvert to float after the read. Float values can contain only 7 digits, so no precision is lost.
float val2 = 1234567;
@@ -162,8 +155,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
@@ -175,8 +168,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10);
Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable);
Assert.AreEqual(tc.IntVariable, tc2.IntVariable);
- Assert.AreEqual(tc.RealVariableDouble, Math.Round(tc2.RealVariableDouble, 3));
- Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
+ Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
+ Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -219,8 +212,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
plc.WriteStruct(tc, DB2);
@@ -230,8 +223,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10);
Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable);
Assert.AreEqual(tc.IntVariable, tc2.IntVariable);
- Assert.AreEqual(tc.RealVariableDouble, Math.Round(tc2.RealVariableDouble, 3));
- Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
+ Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
+ Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -584,8 +577,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
@@ -599,8 +592,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10);
Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable);
Assert.AreEqual(tc.IntVariable, tc2.IntVariable);
- Assert.AreEqual(tc.RealVariableDouble, tc2.RealVariableDouble, 0.1);
- Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
+ Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable, 0.1);
+ Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
Assert.AreEqual(TestClassWithPrivateSetters.PRIVATE_SETTER_VALUE, tc2.PrivateSetterProperty);
@@ -632,8 +625,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
@@ -649,8 +642,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc2.BitVariable10, tc2Generic.BitVariable10);
Assert.AreEqual(tc2.DIntVariable, tc2Generic.DIntVariable);
Assert.AreEqual(tc2.IntVariable, tc2Generic.IntVariable);
- Assert.AreEqual(Math.Round(tc2.RealVariableDouble, 3), Math.Round(tc2Generic.RealVariableDouble, 3));
- Assert.AreEqual(tc2.RealVariableFloat, tc2Generic.RealVariableFloat);
+ Assert.AreEqual(Math.Round(tc2.LRealVariable, 3), Math.Round(tc2Generic.LRealVariable, 3));
+ Assert.AreEqual(tc2.RealVariable, tc2Generic.RealVariable);
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
}
@@ -675,8 +668,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
@@ -689,8 +682,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc2Generic.BitVariable00, tc2GenericWithClassFactory.BitVariable00);
Assert.AreEqual(tc2Generic.BitVariable10, tc2GenericWithClassFactory.BitVariable10);
Assert.AreEqual(tc2Generic.DIntVariable, tc2GenericWithClassFactory.DIntVariable);
- Assert.AreEqual(Math.Round(tc2Generic.RealVariableDouble, 3), Math.Round(tc2GenericWithClassFactory.RealVariableDouble, 3));
- Assert.AreEqual(tc2Generic.RealVariableFloat, tc2GenericWithClassFactory.RealVariableFloat);
+ Assert.AreEqual(Math.Round(tc2Generic.LRealVariable, 3), Math.Round(tc2GenericWithClassFactory.LRealVariable, 3));
+ Assert.AreEqual(tc2Generic.RealVariable, tc2GenericWithClassFactory.RealVariable);
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
}
@@ -747,8 +740,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
@@ -763,8 +756,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(ts2.BitVariable10, ts2Generic.BitVariable10);
Assert.AreEqual(ts2.DIntVariable, ts2Generic.DIntVariable);
Assert.AreEqual(ts2.IntVariable, ts2Generic.IntVariable);
- Assert.AreEqual(Math.Round(ts2.RealVariableDouble, 3), Math.Round(ts2Generic.RealVariableDouble, 3));
- Assert.AreEqual(ts2.RealVariableFloat, ts2Generic.RealVariableFloat);
+ Assert.AreEqual(ts2.LRealVariable, ts2Generic.LRealVariable);
+ Assert.AreEqual(ts2.RealVariable, ts2Generic.RealVariable);
Assert.AreEqual(ts2.DWordVariable, ts2Generic.DWordVariable);
}
@@ -792,8 +785,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
- RealVariableDouble = -154.789,
- RealVariableFloat = -154.789f,
+ LRealVariable = -154.789,
+ RealVariable = -154.789f,
DWordVariable = 850
};
plc.WriteClass(tc, DB2);
@@ -883,16 +876,16 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.CustomTypes[1].Bools[1], tc2.CustomTypes[1].Bools[1]);
}
- [TestMethod]
- public async Task Test_Async_ReadWriteDouble()
- {
- double test_value = 55.66;
- await plc.WriteAsync("DB1.DBD0", test_value);
- var helper = await plc.ReadAsync("DB1.DBD0");
- double test_value2 = Conversion.ConvertToDouble((uint)helper);
+ //[TestMethod]
+ //public async Task Test_Async_ReadWriteDouble()
+ //{
+ // double test_value = 55.66;
+ // await plc.WriteAsync("DB1.DBD0", test_value);
+ // var helper = await plc.ReadAsync("DB1.DBD0");
+ // double test_value2 = Conversion.ConvertToDouble((uint)helper);
- Assert.AreEqual(test_value, test_value2, 0.01, "Compare Write/Read"); //Need delta here because S7 only has 32 bit reals
- }
+ // Assert.AreEqual(test_value, test_value2, 0.01, "Compare Write/Read"); //Need delta here because S7 only has 32 bit reals
+ //}
[TestMethod]
public async Task Test_Async_ReadWriteSingle()
diff --git a/S7.Net.UnitTest/S7NetTestsSync.cs b/S7.Net.UnitTest/S7NetTestsSync.cs
index e2e563e..fd63448 100644
--- a/S7.Net.UnitTest/S7NetTestsSync.cs
+++ b/S7.Net.UnitTest/S7NetTestsSync.cs
@@ -146,20 +146,13 @@ namespace S7.Net.UnitTest
///
/// Read/Write a single REAL with a single request.
- /// Test that writing a double and reading it gives the correct value.
+ /// Test that writing a float and reading it gives the correct value.
///
[TestMethod]
public void T03_WriteAndReadRealVariables()
{
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
- // Reading and writing a double is quite complicated, because it needs to be converted to DWord before the write,
- // then reconvert to double after the read.
- double val = 35.68729;
- plc.Write("DB1.DBD40", val.ConvertToUInt());
- double result = ((uint)plc.Read("DB1.DBD40")).ConvertToDouble();
- Assert.AreEqual(val, Math.Round(result, 5)); // float lose precision, so i need to round it
-
// Reading and writing a float is quite complicated, because it needs to be converted to DWord before the write,
// then reconvert to float after the read. Float values can contain only 7 digits, so no precision is lost.
float val2 = 1234567;
@@ -186,8 +179,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
- tc.RealVariableDouble = -154.789;
- tc.RealVariableFloat = -154.789f;
+ tc.LRealVariable = -154.789;
+ tc.RealVariable = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
TestClass tc2 = new TestClass();
@@ -197,8 +190,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10);
Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable);
Assert.AreEqual(tc.IntVariable, tc2.IntVariable);
- Assert.AreEqual(Math.Round(tc.RealVariableDouble, 3), Math.Round(tc2.RealVariableDouble, 3));
- Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
+ Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
+ Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -215,8 +208,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
- tc.RealVariableDouble = -154.789;
- tc.RealVariableFloat = -154.789f;
+ tc.LRealVariable = -154.789;
+ tc.RealVariable = -154.789f;
tc.DWordVariable = 850;
plc.WriteStruct(tc, DB2);
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
@@ -225,8 +218,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10);
Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable);
Assert.AreEqual(tc.IntVariable, tc2.IntVariable);
- Assert.AreEqual(tc.RealVariableDouble, Math.Round(tc2.RealVariableDouble, 3));
- Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
+ Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
+ Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -575,8 +568,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
- tc.RealVariableDouble = -154.789;
- tc.RealVariableFloat = -154.789f;
+ tc.LRealVariable = -154.789;
+ tc.RealVariable = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -588,8 +581,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.BitVariable10, tc2.BitVariable10);
Assert.AreEqual(tc.DIntVariable, tc2.DIntVariable);
Assert.AreEqual(tc.IntVariable, tc2.IntVariable);
- Assert.AreEqual(Math.Round(tc.RealVariableDouble, 3), Math.Round(tc2.RealVariableDouble, 3));
- Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
+ Assert.AreEqual(tc.LRealVariable, tc2.LRealVariable);
+ Assert.AreEqual(tc.RealVariable, tc2.RealVariable);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
Assert.AreEqual(TestClassWithPrivateSetters.PRIVATE_SETTER_VALUE, tc2.PrivateSetterProperty);
@@ -620,8 +613,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
- tc.RealVariableDouble = -154.789;
- tc.RealVariableFloat = -154.789f;
+ tc.LRealVariable = -154.789;
+ tc.RealVariable = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -635,8 +628,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc2.BitVariable10, tc2Generic.BitVariable10);
Assert.AreEqual(tc2.DIntVariable, tc2Generic.DIntVariable);
Assert.AreEqual(tc2.IntVariable, tc2Generic.IntVariable);
- Assert.AreEqual(Math.Round(tc2.RealVariableDouble, 3), Math.Round(tc2Generic.RealVariableDouble, 3));
- Assert.AreEqual(tc2.RealVariableFloat, tc2Generic.RealVariableFloat);
+ Assert.AreEqual(Math.Round(tc2.LRealVariable, 3), Math.Round(tc2Generic.LRealVariable, 3));
+ Assert.AreEqual(tc2.RealVariable, tc2Generic.RealVariable);
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
}
@@ -663,8 +656,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
- tc.RealVariableDouble = -154.789;
- tc.RealVariableFloat = -154.789f;
+ tc.LRealVariable = -154.789;
+ tc.RealVariable = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -677,8 +670,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc2Generic.BitVariable10, tc2GenericWithClassFactory.BitVariable10);
Assert.AreEqual(tc2Generic.DIntVariable, tc2GenericWithClassFactory.DIntVariable);
Assert.AreEqual(tc2Generic.IntVariable, tc2GenericWithClassFactory.IntVariable);
- Assert.AreEqual(Math.Round(tc2Generic.RealVariableDouble, 3), Math.Round(tc2GenericWithClassFactory.RealVariableDouble, 3));
- Assert.AreEqual(tc2Generic.RealVariableFloat, tc2GenericWithClassFactory.RealVariableFloat);
+ Assert.AreEqual(Math.Round(tc2Generic.LRealVariable, 3), Math.Round(tc2GenericWithClassFactory.LRealVariable, 3));
+ Assert.AreEqual(tc2Generic.RealVariable, tc2GenericWithClassFactory.RealVariable);
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
}
@@ -786,8 +779,8 @@ namespace S7.Net.UnitTest
ts.BitVariable10 = true;
ts.DIntVariable = -100000;
ts.IntVariable = -15000;
- ts.RealVariableDouble = -154.789;
- ts.RealVariableFloat = -154.789f;
+ ts.LRealVariable = -154.789;
+ ts.RealVariable = -154.789f;
ts.DWordVariable = 850;
plc.WriteStruct(ts, DB2);
@@ -800,8 +793,8 @@ namespace S7.Net.UnitTest
Assert.AreEqual(ts2.BitVariable10, ts2Generic.BitVariable10);
Assert.AreEqual(ts2.DIntVariable, ts2Generic.DIntVariable);
Assert.AreEqual(ts2.IntVariable, ts2Generic.IntVariable);
- Assert.AreEqual(Math.Round(ts2.RealVariableDouble, 3), Math.Round(ts2Generic.RealVariableDouble, 3));
- Assert.AreEqual(ts2.RealVariableFloat, ts2Generic.RealVariableFloat);
+ Assert.AreEqual(ts2.LRealVariable, ts2Generic.LRealVariable);
+ Assert.AreEqual(ts2.RealVariable, ts2Generic.RealVariable);
Assert.AreEqual(ts2.DWordVariable, ts2Generic.DWordVariable);
}
@@ -831,8 +824,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
- tc.RealVariableDouble = -154.789;
- tc.RealVariableFloat = -154.789f;
+ tc.LRealVariable = -154.789;
+ tc.RealVariable = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -948,11 +941,10 @@ namespace S7.Net.UnitTest
public void T26_ReadWriteDouble()
{
double test_value = 55.66;
- plc.Write("DB1.DBD0", test_value);
- var helper = plc.Read("DB1.DBD0");
- double test_value2 = Conversion.ConvertToDouble((uint)helper);
+ plc.Write(DataType.DataBlock, 1, 0, test_value);
+ var result = (double)plc.Read(DataType.DataBlock, 1, 0, VarType.LReal, 1);
- Assert.AreEqual(test_value, test_value2, 0.01, "Compare Write/Read"); //Need delta here because S7 only has 32 bit reals
+ Assert.AreEqual(test_value, result, "Compare Write/Read");
}
[TestMethod]
diff --git a/S7.Net/Conversion.cs b/S7.Net/Conversion.cs
index 09cdd4d..44f9e25 100644
--- a/S7.Net/Conversion.cs
+++ b/S7.Net/Conversion.cs
@@ -199,19 +199,6 @@ namespace S7.Net
return output;
}
- ///
- /// Converts from double to DWord (DBD)
- ///
- ///
- ///
- [Obsolete("Double support is obsolete. Use ConvertToUInt(float) instead.")]
- public static UInt32 ConvertToUInt(this double input)
- {
- uint output;
- output = S7.Net.Types.DWord.FromByteArray(S7.Net.Types.Double.ToByteArray(input));
- return output;
- }
-
///
/// Converts from float to DWord (DBD)
///
@@ -220,20 +207,7 @@ namespace S7.Net
public static UInt32 ConvertToUInt(this float input)
{
uint output;
- output = S7.Net.Types.DWord.FromByteArray(S7.Net.Types.Single.ToByteArray(input));
- return output;
- }
-
- ///
- /// Converts from DWord (DBD) to double
- ///
- ///
- ///
- [Obsolete("Double support is obsolete. Use ConvertToFloat(uint) instead.")]
- public static double ConvertToDouble(this uint input)
- {
- double output;
- output = S7.Net.Types.Double.FromByteArray(S7.Net.Types.DWord.ToByteArray(input));
+ output = S7.Net.Types.DWord.FromByteArray(S7.Net.Types.Real.ToByteArray(input));
return output;
}
@@ -245,7 +219,7 @@ namespace S7.Net
public static float ConvertToFloat(this uint input)
{
float output;
- output = S7.Net.Types.Single.FromByteArray(S7.Net.Types.DWord.ToByteArray(input));
+ output = S7.Net.Types.Real.FromByteArray(S7.Net.Types.DWord.ToByteArray(input));
return output;
}
}
diff --git a/S7.Net/Enums.cs b/S7.Net/Enums.cs
index 6082d28..fdb96ff 100644
--- a/S7.Net/Enums.cs
+++ b/S7.Net/Enums.cs
@@ -163,6 +163,11 @@
///
Real,
+ ///
+ /// LReal variable type (64 bits, 8 bytes)
+ ///
+ LReal,
+
///
/// String variable type (variable)
///
diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs
index 9325f8a..ae1ff29 100644
--- a/S7.Net/PLCHelpers.cs
+++ b/S7.Net/PLCHelpers.cs
@@ -111,9 +111,14 @@ namespace S7.Net
return DInt.ToArray(bytes);
case VarType.Real:
if (varCount == 1)
- return Types.Single.FromByteArray(bytes);
+ return Types.Real.FromByteArray(bytes);
else
- return Types.Single.ToArray(bytes);
+ return Types.Real.ToArray(bytes);
+ case VarType.LReal:
+ if (varCount == 1)
+ return Types.LReal.FromByteArray(bytes);
+ else
+ return Types.LReal.ToArray(bytes);
case VarType.String:
return Types.String.FromByteArray(bytes);
@@ -192,6 +197,7 @@ namespace S7.Net
case VarType.DInt:
case VarType.Real:
return varCount * 4;
+ case VarType.LReal:
case VarType.DateTime:
return varCount * 8;
case VarType.DateTimeLong:
diff --git a/S7.Net/Protocol/Serialization.cs b/S7.Net/Protocol/Serialization.cs
index 66142c2..de7fb84 100644
--- a/S7.Net/Protocol/Serialization.cs
+++ b/S7.Net/Protocol/Serialization.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using S7.Net.Types;
namespace S7.Net.Protocol
@@ -37,10 +38,10 @@ namespace S7.Net.Protocol
return Types.DInt.ToByteArray((Int32)value);
case "UInt32":
return Types.DWord.ToByteArray((UInt32)value);
- case "Double":
- return Types.Double.ToByteArray((double)value);
case "Single":
- return Types.Single.ToByteArray((float)value);
+ return Types.Real.ToByteArray((float)value);
+ case "Double":
+ return Types.LReal.ToByteArray((double)value);
case "DateTime":
return Types.DateTime.ToByteArray((System.DateTime) value);
case "Byte[]":
@@ -53,10 +54,10 @@ namespace S7.Net.Protocol
return Types.DInt.ToByteArray((Int32[])value);
case "UInt32[]":
return Types.DWord.ToByteArray((UInt32[])value);
- case "Double[]":
- return Types.Double.ToByteArray((double[])value);
case "Single[]":
- return Types.Single.ToByteArray((float[])value);
+ return Types.Real.ToByteArray((float[])value);
+ case "Double[]":
+ return Types.LReal.ToByteArray((double[])value);
case "String":
// Hack: This is backwards compatible with the old code, but functionally it's broken
// if the consumer does not pay attention to string length.
diff --git a/S7.Net/Types/Class.cs b/S7.Net/Types/Class.cs
index ab76f8d..ecb59ac 100644
--- a/S7.Net/Types/Class.cs
+++ b/S7.Net/Types/Class.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Reflection;
@@ -51,12 +52,17 @@ namespace S7.Net.Types
numBytes += 4;
break;
case "Single":
- case "Double":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
numBytes += 4;
break;
+ case "Double":
+ numBytes = Math.Ceiling(numBytes);
+ if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
+ numBytes++;
+ numBytes += 8;
+ break;
default:
var propertyClass = Activator.CreateInstance(type);
numBytes = GetClassSize(propertyClass, numBytes, true);
@@ -168,12 +174,12 @@ namespace S7.Net.Types
bytes[(int)numBytes + 3]);
numBytes += 4;
break;
- case "Double":
+ case "Single":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
// hier auswerten
- value = Double.FromByteArray(
+ value = Real.FromByteArray(
new byte[] {
bytes[(int)numBytes],
bytes[(int)numBytes + 1],
@@ -181,18 +187,15 @@ namespace S7.Net.Types
bytes[(int)numBytes + 3] });
numBytes += 4;
break;
- case "Single":
+ case "Double":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
+ var buffer = new byte[8];
+ Array.Copy(bytes, (int)numBytes, buffer, 0, 8);
// hier auswerten
- value = Single.FromByteArray(
- new byte[] {
- bytes[(int)numBytes],
- bytes[(int)numBytes + 1],
- bytes[(int)numBytes + 2],
- bytes[(int)numBytes + 3] });
- numBytes += 4;
+ value = LReal.FromByteArray(buffer);
+ numBytes += 8;
break;
default:
var propClass = Activator.CreateInstance(propertyType);
@@ -277,11 +280,11 @@ namespace S7.Net.Types
case "UInt32":
bytes2 = DWord.ToByteArray((UInt32)propertyValue);
break;
- case "Double":
- bytes2 = Double.ToByteArray((double)propertyValue);
- break;
case "Single":
- bytes2 = Single.ToByteArray((float)propertyValue);
+ bytes2 = Real.ToByteArray((float)propertyValue);
+ break;
+ case "Double":
+ bytes2 = LReal.ToByteArray((double)propertyValue);
break;
default:
numBytes = ToBytes(propertyValue, bytes, numBytes);
diff --git a/S7.Net/Types/Double.cs b/S7.Net/Types/Double.cs
index 857784f..c9daf24 100644
--- a/S7.Net/Types/Double.cs
+++ b/S7.Net/Types/Double.cs
@@ -5,27 +5,13 @@ namespace S7.Net.Types
///
/// Contains the conversion methods to convert Real from S7 plc to C# double.
///
+ [Obsolete("Class Double is obsolete. Use Real instead for 32bit floating point, or LReal for 64bit floating point.")]
public static class Double
{
///
/// Converts a S7 Real (4 bytes) to double
///
- public static double FromByteArray(byte[] bytes)
- {
- if (bytes.Length != 4)
- {
- throw new ArgumentException("Wrong number of bytes. Bytes array must contain 4 bytes.");
- }
-
- // sps uses bigending so we have to reverse if platform needs
- if (BitConverter.IsLittleEndian)
- {
- // create deep copy of the array and reverse
- bytes = new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
- }
-
- return BitConverter.ToSingle(bytes, 0);
- }
+ public static double FromByteArray(byte[] bytes) => Real.FromByteArray(bytes);
///
/// Converts a S7 DInt to double
@@ -51,16 +37,7 @@ namespace S7.Net.Types
///
/// Converts a double to S7 Real (4 bytes)
///
- public static byte[] ToByteArray(double value)
- {
- byte[] bytes = BitConverter.GetBytes((float)(value));
-
- // sps uses bigending so we have to check if platform is same
- if (!BitConverter.IsLittleEndian) return bytes;
-
- // create deep copy of the array and reverse
- return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
- }
+ public static byte[] ToByteArray(double value) => Real.ToByteArray((float)value);
///
/// Converts an array of double to an array of bytes
diff --git a/S7.Net/Types/LReal.cs b/S7.Net/Types/LReal.cs
new file mode 100644
index 0000000..c541645
--- /dev/null
+++ b/S7.Net/Types/LReal.cs
@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+
+namespace S7.Net.Types
+{
+ ///
+ /// Contains the conversion methods to convert Real from S7 plc to C# double.
+ ///
+ public static class LReal
+ {
+ ///
+ /// Converts a S7 LReal (8 bytes) to double
+ ///
+ public static double FromByteArray(byte[] bytes)
+ {
+ if (bytes.Length != 8)
+ {
+ throw new ArgumentException("Wrong number of bytes. Bytes array must contain 8 bytes.");
+ }
+ var buffer = bytes;
+
+ // sps uses bigending so we have to reverse if platform needs
+ if (BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(buffer);
+ }
+
+ return BitConverter.ToDouble(buffer, 0);
+ }
+
+ ///
+ /// Converts a double to S7 LReal (8 bytes)
+ ///
+ public static byte[] ToByteArray(double value)
+ {
+ var bytes = BitConverter.GetBytes(value);
+
+ // sps uses bigending so we have to check if platform is same
+ if (BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(bytes);
+ }
+ return bytes;
+ }
+
+ ///
+ /// Converts an array of double to an array of bytes
+ ///
+ public static byte[] ToByteArray(double[] value) => TypeHelper.ToByteArray(value, ToByteArray);
+
+ ///
+ /// Converts an array of S7 LReal to an array of double
+ ///
+ public static double[] ToArray(byte[] bytes) => TypeHelper.ToArray(bytes, FromByteArray);
+
+ }
+}
diff --git a/S7.Net/Types/Real.cs b/S7.Net/Types/Real.cs
new file mode 100644
index 0000000..1d28202
--- /dev/null
+++ b/S7.Net/Types/Real.cs
@@ -0,0 +1,75 @@
+using System;
+using System.IO;
+
+namespace S7.Net.Types
+{
+ ///
+ /// Contains the conversion methods to convert Real from S7 plc to C# double.
+ ///
+ public static class Real
+ {
+ ///
+ /// Converts a S7 Real (4 bytes) to float
+ ///
+ public static float FromByteArray(byte[] bytes)
+ {
+ if (bytes.Length != 4)
+ {
+ throw new ArgumentException("Wrong number of bytes. Bytes array must contain 4 bytes.");
+ }
+
+ // sps uses bigending so we have to reverse if platform needs
+ if (BitConverter.IsLittleEndian)
+ {
+ // create deep copy of the array and reverse
+ bytes = new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
+ }
+
+ return BitConverter.ToSingle(bytes, 0);
+ }
+
+ ///
+ /// Converts a float to S7 Real (4 bytes)
+ ///
+ public static byte[] ToByteArray(float value)
+ {
+ byte[] bytes = BitConverter.GetBytes(value);
+
+ // sps uses bigending so we have to check if platform is same
+ if (!BitConverter.IsLittleEndian) return bytes;
+
+ // create deep copy of the array and reverse
+ return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
+ }
+
+ ///
+ /// Converts an array of float to an array of bytes
+ ///
+ public static byte[] ToByteArray(float[] value)
+ {
+ var buffer = new byte[4 * value.Length];
+ var stream = new MemoryStream(buffer);
+ foreach (var val in value)
+ {
+ stream.Write(ToByteArray(val), 0, 4);
+ }
+
+ return buffer;
+ }
+
+ ///
+ /// Converts an array of S7 Real to an array of float
+ ///
+ public static float[] ToArray(byte[] bytes)
+ {
+ var values = new float[bytes.Length / 4];
+
+ int counter = 0;
+ for (int cnt = 0; cnt < bytes.Length / 4; cnt++)
+ values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] });
+
+ return values;
+ }
+
+ }
+}
diff --git a/S7.Net/Types/Single.cs b/S7.Net/Types/Single.cs
index 3121efa..4f27553 100644
--- a/S7.Net/Types/Single.cs
+++ b/S7.Net/Types/Single.cs
@@ -5,27 +5,13 @@ namespace S7.Net.Types
///
/// Contains the conversion methods to convert Real from S7 plc to C# float.
///
+ [Obsolete("Class Single is obsolete. Use Real instead.")]
public static class Single
{
///
/// Converts a S7 Real (4 bytes) to float
///
- public static float FromByteArray(byte[] bytes)
- {
- if (bytes.Length != 4)
- {
- throw new ArgumentException("Wrong number of bytes. Bytes array must contain 4 bytes.");
- }
-
- // sps uses bigending so we have to reverse if platform needs
- if (BitConverter.IsLittleEndian)
- {
- // create deep copy of the array and reverse
- bytes = new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
- }
-
- return BitConverter.ToSingle(bytes, 0);
- }
+ public static float FromByteArray(byte[] bytes) => Real.FromByteArray(bytes);
///
/// Converts a S7 DInt to float
@@ -51,16 +37,7 @@ namespace S7.Net.Types
///
/// Converts a double to S7 Real (4 bytes)
///
- public static byte[] ToByteArray(float value)
- {
- byte[] bytes = BitConverter.GetBytes((float)(value));
-
- // sps uses bigending so we have to check if platform is same
- if (!BitConverter.IsLittleEndian) return bytes;
-
- // create deep copy of the array and reverse
- return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
- }
+ public static byte[] ToByteArray(float value) => Real.ToByteArray(value);
///
/// Converts an array of float to an array of bytes
diff --git a/S7.Net/Types/Struct.cs b/S7.Net/Types/Struct.cs
index 733800a..1e126a5 100644
--- a/S7.Net/Types/Struct.cs
+++ b/S7.Net/Types/Struct.cs
@@ -50,12 +50,17 @@ namespace S7.Net.Types
numBytes += 4;
break;
case "Single":
- case "Double":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
numBytes += 4;
break;
+ case "Double":
+ numBytes = Math.Ceiling(numBytes);
+ if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
+ numBytes++;
+ numBytes += 8;
+ break;
default:
numBytes += GetStructSize(info.FieldType);
break;
@@ -152,28 +157,27 @@ namespace S7.Net.Types
bytes[(int)numBytes + 3]));
numBytes += 4;
break;
- case "Double":
- numBytes = Math.Ceiling(numBytes);
- if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
- numBytes++;
- // hier auswerten
- info.SetValue(structValue, Double.FromByteArray(new byte[] { bytes[(int)numBytes],
- bytes[(int)numBytes + 1],
- bytes[(int)numBytes + 2],
- bytes[(int)numBytes + 3] }));
- numBytes += 4;
- break;
case "Single":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
// hier auswerten
- info.SetValue(structValue, Single.FromByteArray(new byte[] { bytes[(int)numBytes],
+ info.SetValue(structValue, Real.FromByteArray(new byte[] { bytes[(int)numBytes],
bytes[(int)numBytes + 1],
bytes[(int)numBytes + 2],
bytes[(int)numBytes + 3] }));
numBytes += 4;
break;
+ case "Double":
+ numBytes = Math.Ceiling(numBytes);
+ if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
+ numBytes++;
+ // hier auswerten
+ var data = new byte[8];
+ Array.Copy(bytes, (int)numBytes, data, 0, 8);
+ info.SetValue(structValue, LReal.FromByteArray(data));
+ numBytes += 8;
+ break;
default:
var buffer = new byte[GetStructSize(info.FieldType)];
if (buffer.Length == 0)
@@ -244,11 +248,11 @@ namespace S7.Net.Types
case "UInt32":
bytes2 = DWord.ToByteArray((UInt32)info.GetValue(structValue));
break;
- case "Double":
- bytes2 = Double.ToByteArray((double)info.GetValue(structValue));
- break;
case "Single":
- bytes2 = Single.ToByteArray((float)info.GetValue(structValue));
+ bytes2 = Real.ToByteArray((float)info.GetValue(structValue));
+ break;
+ case "Double":
+ bytes2 = LReal.ToByteArray((double)info.GetValue(structValue));
break;
}
if (bytes2 != null)
diff --git a/S7.Net/Types/TypeHelper.cs b/S7.Net/Types/TypeHelper.cs
new file mode 100644
index 0000000..983299b
--- /dev/null
+++ b/S7.Net/Types/TypeHelper.cs
@@ -0,0 +1,43 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace S7.Net.Types
+{
+ internal static class TypeHelper
+ {
+ ///
+ /// Converts an array of T to an array of bytes
+ ///
+ public static byte[] ToByteArray(T[] value, Func converter) where T : struct
+ {
+ var buffer = new byte[Marshal.SizeOf(default(T)) * value.Length];
+ var stream = new MemoryStream(buffer);
+ foreach (var val in value)
+ {
+ stream.Write(converter(val), 0, 4);
+ }
+
+ return buffer;
+ }
+
+ ///
+ /// Converts an array of T repesented as S7 binary data to an array of T
+ ///
+ public static T[] ToArray(byte[] bytes, Func converter)
+ {
+ var typeSize = Marshal.SizeOf(default(T));
+ var entries = bytes.Length / typeSize;
+ var values = new T[entries];
+
+ for(int i = 0; i < entries; ++i)
+ {
+ var buffer = new byte[typeSize];
+ Array.Copy(bytes, i * typeSize, buffer, 0, typeSize);
+ values[i] = converter(buffer);
+ }
+
+ return values;
+ }
+ }
+}