Add support for datatype float (Single) and obsolete double (Double) usage

This commit is contained in:
Raphael
2018-07-02 10:14:47 +02:00
parent 534ecb2546
commit b8b144d7ae
11 changed files with 336 additions and 91 deletions

View File

@@ -35,16 +35,21 @@ namespace S7.Net.UnitTest.Helpers
/// <summary>
/// DB1.DBD4
/// </summary>
public double RealVariable { get; set; }
public double RealVariableDouble { get; set; }
/// <summary>
/// DB1.DBD8
/// </summary>
public int DIntVariable { get; set; }
public float RealVariableFloat { get; set; }
/// <summary>
/// DB1.DBD12
/// </summary>
public int DIntVariable { get; set; }
/// <summary>
/// DB1.DBD16
/// </summary>
public ushort DWordVariable { get; set; }
}
}

View File

@@ -15,10 +15,12 @@ namespace S7.UnitTest.Helpers
public ushort[] UShorts { get; set; } = new ushort[2];
public int[] Ints { get; set; } = new int[2];
public double[] Doubles { get; set; } = new double[2];
public float[] Singles { get; set; } = new float[2];
public short Short { get; set; }
public ushort UShort { get; set; }
public int Int { get; set; }
public double Double { get; set; }
public float Single { get; set; }
}
}

View File

@@ -35,16 +35,21 @@ namespace S7.Net.UnitTest.Helpers
/// <summary>
/// DB1.DBD4
/// </summary>
public double RealVariable;
public double RealVariableDouble;
/// <summary>
/// DB1.DBD8
/// </summary>
public int DIntVariable;
public float RealVariableFloat;
/// <summary>
/// DB1.DBD12
/// </summary>
public int DIntVariable;
/// <summary>
/// DB1.DBD16
/// </summary>
public ushort DWordVariable;
}
}

View File

@@ -32,7 +32,7 @@ using System.Threading.Tasks;
*
*/
//Tests for Async Methods
//Tests for Async Methods
namespace S7.Net.UnitTest
{
@@ -85,9 +85,9 @@ namespace S7.Net.UnitTest
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
// To write a uint I don't need any cast, only unboxing must be done
uint val = 1000;
int val = 1000;
await plc.WriteAsync("DB1.DBD40", val);
uint result = (uint)await plc.ReadAsync("DB1.DBD40");
int result = ((uint)await plc.ReadAsync("DB1.DBD40")).ConvertToInt();
Assert.AreEqual(val, result);
// To write a int I need to convert it to uint, then I need to reconvert the readed value to get
@@ -110,10 +110,22 @@ namespace S7.Net.UnitTest
// 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.687;
await plc.WriteAsync ("DB1.DBD40", val.ConvertToUInt());
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, 3)); // float lose precision, so i need to round it
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;
await plc.WriteAsync("DB1.DBD40", val2.ConvertToUInt());
float result2 = ((uint)await plc.ReadAsync("DB1.DBD40")).ConvertToFloat();
Assert.AreEqual(val2, result2);
float val3 = 12.34567f;
await plc.WriteAsync("DB1.DBD40", val3.ConvertToUInt());
float result3 = ((uint)await plc.ReadAsync("DB1.DBD40")).ConvertToFloat();
Assert.AreEqual(val3, result3);
}
/// <summary>
@@ -130,7 +142,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
@@ -142,7 +155,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.RealVariable, Math.Round(tc2.RealVariable, 3));
Assert.AreEqual(tc.RealVariableDouble, Math.Round(tc2.RealVariableDouble, 3));
Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -160,7 +174,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
plc.WriteStruct(tc, DB2);
@@ -170,7 +185,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.RealVariable, Math.Round(tc2.RealVariable, 3));
Assert.AreEqual(tc.RealVariableDouble, Math.Round(tc2.RealVariableDouble, 3));
Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -214,26 +230,26 @@ namespace S7.Net.UnitTest
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
TestLongStruct tc2 = (TestLongStruct)await plc.ReadStructAsync(typeof(TestLongStruct), DB2);
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
Assert.AreEqual( tc.IntVariable0, tc2.IntVariable0 );
Assert.AreEqual( tc.IntVariable1, tc2.IntVariable1 );
Assert.AreEqual( tc.IntVariable10, tc2.IntVariable10);
Assert.AreEqual( tc.IntVariable11, tc2.IntVariable11);
Assert.AreEqual( tc.IntVariable20, tc2.IntVariable20);
Assert.AreEqual( tc.IntVariable21, tc2.IntVariable21);
Assert.AreEqual( tc.IntVariable30, tc2.IntVariable30);
Assert.AreEqual( tc.IntVariable31, tc2.IntVariable31);
Assert.AreEqual( tc.IntVariable40, tc2.IntVariable40);
Assert.AreEqual( tc.IntVariable41, tc2.IntVariable41);
Assert.AreEqual( tc.IntVariable50, tc2.IntVariable50);
Assert.AreEqual( tc.IntVariable51, tc2.IntVariable51);
Assert.AreEqual( tc.IntVariable60, tc2.IntVariable60);
Assert.AreEqual( tc.IntVariable61, tc2.IntVariable61);
Assert.AreEqual( tc.IntVariable70, tc2.IntVariable70);
Assert.AreEqual( tc.IntVariable71, tc2.IntVariable71);
Assert.AreEqual( tc.IntVariable80, tc2.IntVariable80);
Assert.AreEqual( tc.IntVariable81, tc2.IntVariable81);
Assert.AreEqual( tc.IntVariable90, tc2.IntVariable90);
Assert.AreEqual(tc.IntVariable91, tc2.IntVariable91);
Assert.AreEqual(tc.IntVariable0, tc2.IntVariable0);
Assert.AreEqual(tc.IntVariable1, tc2.IntVariable1);
Assert.AreEqual(tc.IntVariable10, tc2.IntVariable10);
Assert.AreEqual(tc.IntVariable11, tc2.IntVariable11);
Assert.AreEqual(tc.IntVariable20, tc2.IntVariable20);
Assert.AreEqual(tc.IntVariable21, tc2.IntVariable21);
Assert.AreEqual(tc.IntVariable30, tc2.IntVariable30);
Assert.AreEqual(tc.IntVariable31, tc2.IntVariable31);
Assert.AreEqual(tc.IntVariable40, tc2.IntVariable40);
Assert.AreEqual(tc.IntVariable41, tc2.IntVariable41);
Assert.AreEqual(tc.IntVariable50, tc2.IntVariable50);
Assert.AreEqual(tc.IntVariable51, tc2.IntVariable51);
Assert.AreEqual(tc.IntVariable60, tc2.IntVariable60);
Assert.AreEqual(tc.IntVariable61, tc2.IntVariable61);
Assert.AreEqual(tc.IntVariable70, tc2.IntVariable70);
Assert.AreEqual(tc.IntVariable71, tc2.IntVariable71);
Assert.AreEqual(tc.IntVariable80, tc2.IntVariable80);
Assert.AreEqual(tc.IntVariable81, tc2.IntVariable81);
Assert.AreEqual(tc.IntVariable90, tc2.IntVariable90);
Assert.AreEqual(tc.IntVariable91, tc2.IntVariable91);
Assert.AreEqual(tc.IntVariable100, tc2.IntVariable100);
Assert.AreEqual(tc.IntVariable101, tc2.IntVariable101);
Assert.AreEqual(tc.IntVariable110, tc2.IntVariable110);
@@ -527,7 +543,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
@@ -541,7 +558,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.RealVariable, tc2.RealVariable, 0.1);
Assert.AreEqual(tc.RealVariableDouble, tc2.RealVariableDouble, 0.1);
Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
Assert.AreEqual(TestClassWithPrivateSetters.PRIVATE_SETTER_VALUE, tc2.PrivateSetterProperty);
@@ -575,7 +593,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
@@ -591,7 +610,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.RealVariable, 3), Math.Round(tc2Generic.RealVariable, 3));
Assert.AreEqual(Math.Round(tc2.RealVariableDouble, 3), Math.Round(tc2Generic.RealVariableDouble, 3));
Assert.AreEqual(tc2.RealVariableFloat, tc2Generic.RealVariableFloat);
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
}
@@ -617,7 +637,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
@@ -630,8 +651,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(tc2Generic.IntVariable, tc2GenericWithClassFactory.IntVariable);
Assert.AreEqual(Math.Round(tc2Generic.RealVariable, 3), Math.Round(tc2GenericWithClassFactory.RealVariable, 3));
Assert.AreEqual(Math.Round(tc2Generic.RealVariableDouble, 3), Math.Round(tc2GenericWithClassFactory.RealVariableDouble, 3));
Assert.AreEqual(tc2Generic.RealVariableFloat, tc2GenericWithClassFactory.RealVariableFloat);
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
}
@@ -668,7 +689,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
@@ -683,7 +705,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.RealVariable, 3), Math.Round(ts2Generic.RealVariable, 3));
Assert.AreEqual(Math.Round(ts2.RealVariableDouble, 3), Math.Round(ts2Generic.RealVariableDouble, 3));
Assert.AreEqual(ts2.RealVariableFloat, ts2Generic.RealVariableFloat);
Assert.AreEqual(ts2.DWordVariable, ts2Generic.DWordVariable);
}
@@ -712,7 +735,8 @@ namespace S7.Net.UnitTest
BitVariable10 = true,
DIntVariable = -100000,
IntVariable = -15000,
RealVariable = -154.789,
RealVariableDouble = -154.789,
RealVariableFloat = -154.789f,
DWordVariable = 850
};
plc.WriteClass(tc, DB2);
@@ -726,7 +750,7 @@ namespace S7.Net.UnitTest
Assert.AreEqual(expectedReadBytes, actualReadBytes);
}
[TestMethod]
public async Task Test_Async_ReadClassWithArray()
{
@@ -815,6 +839,19 @@ namespace S7.Net.UnitTest
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()
{
float test_value = 55.6632f;
await plc.WriteAsync("DB1.DBD0", test_value);
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Write Single");
var helper = await plc.ReadAsync("DB1.DBD0");
float test_value2 = Conversion.ConvertToFloat((uint)helper);
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Read Single");
Assert.AreEqual(test_value, test_value2, "Compare Write/Read"); //No delta, datatype matches
}
[TestMethod]
public async Task Test_Async_ReadWriteBytesMany()
{
@@ -824,14 +861,14 @@ namespace S7.Net.UnitTest
var dataItems = new List<byte>();
for (int i = 0; i < count; i++)
{
dataItems.Add((byte)(i%256));
dataItems.Add((byte)(i % 256));
}
await plc.WriteBytesAsync(DataType.DataBlock, 2, 0, dataItems.ToArray());
var res = await plc.ReadBytesAsync(DataType.DataBlock, 2, 0, count);
for (int x = 0; x < count; x++)
for (int x = 0; x < count; x++)
{
Assert.AreEqual(x % 256, res[x], string.Format("Bit {0} failed", x));
}

View File

@@ -148,10 +148,22 @@ namespace S7.Net.UnitTest
// 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.687;
double val = 35.68729;
plc.Write("DB1.DBD40", val.ConvertToUInt());
double result = ((uint)plc.Read("DB1.DBD40")).ConvertToDouble();
Assert.AreEqual(val, Math.Round(result, 3)); // float lose precision, so i need to round it
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;
plc.Write("DB1.DBD40", val2.ConvertToUInt());
float result2 = ((uint)plc.Read("DB1.DBD40")).ConvertToFloat();
Assert.AreEqual(val2, result2);
float val3 = 12.34567f;
plc.Write("DB1.DBD40", val3.ConvertToUInt());
float result3 = ((uint)plc.Read("DB1.DBD40")).ConvertToFloat();
Assert.AreEqual(val3, result3);
}
/// <summary>
@@ -167,7 +179,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
tc.RealVariable = -154.789;
tc.RealVariableDouble = -154.789;
tc.RealVariableFloat = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
TestClass tc2 = new TestClass();
@@ -177,7 +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(tc.RealVariable, Math.Round(tc2.RealVariable, 3));
Assert.AreEqual(Math.Round(tc.RealVariableDouble, 3), Math.Round(tc2.RealVariableDouble, 3));
Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -194,7 +208,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
tc.RealVariable = -154.789;
tc.RealVariableDouble = -154.789;
tc.RealVariableFloat = -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
@@ -203,7 +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.RealVariable, Math.Round(tc2.RealVariable, 3));
Assert.AreEqual(tc.RealVariableDouble, Math.Round(tc2.RealVariableDouble, 3));
Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
}
@@ -556,7 +572,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
tc.RealVariable = -154.789;
tc.RealVariableDouble = -154.789;
tc.RealVariableFloat = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -568,7 +585,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.RealVariable, Math.Round(tc2.RealVariable, 3));
Assert.AreEqual(Math.Round(tc.RealVariableDouble, 3), Math.Round(tc2.RealVariableDouble, 3));
Assert.AreEqual(tc.RealVariableFloat, tc2.RealVariableFloat);
Assert.AreEqual(tc.DWordVariable, tc2.DWordVariable);
Assert.AreEqual(TestClassWithPrivateSetters.PRIVATE_SETTER_VALUE, tc2.PrivateSetterProperty);
@@ -604,7 +622,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
tc.RealVariable = -154.789;
tc.RealVariableDouble = -154.789;
tc.RealVariableFloat = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -618,7 +637,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.RealVariable, 3), Math.Round(tc2Generic.RealVariable, 3));
Assert.AreEqual(Math.Round(tc2.RealVariableDouble, 3), Math.Round(tc2Generic.RealVariableDouble, 3));
Assert.AreEqual(tc2.RealVariableFloat, tc2Generic.RealVariableFloat);
Assert.AreEqual(tc2.DWordVariable, tc2Generic.DWordVariable);
}
@@ -645,7 +665,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
tc.RealVariable = -154.789;
tc.RealVariableDouble = -154.789;
tc.RealVariableFloat = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -658,7 +679,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.RealVariable, 3), Math.Round(tc2GenericWithClassFactory.RealVariable, 3));
Assert.AreEqual(Math.Round(tc2Generic.RealVariableDouble, 3), Math.Round(tc2GenericWithClassFactory.RealVariableDouble, 3));
Assert.AreEqual(tc2Generic.RealVariableFloat, tc2GenericWithClassFactory.RealVariableFloat);
Assert.AreEqual(tc2Generic.DWordVariable, tc2GenericWithClassFactory.DWordVariable);
}
@@ -698,7 +720,8 @@ namespace S7.Net.UnitTest
ts.BitVariable10 = true;
ts.DIntVariable = -100000;
ts.IntVariable = -15000;
ts.RealVariable = -154.789;
ts.RealVariableDouble = -154.789;
ts.RealVariableFloat = -154.789f;
ts.DWordVariable = 850;
plc.WriteStruct(ts, DB2);
@@ -711,7 +734,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.RealVariable, 3), Math.Round(ts2Generic.RealVariable, 3));
Assert.AreEqual(Math.Round(ts2.RealVariableDouble, 3), Math.Round(ts2Generic.RealVariableDouble, 3));
Assert.AreEqual(ts2.RealVariableFloat, ts2Generic.RealVariableFloat);
Assert.AreEqual(ts2.DWordVariable, ts2Generic.DWordVariable);
}
@@ -741,7 +765,8 @@ namespace S7.Net.UnitTest
tc.BitVariable10 = true;
tc.DIntVariable = -100000;
tc.IntVariable = -15000;
tc.RealVariable = -154.789;
tc.RealVariableDouble = -154.789;
tc.RealVariableFloat = -154.789f;
tc.DWordVariable = 850;
plc.WriteClass(tc, DB2);
@@ -771,6 +796,9 @@ namespace S7.Net.UnitTest
tc.Double = float.MinValue;
tc.Doubles[0] = float.MinValue + 1;
tc.Doubles[1] = float.MaxValue;
tc.Single = float.MinValue;
tc.Singles[0] = float.MinValue + 1;
tc.Singles[1] = float.MaxValue;
tc.UShort = ushort.MinValue + 1;
tc.UShorts[0] = ushort.MinValue + 1;
tc.UShorts[1] = ushort.MaxValue;
@@ -794,6 +822,10 @@ namespace S7.Net.UnitTest
Assert.AreEqual(tc.Doubles[0], tc2.Doubles[0]);
Assert.AreEqual(tc.Doubles[1], tc2.Doubles[1]);
Assert.AreEqual(tc.Single, tc2.Single);
Assert.AreEqual(tc.Singles[0], tc2.Singles[0]);
Assert.AreEqual(tc.Singles[1], tc2.Singles[1]);
Assert.AreEqual(tc.UShort, tc2.UShort);
Assert.AreEqual(tc.UShorts[0], tc2.UShorts[0]);
Assert.AreEqual(tc.UShorts[1], tc2.UShorts[1]);
@@ -912,6 +944,19 @@ namespace S7.Net.UnitTest
Assert.AreEqual(plc.LastErrorCode, ErrorCode.ReadData, "No Read Error.");
}
[TestMethod]
public void T30_ReadWriteSingle()
{
float test_value = 55.6632f;
plc.Write("DB1.DBD0", test_value);
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Write Single");
var helper = plc.Read("DB1.DBD0");
float test_value2 = Conversion.ConvertToFloat((uint)helper);
Assert.AreEqual(plc.LastErrorCode, ErrorCode.NoError, "Read Single");
Assert.AreEqual(test_value, test_value2, "Compare Write/Read"); //No delta, datatype matches
}
#endregion
#region Private methods

View File

@@ -130,7 +130,7 @@ namespace S7.Net
}
return txt;
}
catch
catch
{
return "";
}
@@ -204,23 +204,49 @@ namespace S7.Net
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static UInt32 ConvertToUInt(this double input)
[Obsolete("This method will soon be deprecated. 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;
}
/// <summary>
/// Converts from float to DWord (DBD)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static UInt32 ConvertToUInt(this float input)
{
uint output;
output = S7.Net.Types.DWord.FromByteArray(S7.Net.Types.Single.ToByteArray(input));
return output;
}
/// <summary>
/// Converts from DWord (DBD) to double
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[Obsolete("This method will soon be deprecated. 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));
return output;
}
/// <summary>
/// Converts from DWord (DBD) to float
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static float ConvertToFloat(this uint input)
{
float output;
output = S7.Net.Types.Single.FromByteArray(S7.Net.Types.DWord.ToByteArray(input));
return output;
}
}
}

View File

@@ -280,9 +280,9 @@ namespace S7.Net
return DInt.ToArray(bytes);
case VarType.Real:
if (varCount == 1)
return Types.Double.FromByteArray(bytes);
return Types.Single.FromByteArray(bytes);
else
return Types.Double.ToArray(bytes);
return Types.Single.ToArray(bytes);
case VarType.String:
return Types.String.FromByteArray(bytes);

View File

@@ -8,7 +8,7 @@ namespace S7.Net.Protocol
{
public static ushort GetWordAt(IList<byte> buf, int index)
{
return (ushort) ((buf[index] << 8) + buf[index]);
return (ushort)((buf[index] << 8) + buf[index]);
}
public static byte[] SerializeValue(object value)
@@ -16,31 +16,35 @@ namespace S7.Net.Protocol
switch (value.GetType().Name)
{
case "Boolean":
return new[] {(byte) ((bool) value ? 1 : 0)};
return new[] { (byte)((bool)value ? 1 : 0) };
case "Byte":
return Types.Byte.ToByteArray((byte) value);
return Types.Byte.ToByteArray((byte)value);
case "Int16":
return Types.Int.ToByteArray((Int16) value);
return Types.Int.ToByteArray((Int16)value);
case "UInt16":
return Types.Word.ToByteArray((UInt16) value);
return Types.Word.ToByteArray((UInt16)value);
case "Int32":
return Types.DInt.ToByteArray((Int32) value);
return Types.DInt.ToByteArray((Int32)value);
case "UInt32":
return Types.DWord.ToByteArray((UInt32) value);
return Types.DWord.ToByteArray((UInt32)value);
case "Double":
return Types.Double.ToByteArray((double) value);
return Types.Double.ToByteArray((double)value);
case "Single":
return Types.Single.ToByteArray((float)value);
case "Byte[]":
return (byte[]) value;
return (byte[])value;
case "Int16[]":
return Types.Int.ToByteArray((Int16[]) value);
return Types.Int.ToByteArray((Int16[])value);
case "UInt16[]":
return Types.Word.ToByteArray((UInt16[]) value);
return Types.Word.ToByteArray((UInt16[])value);
case "Int32[]":
return Types.DInt.ToByteArray((Int32[]) value);
return Types.DInt.ToByteArray((Int32[])value);
case "UInt32[]":
return Types.DWord.ToByteArray((UInt32[]) value);
return Types.DWord.ToByteArray((UInt32[])value);
case "Double[]":
return Types.Double.ToByteArray((double[]) value);
return Types.Double.ToByteArray((double[])value);
case "Single[]":
return Types.Single.ToByteArray((float[])value);
case "String":
return Types.String.ToByteArray(value as string);
default:
@@ -51,17 +55,17 @@ namespace S7.Net.Protocol
public static void SetAddressAt(ByteArray buffer, int index, int startByte, byte bitNumber)
{
var start = startByte * 8 + bitNumber;
buffer[index + 2] = (byte) start;
buffer[index + 2] = (byte)start;
start = start >> 8;
buffer[index + 1] = (byte) start;
buffer[index + 1] = (byte)start;
start = start >> 8;
buffer[index] = (byte) start;
buffer[index] = (byte)start;
}
public static void SetWordAt(ByteArray buffer, int index, ushort value)
{
buffer[index] = (byte) (value >> 8);
buffer[index + 1] = (byte) value;
buffer[index] = (byte)(value >> 8);
buffer[index + 1] = (byte)value;
}
}
}

View File

@@ -52,7 +52,7 @@ namespace S7.Net.Types
numBytes++;
numBytes += 4;
break;
case "Float":
case "Single":
case "Double":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
@@ -181,6 +181,19 @@ namespace S7.Net.Types
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
value = Single.FromByteArray(
new byte[] {
bytes[(int)numBytes],
bytes[(int)numBytes + 1],
bytes[(int)numBytes + 2],
bytes[(int)numBytes + 3] });
numBytes += 4;
break;
default:
var propClass = Activator.CreateInstance(propertyType);
var buffer = new byte[GetClassSize(propClass)];
@@ -276,6 +289,9 @@ namespace S7.Net.Types
case "Double":
bytes2 = Double.ToByteArray((double)propertyValue);
break;
case "Single":
bytes2 = Single.ToByteArray((float)propertyValue);
break;
default:
bytes2 = ToBytes(propertyValue);
break;

91
S7.Net/Types/Single.cs Normal file
View File

@@ -0,0 +1,91 @@
using System;
namespace S7.Net.Types
{
/// <summary>
/// Contains the conversion methods to convert Real from S7 plc to C# float.
/// </summary>
public static class Single
{
/// <summary>
/// Converts a S7 Real (4 bytes) to float
/// </summary>
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);
}
/// <summary>
/// Converts a S7 DInt to float
/// </summary>
public static float FromDWord(Int32 value)
{
byte[] b = DInt.ToByteArray(value);
float d = FromByteArray(b);
return d;
}
/// <summary>
/// Converts a S7 DWord to float
/// </summary>
public static float FromDWord(UInt32 value)
{
byte[] b = DWord.ToByteArray(value);
float d = FromByteArray(b);
return d;
}
/// <summary>
/// Converts a double to S7 Real (4 bytes)
/// </summary>
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] };
}
/// <summary>
/// Converts an array of float to an array of bytes
/// </summary>
public static byte[] ToByteArray(float[] value)
{
ByteArray arr = new ByteArray();
foreach (float val in value)
arr.Add(ToByteArray(val));
return arr.Array;
}
/// <summary>
/// Converts an array of S7 Real to an array of float
/// </summary>
public static float[] ToArray(byte[] bytes)
{
float[] 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;
}
}
}

View File

@@ -45,7 +45,7 @@ namespace S7.Net.Types
numBytes++;
numBytes += 4;
break;
case "Float":
case "Single":
case "Double":
numBytes = Math.Ceiling(numBytes);
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
@@ -126,8 +126,8 @@ namespace S7.Net.Types
uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3],
bytes[(int)numBytes + 2],
bytes[(int)numBytes + 1],
bytes[(int)numBytes + 0]);
info.SetValue(structValue, sourceUInt.ConvertToInt());
bytes[(int)numBytes + 0]);
info.SetValue(structValue, sourceUInt.ConvertToInt());
numBytes += 4;
break;
case "UInt32":
@@ -152,6 +152,17 @@ namespace S7.Net.Types
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],
bytes[(int)numBytes + 1],
bytes[(int)numBytes + 2],
bytes[(int)numBytes + 3] }));
numBytes += 4;
break;
default:
var buffer = new byte[GetStructSize(info.FieldType)];
if (buffer.Length == 0)
@@ -219,6 +230,9 @@ namespace S7.Net.Types
case "Double":
bytes2 = Double.ToByteArray((double)info.GetValue(structValue));
break;
case "Single":
bytes2 = Single.ToByteArray((float)info.GetValue(structValue));
break;
}
if (bytes2 != null)
{
@@ -227,7 +241,7 @@ namespace S7.Net.Types
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
numBytes++;
bytePos = (int)numBytes;
for (int bCnt=0; bCnt<bytes2.Length; bCnt++)
for (int bCnt = 0; bCnt < bytes2.Length; bCnt++)
bytes[bytePos + bCnt] = bytes2[bCnt];
numBytes += bytes2.Length;
}
@@ -235,6 +249,6 @@ namespace S7.Net.Types
return bytes;
}
}
}