mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-26 09:38:26 +08:00
S7.Net and S7.Net.Core unification (issue #56): moved files, updated csproj, minor modification for compatibility in SocketClient class.
Signed-off-by: Michele Cattafesta <michele.cattafesta@mesta-automation.com>
This commit is contained in:
1109
S7.Net.Core/PLC.cs
1109
S7.Net.Core/PLC.cs
File diff suppressed because it is too large
Load Diff
@@ -107,16 +107,61 @@
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PLC.cs" />
|
||||
<Compile Include="..\S7.Net\Conversion.cs">
|
||||
<Link>Conversion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Enums.cs">
|
||||
<Link>Enums.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\PLC.cs">
|
||||
<Link>PLC.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Boolean.cs">
|
||||
<Link>Types\Boolean.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Byte.cs">
|
||||
<Link>Types\Byte.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\ByteArray.cs">
|
||||
<Link>Types\ByteArray.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Class.cs">
|
||||
<Link>Types\Class.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Counter.cs">
|
||||
<Link>Types\Counter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\DataItem.cs">
|
||||
<Link>Types\DataItem.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\DInt.cs">
|
||||
<Link>Types\DInt.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Double.cs">
|
||||
<Link>Types\Double.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\DWord.cs">
|
||||
<Link>Types\DWord.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Int.cs">
|
||||
<Link>Types\Int.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\String.cs">
|
||||
<Link>Types\String.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Struct.cs">
|
||||
<Link>Types\Struct.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Timer.cs">
|
||||
<Link>Types\Timer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net\Types\Word.cs">
|
||||
<Link>Types\Word.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SocketClient.cs" />
|
||||
<EmbeddedResource Include="Properties\S7.Net.Core.rd.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\S7.Net.Common\**\*.*">
|
||||
<Link>%(RecursiveDir)%(FileName)</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace S7.Net
|
||||
_sendTimeout = milis;
|
||||
}
|
||||
|
||||
public int Send(byte[] buffer, int size)
|
||||
public int Send(byte[] buffer, int size, SocketFlags socketFlag)
|
||||
{
|
||||
var response = 0;
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace S7.Net
|
||||
return response;
|
||||
}
|
||||
|
||||
public int Receive(byte[] buffer, int size)
|
||||
public int Receive(byte[] buffer, int size, SocketFlags socketFlag)
|
||||
{
|
||||
var response = 0;
|
||||
|
||||
@@ -170,4 +170,54 @@ namespace S7.Net
|
||||
private const int TIMEOUT_MILLISECONDS = 1000;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Summary:
|
||||
// Specifies socket send and receive behaviors.
|
||||
[Flags]
|
||||
public enum SocketFlags
|
||||
{
|
||||
//
|
||||
// Summary:
|
||||
// Use no flags for this call.
|
||||
None = 0,
|
||||
//
|
||||
// Summary:
|
||||
// Process out-of-band data.
|
||||
OutOfBand = 1,
|
||||
//
|
||||
// Summary:
|
||||
// Peek at the incoming message.
|
||||
Peek = 2,
|
||||
//
|
||||
// Summary:
|
||||
// Send without using routing tables.
|
||||
DontRoute = 4,
|
||||
//
|
||||
// Summary:
|
||||
// Provides a standard value for the number of WSABUF structures that are used to
|
||||
// send and receive data.
|
||||
MaxIOVectorLength = 16,
|
||||
//
|
||||
// Summary:
|
||||
// The message was too large to fit into the specified buffer and was truncated.
|
||||
Truncated = 256,
|
||||
//
|
||||
// Summary:
|
||||
// Indicates that the control data did not fit into an internal 64-KB buffer and
|
||||
// was truncated.
|
||||
ControlDataTruncated = 512,
|
||||
//
|
||||
// Summary:
|
||||
// Indicates a broadcast packet.
|
||||
Broadcast = 1024,
|
||||
//
|
||||
// Summary:
|
||||
// Indicates a multicast packet.
|
||||
Multicast = 2048,
|
||||
//
|
||||
// Summary:
|
||||
// Partial send or receive for message.
|
||||
Partial = 32768
|
||||
}
|
||||
}
|
||||
235
S7.Net/Conversion.cs
Normal file
235
S7.Net/Conversion.cs
Normal file
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace S7.Net
|
||||
{
|
||||
public static class Conversion
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a binary string to Int32 value
|
||||
/// </summary>
|
||||
/// <param name="txt"></param>
|
||||
/// <returns></returns>
|
||||
public static int BinStringToInt32(this string txt)
|
||||
{
|
||||
int cnt = 0;
|
||||
int ret = 0;
|
||||
|
||||
for (cnt = txt.Length - 1; cnt >= 0; cnt += -1)
|
||||
{
|
||||
if (int.Parse(txt.Substring(cnt, 1)) == 1)
|
||||
{
|
||||
ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static byte? BinStringToByte(this string txt)
|
||||
{
|
||||
int cnt = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (txt.Length == 8)
|
||||
{
|
||||
for (cnt = 7; cnt >= 0; cnt += -1)
|
||||
{
|
||||
if (int.Parse(txt.Substring(cnt, 1)) == 1)
|
||||
{
|
||||
ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
|
||||
}
|
||||
}
|
||||
return (byte)ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the value to a binary string
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static string ValToBinString(this object value)
|
||||
{
|
||||
int cnt = 0;
|
||||
int cnt2 = 0;
|
||||
int x = 0;
|
||||
string txt = "";
|
||||
long longValue = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (value.GetType().Name.IndexOf("[]") < 0)
|
||||
{
|
||||
// ist nur ein Wert
|
||||
switch (value.GetType().Name)
|
||||
{
|
||||
case "Byte":
|
||||
x = 7;
|
||||
longValue = (long)((byte)value);
|
||||
break;
|
||||
case "Int16":
|
||||
x = 15;
|
||||
longValue = (long)((Int16)value);
|
||||
break;
|
||||
case "Int32":
|
||||
x = 31;
|
||||
longValue = (long)((Int32)value);
|
||||
break;
|
||||
case "Int64":
|
||||
x = 63;
|
||||
longValue = (long)((Int64)value);
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
for (cnt = x; cnt >= 0; cnt += -1)
|
||||
{
|
||||
if (((Int64)longValue & (Int64)Math.Pow(2, cnt)) > 0)
|
||||
txt += "1";
|
||||
else
|
||||
txt += "0";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ist ein Array
|
||||
switch (value.GetType().Name)
|
||||
{
|
||||
case "Byte[]":
|
||||
x = 7;
|
||||
byte[] ByteArr = (byte[])value;
|
||||
for (cnt2 = 0; cnt2 <= ByteArr.Length - 1; cnt2++)
|
||||
{
|
||||
for (cnt = x; cnt >= 0; cnt += -1)
|
||||
if ((ByteArr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0";
|
||||
}
|
||||
break;
|
||||
case "Int16[]":
|
||||
x = 15;
|
||||
Int16[] Int16Arr = (Int16[])value;
|
||||
for (cnt2 = 0; cnt2 <= Int16Arr.Length - 1; cnt2++)
|
||||
{
|
||||
for (cnt = x; cnt >= 0; cnt += -1)
|
||||
if ((Int16Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0";
|
||||
}
|
||||
break;
|
||||
case "Int32[]":
|
||||
x = 31;
|
||||
Int32[] Int32Arr = (Int32[])value;
|
||||
for (cnt2 = 0; cnt2 <= Int32Arr.Length - 1; cnt2++)
|
||||
{
|
||||
for (cnt = x; cnt >= 0; cnt += -1)
|
||||
if ((Int32Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0";
|
||||
}
|
||||
break;
|
||||
case "Int64[]":
|
||||
x = 63;
|
||||
byte[] Int64Arr = (byte[])value;
|
||||
for (cnt2 = 0; cnt2 <= Int64Arr.Length - 1; cnt2++)
|
||||
{
|
||||
for (cnt = x; cnt >= 0; cnt += -1)
|
||||
if ((Int64Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to get a bit value given a byte and the bit index.
|
||||
/// Example: DB1.DBX0.5 -> var bytes = ReadBytes(DB1.DBW0); bool bit = bytes[0].SelectBit(5);
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="bitPosition"></param>
|
||||
/// <returns></returns>
|
||||
public static bool SelectBit(this byte data, int bitPosition)
|
||||
{
|
||||
int mask = 1 << bitPosition;
|
||||
int result = data & mask;
|
||||
|
||||
return (result != 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts from ushort value to short value; it's used to retrieve negative values from words
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static short ConvertToShort(this ushort input)
|
||||
{
|
||||
short output;
|
||||
output = short.Parse(input.ToString("X"), NumberStyles.HexNumber);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts from short value to ushort value; it's used to pass negative values to DWs
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static ushort ConvertToUshort(this short input)
|
||||
{
|
||||
ushort output;
|
||||
output = ushort.Parse(input.ToString("X"), NumberStyles.HexNumber);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts from UInt32 value to Int32 value; it's used to retrieve negative values from DBDs
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static Int32 ConvertToInt(this uint input)
|
||||
{
|
||||
int output;
|
||||
output = int.Parse(input.ToString("X"), NumberStyles.HexNumber);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts from Int32 value to UInt32 value; it's used to pass negative values to DBDs
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static UInt32 ConvertToUInt(this int input)
|
||||
{
|
||||
uint output;
|
||||
output = uint.Parse(input.ToString("X"), NumberStyles.HexNumber);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts from double to DWord (DBD)
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
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 DWord (DBD) to double
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static double ConvertToDouble(this uint input)
|
||||
{
|
||||
double output;
|
||||
output = S7.Net.Types.Double.FromByteArray(S7.Net.Types.DWord.ToByteArray(input));
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
S7.Net/Enums.cs
Normal file
51
S7.Net/Enums.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace S7.Net
|
||||
{
|
||||
public enum CpuType
|
||||
{
|
||||
S7200 = 0,
|
||||
S7300 = 10,
|
||||
S7400 = 20,
|
||||
S71200 = 30,
|
||||
S71500 = 40,
|
||||
}
|
||||
|
||||
public enum ErrorCode
|
||||
{
|
||||
NoError = 0,
|
||||
WrongCPU_Type = 1,
|
||||
ConnectionError = 2,
|
||||
IPAddressNotAvailable,
|
||||
|
||||
WrongVarFormat = 10,
|
||||
WrongNumberReceivedBytes = 11,
|
||||
|
||||
SendData = 20,
|
||||
ReadData = 30,
|
||||
|
||||
WriteData = 50
|
||||
}
|
||||
|
||||
public enum DataType
|
||||
{
|
||||
Input = 129,
|
||||
Output = 130,
|
||||
Memory = 131,
|
||||
DataBlock = 132,
|
||||
Timer = 29,
|
||||
Counter = 28
|
||||
}
|
||||
|
||||
public enum VarType
|
||||
{
|
||||
Bit,
|
||||
Byte,
|
||||
Word,
|
||||
DWord,
|
||||
Int,
|
||||
DInt,
|
||||
Real,
|
||||
String,
|
||||
Timer,
|
||||
Counter
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,11 @@ namespace S7.Net
|
||||
{
|
||||
public class Plc : IDisposable
|
||||
{
|
||||
#if NETFX_CORE
|
||||
private SocketClient _mSocket; //TCP connection to device
|
||||
#else
|
||||
private Socket _mSocket; //TCP connection to device
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Ip address of the plc
|
||||
@@ -33,7 +37,7 @@ namespace S7.Net
|
||||
/// Slot of the CPU of the plc
|
||||
/// </summary>
|
||||
public Int16 Slot { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Pings the IP address and returns true if the result of the ping is Success.
|
||||
/// </summary>
|
||||
@@ -41,6 +45,9 @@ namespace S7.Net
|
||||
{
|
||||
get
|
||||
{
|
||||
#if NETFX_CORE
|
||||
return (!string.IsNullOrWhiteSpace(IP));
|
||||
#else
|
||||
using (Ping ping = new Ping())
|
||||
{
|
||||
PingReply result;
|
||||
@@ -54,9 +61,11 @@ namespace S7.Net
|
||||
}
|
||||
return result != null && result.Status == IPStatus.Success;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the socket is connected and polls the other peer (the plc) to see if it's connected.
|
||||
/// This is the variable that you should continously check to see if the communication is working
|
||||
@@ -70,8 +79,13 @@ namespace S7.Net
|
||||
{
|
||||
if (_mSocket == null)
|
||||
return false;
|
||||
|
||||
#if NETFX_CORE
|
||||
return _mSocket.Connected;
|
||||
#else
|
||||
return !((_mSocket.Poll(1000, SelectMode.SelectRead) && (_mSocket.Available == 0)) || !_mSocket.Connected);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
}
|
||||
@@ -128,14 +142,10 @@ namespace S7.Net
|
||||
return LastErrorCode;
|
||||
}
|
||||
|
||||
try {
|
||||
// open the channel
|
||||
_mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
_mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
|
||||
_mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
|
||||
|
||||
IPEndPoint server = new IPEndPoint(IPAddress.Parse(IP), 102);
|
||||
try
|
||||
{
|
||||
CreateSocket();
|
||||
IPEndPoint server = new IPEndPoint(IPAddress.Parse(IP), 102);
|
||||
_mSocket.Connect(server);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -324,7 +334,8 @@ namespace S7.Net
|
||||
|
||||
byte[] bReceive = new byte[512];
|
||||
int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
|
||||
if (bReceive[21] != 0xff) throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
if (bReceive[21] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
for (int cnt = 0; cnt < count; cnt++)
|
||||
bytes[cnt] = bReceive[cnt + 25];
|
||||
@@ -1084,9 +1095,20 @@ namespace S7.Net
|
||||
return package;
|
||||
}
|
||||
|
||||
private void CreateSocket()
|
||||
{
|
||||
#if NETFX_CORE
|
||||
_mSocket = new SocketClient(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
_mSocket.SetReceiveTimeout(1000);
|
||||
_mSocket.SetSendTimeout(1000);
|
||||
#else
|
||||
_mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
_mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
|
||||
_mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#region IDisposable members
|
||||
#region IDisposable members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -1099,8 +1121,7 @@ namespace S7.Net
|
||||
}
|
||||
//((IDisposable)_mSocket).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,58 +74,24 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Conversion.cs" />
|
||||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="PLC.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\S7.Net.Common\Conversion.cs">
|
||||
<Link>Conversion</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Enums.cs">
|
||||
<Link>Enums</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Boolean.cs">
|
||||
<Link>Types\Boolean</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Byte.cs">
|
||||
<Link>Types\Byte</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\ByteArray.cs">
|
||||
<Link>Types\ByteArray</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Class.cs">
|
||||
<Link>Types\Class</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Counter.cs">
|
||||
<Link>Types\Counter</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\DataItem.cs">
|
||||
<Link>Types\DataItem</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\DInt.cs">
|
||||
<Link>Types\DInt</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Double.cs">
|
||||
<Link>Types\Double</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\DWord.cs">
|
||||
<Link>Types\DWord</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Int.cs">
|
||||
<Link>Types\Int</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\String.cs">
|
||||
<Link>Types\String</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Struct.cs">
|
||||
<Link>Types\Struct</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Timer.cs">
|
||||
<Link>Types\Timer</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\S7.Net.Common\Types\Word.cs">
|
||||
<Link>Types\Word</Link>
|
||||
</Compile>
|
||||
<Compile Include="Types\Boolean.cs" />
|
||||
<Compile Include="Types\Byte.cs" />
|
||||
<Compile Include="Types\ByteArray.cs" />
|
||||
<Compile Include="Types\Class.cs" />
|
||||
<Compile Include="Types\Counter.cs" />
|
||||
<Compile Include="Types\DataItem.cs" />
|
||||
<Compile Include="Types\DInt.cs" />
|
||||
<Compile Include="Types\Double.cs" />
|
||||
<Compile Include="Types\DWord.cs" />
|
||||
<Compile Include="Types\Int.cs" />
|
||||
<Compile Include="Types\String.cs" />
|
||||
<Compile Include="Types\Struct.cs" />
|
||||
<Compile Include="Types\Timer.cs" />
|
||||
<Compile Include="Types\Word.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
@@ -142,6 +108,7 @@
|
||||
<ItemGroup>
|
||||
<None Include="Properties\S7.Net.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
26
S7.Net/Types/Boolean.cs
Normal file
26
S7.Net/Types/Boolean.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Boolean
|
||||
{
|
||||
public static bool GetValue(byte value, int bit)
|
||||
{
|
||||
if ((value & (int)Math.Pow(2, bit)) != 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static byte SetBit(byte value, int bit)
|
||||
{
|
||||
return (byte)(value | (byte)Math.Pow(2, bit));
|
||||
}
|
||||
|
||||
public static byte ClearBit(byte value, int bit)
|
||||
{
|
||||
return (byte)(value & (byte)(~(byte)Math.Pow(2, bit)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
20
S7.Net/Types/Byte.cs
Normal file
20
S7.Net/Types/Byte.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Byte
|
||||
{
|
||||
// publics
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(byte value)
|
||||
{
|
||||
byte[] bytes = new byte[] { value};
|
||||
return bytes;
|
||||
}
|
||||
#endregion
|
||||
#region FromByteArray
|
||||
public static byte FromByteArray(byte[] bytes)
|
||||
{
|
||||
return bytes[0];
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
44
S7.Net/Types/ByteArray.cs
Normal file
44
S7.Net/Types/ByteArray.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
class ByteArray
|
||||
{
|
||||
List<byte> list = new List<byte>();
|
||||
|
||||
public byte[] array
|
||||
{
|
||||
get { return list.ToArray(); }
|
||||
}
|
||||
|
||||
public ByteArray()
|
||||
{
|
||||
list = new List<byte>();
|
||||
}
|
||||
|
||||
public ByteArray(int size)
|
||||
{
|
||||
list = new List<byte>(size);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
list = new List<byte>();
|
||||
}
|
||||
|
||||
public void Add(byte item)
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
public void Add(byte[] items)
|
||||
{
|
||||
list.AddRange(items);
|
||||
}
|
||||
|
||||
public void Add(ByteArray byteArray)
|
||||
{
|
||||
list.AddRange(byteArray.array);
|
||||
}
|
||||
}
|
||||
}
|
||||
234
S7.Net/Types/Class.cs
Normal file
234
S7.Net/Types/Class.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Class
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the size of the struct in bytes.
|
||||
/// </summary>
|
||||
/// <param name="classType">the type of the class</param>
|
||||
/// <returns>the number of bytes</returns>
|
||||
public static int GetClassSize(Type classType)
|
||||
{
|
||||
double numBytes = 0.0;
|
||||
|
||||
var properties = classType.GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
switch (property.PropertyType.Name)
|
||||
{
|
||||
case "Boolean":
|
||||
numBytes += 0.125;
|
||||
break;
|
||||
case "Byte":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
case "UInt16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "Int32":
|
||||
case "UInt32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Float":
|
||||
case "Double":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
numBytes += 4;
|
||||
break;
|
||||
default:
|
||||
numBytes += GetClassSize(property.PropertyType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int)numBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a struct of a specified type by an array of bytes.
|
||||
/// </summary>
|
||||
/// <param name="sourceClass"></param>
|
||||
/// <param name="classType">The struct type</param>
|
||||
/// <param name="bytes">The array of bytes</param>
|
||||
/// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns>
|
||||
public static void FromBytes(object sourceClass, Type classType, byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
return;
|
||||
|
||||
if (bytes.Length != GetClassSize(classType))
|
||||
return;
|
||||
|
||||
// and decode it
|
||||
int bytePos = 0;
|
||||
int bitPos = 0;
|
||||
double numBytes = 0.0;
|
||||
|
||||
|
||||
var properties = sourceClass.GetType().GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
switch (property.PropertyType.Name)
|
||||
{
|
||||
case "Boolean":
|
||||
// get the value
|
||||
bytePos = (int)Math.Floor(numBytes);
|
||||
bitPos = (int)((numBytes - (double)bytePos) / 0.125);
|
||||
if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0)
|
||||
property.SetValue(sourceClass, true, null);
|
||||
else
|
||||
property.SetValue(sourceClass, false, null);
|
||||
numBytes += 0.125;
|
||||
break;
|
||||
case "Byte":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
property.SetValue(sourceClass, (byte)(bytes[(int)numBytes]), null);
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
|
||||
property.SetValue(sourceClass, source.ConvertToShort(), null);
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "UInt16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
property.SetValue(sourceClass, Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]), null);
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "Int32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3],
|
||||
bytes[(int)numBytes + 2],
|
||||
bytes[(int)numBytes + 1],
|
||||
bytes[(int)numBytes + 0]);
|
||||
property.SetValue(sourceClass, sourceUInt.ConvertToInt(), null);
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "UInt32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
property.SetValue(sourceClass, DWord.FromBytes(bytes[(int)numBytes],
|
||||
bytes[(int)numBytes + 1],
|
||||
bytes[(int)numBytes + 2],
|
||||
bytes[(int)numBytes + 3]), null);
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Double":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
property.SetValue(sourceClass, Double.FromByteArray(new byte[] { bytes[(int)numBytes],
|
||||
bytes[(int)numBytes + 1],
|
||||
bytes[(int)numBytes + 2],
|
||||
bytes[(int)numBytes + 3] }), null);
|
||||
numBytes += 4;
|
||||
break;
|
||||
default:
|
||||
var buffer = new byte[GetClassSize(property.PropertyType)];
|
||||
if (buffer.Length == 0)
|
||||
continue;
|
||||
Buffer.BlockCopy(bytes, (int)Math.Ceiling(numBytes), buffer, 0, buffer.Length);
|
||||
var propClass = Activator.CreateInstance(property.PropertyType);
|
||||
FromBytes(propClass, property.PropertyType, buffer);
|
||||
property.SetValue(sourceClass, propClass, null);
|
||||
numBytes += buffer.Length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a byte array depending on the struct type.
|
||||
/// </summary>
|
||||
/// <param name="sourceClass">The struct object</param>
|
||||
/// <returns>A byte array or null if fails.</returns>
|
||||
public static byte[] ToBytes(object sourceClass)
|
||||
{
|
||||
Type type = sourceClass.GetType();
|
||||
|
||||
int size = GetClassSize(type);
|
||||
byte[] bytes = new byte[size];
|
||||
byte[] bytes2 = null;
|
||||
|
||||
int bytePos = 0;
|
||||
int bitPos = 0;
|
||||
double numBytes = 0.0;
|
||||
|
||||
var properties = sourceClass.GetType().GetProperties();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
bytes2 = null;
|
||||
switch (property.PropertyType.Name)
|
||||
{
|
||||
case "Boolean":
|
||||
// get the value
|
||||
bytePos = (int)Math.Floor(numBytes);
|
||||
bitPos = (int)((numBytes - (double)bytePos) / 0.125);
|
||||
if ((bool)property.GetValue(sourceClass, null))
|
||||
bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true
|
||||
else
|
||||
bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false
|
||||
numBytes += 0.125;
|
||||
break;
|
||||
case "Byte":
|
||||
numBytes = (int)Math.Ceiling(numBytes);
|
||||
bytePos = (int)numBytes;
|
||||
bytes[bytePos] = (byte)property.GetValue(sourceClass, null);
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
bytes2 = Int.ToByteArray((Int16)property.GetValue(sourceClass, null));
|
||||
break;
|
||||
case "UInt16":
|
||||
bytes2 = Word.ToByteArray((UInt16)property.GetValue(sourceClass, null));
|
||||
break;
|
||||
case "Int32":
|
||||
bytes2 = DInt.ToByteArray((Int32)property.GetValue(sourceClass, null));
|
||||
break;
|
||||
case "UInt32":
|
||||
bytes2 = DWord.ToByteArray((UInt32)property.GetValue(sourceClass, null));
|
||||
break;
|
||||
case "Double":
|
||||
bytes2 = Double.ToByteArray((double)property.GetValue(sourceClass, null));
|
||||
break;
|
||||
}
|
||||
if (bytes2 != null)
|
||||
{
|
||||
// add them
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
bytePos = (int)numBytes;
|
||||
for (int bCnt = 0; bCnt < bytes2.Length; bCnt++)
|
||||
bytes[bytePos + bCnt] = bytes2[bCnt];
|
||||
numBytes += bytes2.Length;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
S7.Net/Types/Counter.cs
Normal file
61
S7.Net/Types/Counter.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Counter
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static UInt16 FromByteArray(byte[] bytes)
|
||||
{
|
||||
// bytes[0] -> HighByte
|
||||
// bytes[1] -> LowByte
|
||||
return FromBytes(bytes[1], bytes[0]);
|
||||
}
|
||||
#endregion
|
||||
#region FromBytes
|
||||
public static UInt16 FromBytes(byte LoVal, byte HiVal)
|
||||
{
|
||||
return (UInt16)(HiVal * 256 + LoVal);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(UInt16 value)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
int x = 2;
|
||||
long valLong = (long)((UInt16)value);
|
||||
for (int cnt = 0; cnt < x; cnt++)
|
||||
{
|
||||
Int64 x1 = (Int64)Math.Pow(256, (cnt));
|
||||
|
||||
Int64 x3 = (Int64)(valLong / x1);
|
||||
bytes[x - cnt - 1] = (byte)(x3 & 255);
|
||||
valLong -= bytes[x - cnt - 1] * x1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(UInt16[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (UInt16 val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static UInt16[] ToArray(byte[] bytes)
|
||||
{
|
||||
UInt16[] values = new UInt16[bytes.Length / 2];
|
||||
|
||||
int counter = 0;
|
||||
for (int cnt = 0; cnt < bytes.Length / 2; cnt++)
|
||||
values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] });
|
||||
|
||||
return values;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
71
S7.Net/Types/DInt.cs
Normal file
71
S7.Net/Types/DInt.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class DInt
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static Int32 FromByteArray(byte[] bytes)
|
||||
{
|
||||
return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]);
|
||||
}
|
||||
#endregion
|
||||
#region FromBytes
|
||||
public static Int32 FromBytes(byte v1, byte v2, byte v3, byte v4)
|
||||
{
|
||||
return (Int32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(Int32 value)
|
||||
{
|
||||
byte[] bytes = new byte[4];
|
||||
int x = 4;
|
||||
long valLong = (long)((Int32)value);
|
||||
for (int cnt = 0; cnt < x; cnt++)
|
||||
{
|
||||
Int64 x1 = (Int64)Math.Pow(256, (cnt));
|
||||
|
||||
Int64 x3 = (Int64)(valLong / x1);
|
||||
bytes[x - cnt - 1] = (byte)(x3 & 255);
|
||||
valLong -= bytes[x - cnt - 1] * x1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(Int32[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (Int32 val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static Int32[] ToArray(byte[] bytes)
|
||||
{
|
||||
Int32[] values = new Int32[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;
|
||||
}
|
||||
#endregion
|
||||
|
||||
// conversion
|
||||
public static Int32 CDWord(Int64 value)
|
||||
{
|
||||
if (value > Int32.MaxValue)
|
||||
{
|
||||
value -= (long)Int32.MaxValue + 1;
|
||||
value = (long)Int32.MaxValue + 1 - value;
|
||||
value *= -1;
|
||||
}
|
||||
return (int)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
S7.Net/Types/DWord.cs
Normal file
59
S7.Net/Types/DWord.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class DWord
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static UInt32 FromByteArray(byte[] bytes)
|
||||
{
|
||||
return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]);
|
||||
}
|
||||
#endregion
|
||||
#region FromBytes
|
||||
public static UInt32 FromBytes(byte v1, byte v2, byte v3, byte v4)
|
||||
{
|
||||
return (UInt32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(UInt32 value)
|
||||
{
|
||||
byte[] bytes = new byte[4];
|
||||
int x = 4;
|
||||
long valLong = (long)((UInt32)value);
|
||||
for (int cnt = 0; cnt < x; cnt++)
|
||||
{
|
||||
Int64 x1 = (Int64)Math.Pow(256, (cnt));
|
||||
|
||||
Int64 x3 = (Int64)(valLong / x1);
|
||||
bytes[x - cnt - 1] = (byte)(x3 & 255);
|
||||
valLong -= bytes[x - cnt - 1] * x1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(UInt32[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (UInt32 val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static UInt32[] ToArray(byte[] bytes)
|
||||
{
|
||||
UInt32[] values = new UInt32[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;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
18
S7.Net/Types/DataItem.cs
Normal file
18
S7.Net/Types/DataItem.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public class DataItem
|
||||
{
|
||||
public DataType DataType { get; set; }
|
||||
public VarType VarType { get; set; }
|
||||
public int DB { get; set; }
|
||||
public int StartByteAdr { get; set; }
|
||||
public int Count { get; set; }
|
||||
|
||||
public object Value { get; set; }
|
||||
|
||||
public DataItem()
|
||||
{
|
||||
Count = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
166
S7.Net/Types/Double.cs
Normal file
166
S7.Net/Types/Double.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Double
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static double FromByteArray(byte[] bytes)
|
||||
{
|
||||
byte v1 = bytes[0];
|
||||
byte v2 = bytes[1];
|
||||
byte v3 = bytes[2];
|
||||
byte v4 = bytes[3];
|
||||
|
||||
if ((int)v1 + v2 + v3 + v4 == 0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// nun String bilden
|
||||
string txt = ValToBinString(v1) + ValToBinString(v2) + ValToBinString(v3) + ValToBinString(v4);
|
||||
// erstmal das Vorzeichen
|
||||
int vz = int.Parse(txt.Substring(0, 1));
|
||||
int exd = Conversion.BinStringToInt32(txt.Substring(1, 8));
|
||||
string ma = txt.Substring(9, 23);
|
||||
double mantisse = 1;
|
||||
double faktor = 1.0;
|
||||
|
||||
//das ist die Anzahl der restlichen bit's
|
||||
for (int cnt = 0; cnt <= 22; cnt++)
|
||||
{
|
||||
faktor = faktor / 2.0;
|
||||
//entspricht 2^-y
|
||||
if (ma.Substring(cnt, 1) == "1")
|
||||
{
|
||||
mantisse = mantisse + faktor;
|
||||
}
|
||||
}
|
||||
return Math.Pow((-1), vz) * Math.Pow(2, (exd - 127)) * mantisse;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region FromDWord
|
||||
public static double FromDWord(Int32 value)
|
||||
{
|
||||
byte[] b = DInt.ToByteArray(value);
|
||||
double d = FromByteArray(b);
|
||||
return d;
|
||||
}
|
||||
|
||||
public static double FromDWord(UInt32 value)
|
||||
{
|
||||
byte[] b = DWord.ToByteArray(value);
|
||||
double d = FromByteArray(b);
|
||||
return d;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(double value)
|
||||
{
|
||||
double wert = (double)value;
|
||||
string binString = "";
|
||||
byte[] bytes = new byte[4];
|
||||
if (wert != 0f)
|
||||
{
|
||||
if (wert < 0)
|
||||
{
|
||||
wert *= -1;
|
||||
binString = "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
binString = "0";
|
||||
}
|
||||
int exponent = (int)Math.Floor((double)Math.Log(wert) / Math.Log(2.0));
|
||||
wert = wert / (Math.Pow(2, exponent)) - 1;
|
||||
|
||||
binString += ValToBinString((byte)(exponent + 127));
|
||||
for (int cnt = 1; cnt <= 23; cnt++)
|
||||
{
|
||||
if (!(wert - System.Math.Pow(2, -cnt) < 0))
|
||||
{
|
||||
wert = wert - System.Math.Pow(2, -cnt);
|
||||
binString += "1";
|
||||
}
|
||||
else
|
||||
binString += "0";
|
||||
}
|
||||
bytes[0] = (byte)BinStringToByte(binString.Substring(0, 8));
|
||||
bytes[1] = (byte)BinStringToByte(binString.Substring(8, 8));
|
||||
bytes[2] = (byte)BinStringToByte(binString.Substring(16, 8));
|
||||
bytes[3] = (byte)BinStringToByte(binString.Substring(24, 8));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(double[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (double val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static double[] ToArray(byte[] bytes)
|
||||
{
|
||||
double[] values = new double[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;
|
||||
}
|
||||
#endregion
|
||||
|
||||
// privates
|
||||
#region ValToBinString
|
||||
private static string ValToBinString(byte value)
|
||||
{
|
||||
string txt = "";
|
||||
|
||||
for (int cnt = 7; cnt >= 0; cnt += -1)
|
||||
{
|
||||
if ((value & (byte)Math.Pow(2, cnt)) > 0)
|
||||
txt += "1";
|
||||
else
|
||||
txt += "0";
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
#endregion
|
||||
#region BinStringToByte
|
||||
private static byte? BinStringToByte(string txt)
|
||||
{
|
||||
int cnt = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (txt.Length == 8)
|
||||
{
|
||||
for (cnt = 7; cnt >= 0; cnt += -1)
|
||||
{
|
||||
if (int.Parse(txt.Substring(cnt, 1)) == 1)
|
||||
{
|
||||
ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
|
||||
}
|
||||
}
|
||||
return (byte)ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
74
S7.Net/Types/Int.cs
Normal file
74
S7.Net/Types/Int.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Int
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static Int16 FromByteArray(byte[] bytes)
|
||||
{
|
||||
// bytes[0] -> HighByte
|
||||
// bytes[1] -> LowByte
|
||||
return FromBytes(bytes[1], bytes[0]);
|
||||
}
|
||||
#endregion
|
||||
#region FromBytes
|
||||
public static Int16 FromBytes(byte LoVal, byte HiVal)
|
||||
{
|
||||
return (Int16)(HiVal * 256 + LoVal);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(Int16 value)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
int x = 2;
|
||||
long valLong = (long)((Int16)value);
|
||||
for (int cnt = 0; cnt < x; cnt++)
|
||||
{
|
||||
Int64 x1 = (Int64)Math.Pow(256, (cnt));
|
||||
|
||||
Int64 x3 = (Int64)(valLong / x1);
|
||||
bytes[x - cnt - 1] = (byte)(x3 & 255);
|
||||
valLong -= bytes[x - cnt - 1] * x1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(Int16[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (Int16 val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static Int16[] ToArray(byte[] bytes)
|
||||
{
|
||||
Int16[] values = new Int16[bytes.Length / 2];
|
||||
|
||||
int counter = 0;
|
||||
for (int cnt = 0; cnt < bytes.Length / 2; cnt++)
|
||||
values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] });
|
||||
|
||||
return values;
|
||||
}
|
||||
#endregion
|
||||
|
||||
// conversion
|
||||
public static Int16 CWord(int value)
|
||||
{
|
||||
if (value > 32767)
|
||||
{
|
||||
value -= 32768;
|
||||
value = 32768 - value;
|
||||
value *= -1;
|
||||
}
|
||||
return (short)value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
34
S7.Net/Types/String.cs
Normal file
34
S7.Net/Types/String.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class String
|
||||
{
|
||||
// publics
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(string value)
|
||||
{
|
||||
string txt = (string)value;
|
||||
char[] ca = txt.ToCharArray();
|
||||
byte[] bytes = new byte[txt.Length];
|
||||
for (int cnt = 0; cnt <= ca.Length - 1; cnt++)
|
||||
bytes[cnt] = (byte)Asc(ca[cnt].ToString());
|
||||
return bytes;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region FromByteArray
|
||||
public static string FromByteArray(byte[] bytes)
|
||||
{
|
||||
return System.Text.Encoding.ASCII.GetString(bytes);
|
||||
}
|
||||
#endregion
|
||||
|
||||
// privates
|
||||
private static int Asc(string s)
|
||||
{
|
||||
byte[] b = System.Text.Encoding.ASCII.GetBytes(s);
|
||||
if (b.Length > 0)
|
||||
return b[0];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
237
S7.Net/Types/Struct.cs
Normal file
237
S7.Net/Types/Struct.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Struct
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the size of the struct in bytes.
|
||||
/// </summary>
|
||||
/// <param name="structType">the type of the struct</param>
|
||||
/// <returns>the number of bytes</returns>
|
||||
public static int GetStructSize(Type structType)
|
||||
{
|
||||
double numBytes = 0.0;
|
||||
|
||||
System.Reflection.FieldInfo[] infos = structType.GetFields();
|
||||
foreach (System.Reflection.FieldInfo info in infos)
|
||||
{
|
||||
switch (info.FieldType.Name)
|
||||
{
|
||||
case "Boolean":
|
||||
numBytes += 0.125;
|
||||
break;
|
||||
case "Byte":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
case "UInt16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "Int32":
|
||||
case "UInt32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "Float":
|
||||
case "Double":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
numBytes += 4;
|
||||
break;
|
||||
default:
|
||||
numBytes += GetStructSize(info.FieldType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int)numBytes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a struct of a specified type by an array of bytes.
|
||||
/// </summary>
|
||||
/// <param name="structType">The struct type</param>
|
||||
/// <param name="bytes">The array of bytes</param>
|
||||
/// <returns>The object depending on the struct type or null if fails(array-length != struct-length</returns>
|
||||
public static object FromBytes(Type structType, byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
return null;
|
||||
|
||||
if (bytes.Length != GetStructSize(structType))
|
||||
return null;
|
||||
|
||||
// and decode it
|
||||
int bytePos = 0;
|
||||
int bitPos = 0;
|
||||
double numBytes = 0.0;
|
||||
object structValue = Activator.CreateInstance(structType);
|
||||
|
||||
System.Reflection.FieldInfo[] infos = structValue.GetType().GetFields();
|
||||
foreach (System.Reflection.FieldInfo info in infos)
|
||||
{
|
||||
switch (info.FieldType.Name)
|
||||
{
|
||||
case "Boolean":
|
||||
// get the value
|
||||
bytePos = (int)Math.Floor(numBytes);
|
||||
bitPos = (int)((numBytes - (double)bytePos) / 0.125);
|
||||
if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0)
|
||||
info.SetValue(structValue, true);
|
||||
else
|
||||
info.SetValue(structValue, false);
|
||||
numBytes += 0.125;
|
||||
break;
|
||||
case "Byte":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
info.SetValue(structValue, (byte)(bytes[(int)numBytes]));
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]);
|
||||
info.SetValue(structValue, source.ConvertToShort());
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "UInt16":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
info.SetValue(structValue, Word.FromBytes(bytes[(int)numBytes + 1],
|
||||
bytes[(int)numBytes]));
|
||||
numBytes += 2;
|
||||
break;
|
||||
case "Int32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
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());
|
||||
numBytes += 4;
|
||||
break;
|
||||
case "UInt32":
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
// hier auswerten
|
||||
info.SetValue(structValue, DWord.FromBytes(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
|
||||
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;
|
||||
default:
|
||||
var buffer = new byte[GetStructSize(info.FieldType)];
|
||||
if (buffer.Length == 0)
|
||||
continue;
|
||||
Buffer.BlockCopy(bytes, (int)Math.Ceiling(numBytes), buffer, 0, buffer.Length);
|
||||
info.SetValue(structValue, FromBytes(info.FieldType, buffer));
|
||||
numBytes += buffer.Length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return structValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a byte array depending on the struct type.
|
||||
/// </summary>
|
||||
/// <param name="structValue">The struct object</param>
|
||||
/// <returns>A byte array or null if fails.</returns>
|
||||
public static byte[] ToBytes(object structValue)
|
||||
{
|
||||
Type type = structValue.GetType();
|
||||
|
||||
int size = Struct.GetStructSize(type);
|
||||
byte[] bytes = new byte[size];
|
||||
byte[] bytes2 = null;
|
||||
|
||||
int bytePos = 0;
|
||||
int bitPos = 0;
|
||||
double numBytes = 0.0;
|
||||
|
||||
System.Reflection.FieldInfo[] infos = type.GetFields();
|
||||
foreach (System.Reflection.FieldInfo info in infos)
|
||||
{
|
||||
bytes2 = null;
|
||||
switch (info.FieldType.Name)
|
||||
{
|
||||
case "Boolean":
|
||||
// get the value
|
||||
bytePos = (int)Math.Floor(numBytes);
|
||||
bitPos = (int)((numBytes - (double)bytePos) / 0.125);
|
||||
if ((bool)info.GetValue(structValue))
|
||||
bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true
|
||||
else
|
||||
bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false
|
||||
numBytes += 0.125;
|
||||
break;
|
||||
case "Byte":
|
||||
numBytes = (int)Math.Ceiling(numBytes);
|
||||
bytePos = (int)numBytes;
|
||||
bytes[bytePos] = (byte)info.GetValue(structValue);
|
||||
numBytes++;
|
||||
break;
|
||||
case "Int16":
|
||||
bytes2 = Int.ToByteArray((Int16)info.GetValue(structValue));
|
||||
break;
|
||||
case "UInt16":
|
||||
bytes2 = Word.ToByteArray((UInt16)info.GetValue(structValue));
|
||||
break;
|
||||
case "Int32":
|
||||
bytes2 = DInt.ToByteArray((Int32)info.GetValue(structValue));
|
||||
break;
|
||||
case "UInt32":
|
||||
bytes2 = DWord.ToByteArray((UInt32)info.GetValue(structValue));
|
||||
break;
|
||||
case "Double":
|
||||
bytes2 = Double.ToByteArray((double)info.GetValue(structValue));
|
||||
break;
|
||||
}
|
||||
if (bytes2 != null)
|
||||
{
|
||||
// add them
|
||||
numBytes = Math.Ceiling(numBytes);
|
||||
if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
|
||||
numBytes++;
|
||||
bytePos = (int)numBytes;
|
||||
for (int bCnt=0; bCnt<bytes2.Length; bCnt++)
|
||||
bytes[bytePos + bCnt] = bytes2[bCnt];
|
||||
numBytes += bytes2.Length;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
74
S7.Net/Types/Timer.cs
Normal file
74
S7.Net/Types/Timer.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Timer
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static double FromByteArray(byte[] bytes)
|
||||
{
|
||||
double wert = 0;
|
||||
Int16 value = (Int16)Types.Word.FromBytes(bytes[1], bytes[0]);
|
||||
string txt = Conversion.ValToBinString(value);
|
||||
wert = Conversion.BinStringToInt32(txt.Substring(4, 4)) * 100.0;
|
||||
wert += Conversion.BinStringToInt32(txt.Substring(8, 4)) * 10.0;
|
||||
wert += Conversion.BinStringToInt32(txt.Substring(12, 4));
|
||||
switch (txt.Substring(2, 2))
|
||||
{
|
||||
case "00":
|
||||
wert *= 0.01;
|
||||
break;
|
||||
case "01":
|
||||
wert *= 0.1;
|
||||
break;
|
||||
case "10":
|
||||
wert *= 1.0;
|
||||
break;
|
||||
case "11":
|
||||
wert *= 10.0;
|
||||
break;
|
||||
}
|
||||
return wert;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(UInt16 value)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
int x = 2;
|
||||
long valLong = (long)((UInt16)value);
|
||||
for (int cnt = 0; cnt < x; cnt++)
|
||||
{
|
||||
Int64 x1 = (Int64)Math.Pow(256, (cnt));
|
||||
|
||||
Int64 x3 = (Int64)(valLong / x1);
|
||||
bytes[x - cnt - 1] = (byte)(x3 & 255);
|
||||
valLong -= bytes[x - cnt - 1] * x1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(UInt16[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (UInt16 val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static double[] ToArray(byte[] bytes)
|
||||
{
|
||||
double[] values = new double[bytes.Length / 2];
|
||||
|
||||
int counter = 0;
|
||||
for (int cnt = 0; cnt < bytes.Length / 2; cnt++)
|
||||
values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] });
|
||||
|
||||
return values;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
61
S7.Net/Types/Word.cs
Normal file
61
S7.Net/Types/Word.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
public static class Word
|
||||
{
|
||||
// publics
|
||||
#region FromByteArray
|
||||
public static UInt16 FromByteArray(byte[] bytes)
|
||||
{
|
||||
// bytes[0] -> HighByte
|
||||
// bytes[1] -> LowByte
|
||||
return FromBytes(bytes[1], bytes[0]);
|
||||
}
|
||||
#endregion
|
||||
#region FromBytes
|
||||
public static UInt16 FromBytes(byte LoVal, byte HiVal)
|
||||
{
|
||||
return (UInt16)(HiVal * 256 + LoVal);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ToByteArray
|
||||
public static byte[] ToByteArray(UInt16 value)
|
||||
{
|
||||
byte[] bytes = new byte[2];
|
||||
int x = 2;
|
||||
long valLong = (long)((UInt16)value);
|
||||
for (int cnt = 0; cnt < x; cnt++)
|
||||
{
|
||||
Int64 x1 = (Int64)Math.Pow(256, (cnt));
|
||||
|
||||
Int64 x3 = (Int64)(valLong / x1);
|
||||
bytes[x - cnt - 1] = (byte)(x3 & 255);
|
||||
valLong -= bytes[x - cnt - 1] * x1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(UInt16[] value)
|
||||
{
|
||||
ByteArray arr = new ByteArray();
|
||||
foreach (UInt16 val in value)
|
||||
arr.Add(ToByteArray(val));
|
||||
return arr.array;
|
||||
}
|
||||
#endregion
|
||||
#region ToArray
|
||||
public static UInt16[] ToArray(byte[] bytes)
|
||||
{
|
||||
UInt16[] values = new UInt16[bytes.Length / 2];
|
||||
|
||||
int counter = 0;
|
||||
for (int cnt = 0; cnt < bytes.Length / 2; cnt++)
|
||||
values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] });
|
||||
|
||||
return values;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user