mirror of
https://github.com/fbarresi/Sharp7.git
synced 2026-02-04 08:42:51 +00:00
Merge branch 'release/1.0.6'
This commit is contained in:
202
Sharp7/MsgSocket.cs
Normal file
202
Sharp7/MsgSocket.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Sharp7
|
||||
{
|
||||
|
||||
class MsgSocket
|
||||
{
|
||||
private Socket TCPSocket;
|
||||
private int _ReadTimeout = 2000;
|
||||
private int _WriteTimeout = 2000;
|
||||
private int _ConnectTimeout = 1000;
|
||||
public int LastError = 0;
|
||||
|
||||
public MsgSocket()
|
||||
{
|
||||
}
|
||||
|
||||
~MsgSocket()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (TCPSocket != null)
|
||||
{
|
||||
TCPSocket.Dispose();
|
||||
TCPSocket = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSocket()
|
||||
{
|
||||
TCPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
TCPSocket.NoDelay = true;
|
||||
}
|
||||
|
||||
private void TCPPing(string Host, int Port)
|
||||
{
|
||||
// To Ping the PLC an Asynchronous socket is used rather then an ICMP packet.
|
||||
// This allows the use also across Internet and Firewalls (obviously the port must be opened)
|
||||
LastError = 0;
|
||||
Socket PingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
try
|
||||
{
|
||||
|
||||
IAsyncResult result = PingSocket.BeginConnect(Host, Port, null, null);
|
||||
bool success = result.AsyncWaitHandle.WaitOne(_ConnectTimeout, true);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
LastError = S7Consts.errTCPConnectionFailed;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
LastError = S7Consts.errTCPConnectionFailed;
|
||||
};
|
||||
PingSocket.Close();
|
||||
}
|
||||
|
||||
public int Connect(string Host, int Port)
|
||||
{
|
||||
LastError = 0;
|
||||
if (!Connected)
|
||||
{
|
||||
TCPPing(Host, Port);
|
||||
if (LastError == 0)
|
||||
try
|
||||
{
|
||||
CreateSocket();
|
||||
TCPSocket.Connect(Host, Port);
|
||||
}
|
||||
catch
|
||||
{
|
||||
LastError = S7Consts.errTCPConnectionFailed;
|
||||
}
|
||||
}
|
||||
return LastError;
|
||||
}
|
||||
|
||||
private int WaitForData(int Size, int Timeout)
|
||||
{
|
||||
bool Expired = false;
|
||||
int SizeAvail;
|
||||
int Elapsed = Environment.TickCount;
|
||||
LastError = 0;
|
||||
try
|
||||
{
|
||||
SizeAvail = TCPSocket.Available;
|
||||
while ((SizeAvail < Size) && (!Expired))
|
||||
{
|
||||
Thread.Sleep(2);
|
||||
SizeAvail = TCPSocket.Available;
|
||||
Expired = Environment.TickCount - Elapsed > Timeout;
|
||||
// If timeout we clean the buffer
|
||||
if (Expired && (SizeAvail > 0))
|
||||
try
|
||||
{
|
||||
byte[] Flush = new byte[SizeAvail];
|
||||
TCPSocket.Receive(Flush, 0, SizeAvail, SocketFlags.None);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
LastError = S7Consts.errTCPDataReceive;
|
||||
}
|
||||
if (Expired)
|
||||
{
|
||||
LastError = S7Consts.errTCPDataReceive;
|
||||
}
|
||||
return LastError;
|
||||
}
|
||||
|
||||
public int Receive(byte[] Buffer, int Start, int Size)
|
||||
{
|
||||
|
||||
int BytesRead = 0;
|
||||
LastError = WaitForData(Size, _ReadTimeout);
|
||||
if (LastError == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
BytesRead = TCPSocket.Receive(Buffer, Start, Size, SocketFlags.None);
|
||||
}
|
||||
catch
|
||||
{
|
||||
LastError = S7Consts.errTCPDataReceive;
|
||||
}
|
||||
if (BytesRead == 0) // Connection Reset by the peer
|
||||
{
|
||||
LastError = S7Consts.errTCPDataReceive;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
return LastError;
|
||||
}
|
||||
|
||||
public int Send(byte[] Buffer, int Size)
|
||||
{
|
||||
LastError = 0;
|
||||
try
|
||||
{
|
||||
int BytesSent = TCPSocket.Send(Buffer, Size, SocketFlags.None);
|
||||
}
|
||||
catch
|
||||
{
|
||||
LastError = S7Consts.errTCPDataSend;
|
||||
Close();
|
||||
}
|
||||
return LastError;
|
||||
}
|
||||
|
||||
public bool Connected
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TCPSocket != null) && (TCPSocket.Connected);
|
||||
}
|
||||
}
|
||||
|
||||
public int ReadTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ReadTimeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ReadTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int WriteTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _WriteTimeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
_WriteTimeout = value;
|
||||
}
|
||||
|
||||
}
|
||||
public int ConnectTimeout
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ConnectTimeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
_ConnectTimeout = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
559
Sharp7/S7.cs
Normal file
559
Sharp7/S7.cs
Normal file
@@ -0,0 +1,559 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Sharp7
|
||||
{
|
||||
public static class S7
|
||||
{
|
||||
#region [Help Functions]
|
||||
|
||||
private static Int64 bias = 621355968000000000; // "decimicros" between 0001-01-01 00:00:00 and 1970-01-01 00:00:00
|
||||
|
||||
private static int BCDtoByte(byte B)
|
||||
{
|
||||
return ((B >> 4) * 10) + (B & 0x0F);
|
||||
}
|
||||
|
||||
private static byte ByteToBCD(int Value)
|
||||
{
|
||||
return (byte)(((Value / 10) << 4) | (Value % 10));
|
||||
}
|
||||
|
||||
private static byte[] CopyFrom(byte[] Buffer, int Pos, int Size)
|
||||
{
|
||||
byte[] Result=new byte[Size];
|
||||
Array.Copy(Buffer, Pos, Result, 0, Size);
|
||||
return Result;
|
||||
}
|
||||
|
||||
public static int DataSizeByte(int WordLength)
|
||||
{
|
||||
switch (WordLength)
|
||||
{
|
||||
case S7Consts.S7WLBit: return 1; // S7 sends 1 byte per bit
|
||||
case S7Consts.S7WLByte: return 1;
|
||||
case S7Consts.S7WLChar: return 1;
|
||||
case S7Consts.S7WLWord: return 2;
|
||||
case S7Consts.S7WLDWord: return 4;
|
||||
case S7Consts.S7WLInt: return 2;
|
||||
case S7Consts.S7WLDInt: return 4;
|
||||
case S7Consts.S7WLReal: return 4;
|
||||
case S7Consts.S7WLCounter: return 2;
|
||||
case S7Consts.S7WLTimer: return 2;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#region Get/Set the bit at Pos.Bit
|
||||
public static bool GetBitAt(byte[] Buffer, int Pos, int Bit)
|
||||
{
|
||||
byte[] Mask = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
|
||||
if (Bit < 0) Bit = 0;
|
||||
if (Bit > 7) Bit = 7;
|
||||
return (Buffer[Pos] & Mask[Bit]) != 0;
|
||||
}
|
||||
public static void SetBitAt(ref byte[] Buffer, int Pos, int Bit, bool Value)
|
||||
{
|
||||
byte[] Mask = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
|
||||
if (Bit < 0) Bit = 0;
|
||||
if (Bit > 7) Bit = 7;
|
||||
|
||||
if (Value)
|
||||
Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]);
|
||||
else
|
||||
Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 8 bit signed value (S7 SInt) -128..127
|
||||
public static int GetSIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
int Value = Buffer[Pos];
|
||||
if (Value < 128)
|
||||
return Value;
|
||||
else
|
||||
return (int) (Value - 256);
|
||||
}
|
||||
public static void SetSIntAt(byte[] Buffer, int Pos, int Value)
|
||||
{
|
||||
if (Value < -128) Value = -128;
|
||||
if (Value > 127) Value = 127;
|
||||
Buffer[Pos] = (byte)Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 16 bit signed value (S7 int) -32768..32767
|
||||
public static int GetIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return (short)((Buffer[Pos] << 8) | Buffer[Pos + 1]);
|
||||
}
|
||||
public static void SetIntAt(byte[] Buffer, int Pos, Int16 Value)
|
||||
{
|
||||
Buffer[Pos] = (byte)(Value >> 8);
|
||||
Buffer[Pos + 1] = (byte)(Value & 0x00FF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 32 bit signed value (S7 DInt) -2147483648..2147483647
|
||||
public static int GetDIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
int Result;
|
||||
Result = Buffer[Pos]; Result <<= 8;
|
||||
Result += Buffer[Pos + 1]; Result <<= 8;
|
||||
Result += Buffer[Pos + 2]; Result <<= 8;
|
||||
Result += Buffer[Pos + 3];
|
||||
return Result;
|
||||
}
|
||||
public static void SetDIntAt(byte[] Buffer, int Pos, int Value)
|
||||
{
|
||||
Buffer[Pos + 3] = (byte)(Value & 0xFF);
|
||||
Buffer[Pos + 2] = (byte)((Value >> 8) & 0xFF);
|
||||
Buffer[Pos + 1] = (byte)((Value >> 16) & 0xFF);
|
||||
Buffer[Pos] = (byte)((Value >> 24) & 0xFF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 64 bit signed value (S7 LInt) -9223372036854775808..9223372036854775807
|
||||
public static Int64 GetLIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
Int64 Result;
|
||||
Result = Buffer[Pos]; Result <<= 8;
|
||||
Result += Buffer[Pos + 1]; Result <<= 8;
|
||||
Result += Buffer[Pos + 2]; Result <<= 8;
|
||||
Result += Buffer[Pos + 3]; Result <<= 8;
|
||||
Result += Buffer[Pos + 4]; Result <<= 8;
|
||||
Result += Buffer[Pos + 5]; Result <<= 8;
|
||||
Result += Buffer[Pos + 6]; Result <<= 8;
|
||||
Result += Buffer[Pos + 7];
|
||||
return Result;
|
||||
}
|
||||
public static void SetLIntAt(byte[] Buffer, int Pos, Int64 Value)
|
||||
{
|
||||
Buffer[Pos + 7] = (byte)(Value & 0xFF);
|
||||
Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF);
|
||||
Buffer[Pos + 5] = (byte)((Value >> 16) & 0xFF);
|
||||
Buffer[Pos + 4] = (byte)((Value >> 24) & 0xFF);
|
||||
Buffer[Pos + 3] = (byte)((Value >> 32) & 0xFF);
|
||||
Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF);
|
||||
Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF);
|
||||
Buffer[Pos] = (byte)((Value >> 56) & 0xFF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 8 bit unsigned value (S7 USInt) 0..255
|
||||
public static byte GetUSIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return Buffer[Pos];
|
||||
}
|
||||
public static void SetUSIntAt(byte[] Buffer, int Pos, byte Value)
|
||||
{
|
||||
Buffer[Pos] = Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 16 bit unsigned value (S7 UInt) 0..65535
|
||||
public static UInt16 GetUIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return (UInt16)((Buffer[Pos] << 8) | Buffer[Pos + 1]);
|
||||
}
|
||||
public static void SetUIntAt(byte[] Buffer, int Pos, UInt16 Value)
|
||||
{
|
||||
Buffer[Pos] = (byte)(Value >> 8);
|
||||
Buffer[Pos + 1] = (byte)(Value & 0x00FF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 32 bit unsigned value (S7 UDInt) 0..4294967296
|
||||
public static UInt32 GetUDIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
UInt32 Result;
|
||||
Result = Buffer[Pos]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 1]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 2]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 3];
|
||||
return Result;
|
||||
}
|
||||
public static void SetUDIntAt(byte[] Buffer, int Pos, UInt32 Value)
|
||||
{
|
||||
Buffer[Pos + 3] = (byte)(Value & 0xFF);
|
||||
Buffer[Pos + 2] = (byte)((Value >> 8) & 0xFF);
|
||||
Buffer[Pos + 1] = (byte)((Value >> 16) & 0xFF);
|
||||
Buffer[Pos] = (byte)((Value >> 24) & 0xFF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 64 bit unsigned value (S7 ULint) 0..18446744073709551616
|
||||
public static UInt64 GetULIntAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
UInt64 Result;
|
||||
Result = Buffer[Pos]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 1]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 2]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 3]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 4]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 5]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 6]; Result <<= 8;
|
||||
Result |= Buffer[Pos + 7];
|
||||
return Result;
|
||||
}
|
||||
public static void SetULintAt(byte[] Buffer, int Pos, UInt64 Value)
|
||||
{
|
||||
Buffer[Pos + 7] = (byte)(Value & 0xFF);
|
||||
Buffer[Pos + 6] = (byte)((Value >> 8) & 0xFF);
|
||||
Buffer[Pos + 5] = (byte)((Value >> 16) & 0xFF);
|
||||
Buffer[Pos + 4] = (byte)((Value >> 24) & 0xFF);
|
||||
Buffer[Pos + 3] = (byte)((Value >> 32) & 0xFF);
|
||||
Buffer[Pos + 2] = (byte)((Value >> 40) & 0xFF);
|
||||
Buffer[Pos + 1] = (byte)((Value >> 48) & 0xFF);
|
||||
Buffer[Pos] = (byte)((Value >> 56) & 0xFF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 8 bit word (S7 Byte) 16#00..16#FF
|
||||
public static byte GetByteAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return Buffer[Pos];
|
||||
}
|
||||
public static void SetByteAt(byte[] Buffer, int Pos, byte Value)
|
||||
{
|
||||
Buffer[Pos] = Value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 16 bit word (S7 Word) 16#0000..16#FFFF
|
||||
public static UInt16 GetWordAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return GetUIntAt(Buffer,Pos);
|
||||
}
|
||||
public static void SetWordAt(byte[] Buffer, int Pos, UInt16 Value)
|
||||
{
|
||||
SetUIntAt(Buffer, Pos, Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 32 bit word (S7 DWord) 16#00000000..16#FFFFFFFF
|
||||
public static UInt32 GetDWordAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return GetUDIntAt(Buffer, Pos);
|
||||
}
|
||||
public static void SetDWordAt(byte[] Buffer, int Pos, UInt32 Value)
|
||||
{
|
||||
SetUDIntAt(Buffer, Pos, Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 64 bit word (S7 LWord) 16#0000000000000000..16#FFFFFFFFFFFFFFFF
|
||||
public static UInt64 GetLWordAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return GetULIntAt(Buffer, Pos);
|
||||
}
|
||||
public static void SetLWordAt(byte[] Buffer, int Pos, UInt64 Value)
|
||||
{
|
||||
SetULintAt(Buffer, Pos, Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 32 bit floating point number (S7 Real) (Range of Single)
|
||||
public static Single GetRealAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
UInt32 Value = GetUDIntAt(Buffer, Pos);
|
||||
byte[] bytes = BitConverter.GetBytes(Value);
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
}
|
||||
public static void SetRealAt(byte[] Buffer, int Pos, Single Value)
|
||||
{
|
||||
byte[] FloatArray = BitConverter.GetBytes(Value);
|
||||
Buffer[Pos] = FloatArray[3];
|
||||
Buffer[Pos + 1] = FloatArray[2];
|
||||
Buffer[Pos + 2] = FloatArray[1];
|
||||
Buffer[Pos + 3] = FloatArray[0];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set 64 bit floating point number (S7 LReal) (Range of Double)
|
||||
public static Double GetLRealAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
UInt64 Value = GetULIntAt(Buffer, Pos);
|
||||
byte[] bytes = BitConverter.GetBytes(Value);
|
||||
return BitConverter.ToDouble(bytes, 0);
|
||||
}
|
||||
public static void SetLRealAt(byte[] Buffer, int Pos, Double Value)
|
||||
{
|
||||
byte[] FloatArray = BitConverter.GetBytes(Value);
|
||||
Buffer[Pos] = FloatArray[7];
|
||||
Buffer[Pos + 1] = FloatArray[6];
|
||||
Buffer[Pos + 2] = FloatArray[5];
|
||||
Buffer[Pos + 3] = FloatArray[4];
|
||||
Buffer[Pos + 4] = FloatArray[3];
|
||||
Buffer[Pos + 5] = FloatArray[2];
|
||||
Buffer[Pos + 6] = FloatArray[1];
|
||||
Buffer[Pos + 7] = FloatArray[0];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set DateTime (S7 DATE_AND_TIME)
|
||||
public static DateTime GetDateTimeAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
int Year, Month, Day, Hour, Min, Sec, MSec;
|
||||
|
||||
Year = BCDtoByte(Buffer[Pos]);
|
||||
if (Year < 90)
|
||||
Year += 2000;
|
||||
else
|
||||
Year += 1900;
|
||||
|
||||
Month = BCDtoByte(Buffer[Pos + 1]);
|
||||
Day = BCDtoByte(Buffer[Pos + 2]);
|
||||
Hour = BCDtoByte(Buffer[Pos + 3]);
|
||||
Min = BCDtoByte(Buffer[Pos + 4]);
|
||||
Sec = BCDtoByte(Buffer[Pos + 5]);
|
||||
MSec = (BCDtoByte(Buffer[Pos + 6]) * 10) + (BCDtoByte(Buffer[Pos + 7]) / 10);
|
||||
try
|
||||
{
|
||||
return new DateTime(Year, Month, Day, Hour, Min, Sec, MSec);
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException)
|
||||
{
|
||||
return new DateTime(0);
|
||||
}
|
||||
}
|
||||
public static void SetDateTimeAt(byte[] Buffer, int Pos, DateTime Value)
|
||||
{
|
||||
int Year = Value.Year;
|
||||
int Month = Value.Month;
|
||||
int Day = Value.Day;
|
||||
int Hour = Value.Hour;
|
||||
int Min = Value.Minute;
|
||||
int Sec = Value.Second;
|
||||
int Dow = (int)Value.DayOfWeek + 1;
|
||||
// MSecH = First two digits of miliseconds
|
||||
int MsecH = Value.Millisecond / 10;
|
||||
// MSecL = Last digit of miliseconds
|
||||
int MsecL = Value.Millisecond % 10;
|
||||
if (Year > 1999)
|
||||
Year -= 2000;
|
||||
|
||||
Buffer[Pos] = ByteToBCD(Year);
|
||||
Buffer[Pos + 1] = ByteToBCD(Month);
|
||||
Buffer[Pos + 2] = ByteToBCD(Day);
|
||||
Buffer[Pos + 3] = ByteToBCD(Hour);
|
||||
Buffer[Pos + 4] = ByteToBCD(Min);
|
||||
Buffer[Pos + 5] = ByteToBCD(Sec);
|
||||
Buffer[Pos + 6] = ByteToBCD(MsecH);
|
||||
Buffer[Pos + 7] = ByteToBCD(MsecL * 10 + Dow);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set DATE (S7 DATE)
|
||||
public static DateTime GetDateAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DateTime(1990, 1, 1).AddDays(GetIntAt(Buffer, Pos));
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException)
|
||||
{
|
||||
return new DateTime(0);
|
||||
}
|
||||
}
|
||||
public static void SetDateAt(byte[] Buffer, int Pos, DateTime Value)
|
||||
{
|
||||
SetIntAt(Buffer, Pos, (Int16)(Value - new DateTime(1990, 1, 1)).Days);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get/Set TOD (S7 TIME_OF_DAY)
|
||||
public static DateTime GetTODAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DateTime(0).AddMilliseconds(S7.GetDIntAt(Buffer, Pos));
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException)
|
||||
{
|
||||
return new DateTime(0);
|
||||
}
|
||||
}
|
||||
public static void SetTODAt(byte[] Buffer, int Pos, DateTime Value)
|
||||
{
|
||||
TimeSpan Time = Value.TimeOfDay;
|
||||
SetDIntAt(Buffer, Pos, (Int32)Math.Round(Time.TotalMilliseconds));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set LTOD (S7 1500 LONG TIME_OF_DAY)
|
||||
public static DateTime GetLTODAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
// .NET Tick = 100 ns, S71500 Tick = 1 ns
|
||||
try
|
||||
{
|
||||
return new DateTime(Math.Abs(GetLIntAt(Buffer,Pos)/100));
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException)
|
||||
{
|
||||
return new DateTime(0);
|
||||
}
|
||||
}
|
||||
public static void SetLTODAt(byte[] Buffer, int Pos, DateTime Value)
|
||||
{
|
||||
TimeSpan Time = Value.TimeOfDay;
|
||||
SetLIntAt(Buffer, Pos, (Int64)Time.Ticks * 100);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GET/SET LDT (S7 1500 Long Date and Time)
|
||||
public static DateTime GetLDTAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DateTime((GetLIntAt(Buffer, Pos) / 100) + bias);
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException)
|
||||
{
|
||||
return new DateTime(0);
|
||||
}
|
||||
}
|
||||
public static void SetLDTAt(byte[] Buffer, int Pos, DateTime Value)
|
||||
{
|
||||
SetLIntAt(Buffer, Pos, (Value.Ticks-bias) * 100);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set DTL (S71200/1500 Date and Time)
|
||||
// Thanks to Johan Cardoen for GetDTLAt
|
||||
public static DateTime GetDTLAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
int Year, Month, Day, Hour, Min, Sec, MSec;
|
||||
|
||||
Year = Buffer[Pos] * 256 + Buffer[Pos + 1];
|
||||
Month = Buffer[Pos + 2];
|
||||
Day = Buffer[Pos + 3];
|
||||
Hour = Buffer[Pos + 5];
|
||||
Min = Buffer[Pos + 6];
|
||||
Sec = Buffer[Pos + 7];
|
||||
MSec = (int)GetUDIntAt(Buffer, Pos + 8)/1000000;
|
||||
|
||||
try
|
||||
{
|
||||
return new DateTime(Year, Month, Day, Hour, Min, Sec, MSec);
|
||||
}
|
||||
catch (System.ArgumentOutOfRangeException)
|
||||
{
|
||||
return new DateTime(0);
|
||||
}
|
||||
}
|
||||
public static void SetDTLAt(byte[] Buffer, int Pos, DateTime Value)
|
||||
{
|
||||
short Year = (short)Value.Year;
|
||||
byte Month = (byte)Value.Month;
|
||||
byte Day = (byte)Value.Day;
|
||||
byte Hour = (byte)Value.Hour;
|
||||
byte Min = (byte)Value.Minute;
|
||||
byte Sec = (byte)Value.Second;
|
||||
byte Dow = (byte)(Value.DayOfWeek + 1);
|
||||
|
||||
Int32 NanoSecs = Value.Millisecond * 1000000;
|
||||
|
||||
var bytes_short = BitConverter.GetBytes(Year);
|
||||
|
||||
Buffer[Pos] = bytes_short[1];
|
||||
Buffer[Pos + 1] = bytes_short[0];
|
||||
Buffer[Pos + 2] = Month;
|
||||
Buffer[Pos + 3] = Day;
|
||||
Buffer[Pos + 4] = Dow;
|
||||
Buffer[Pos + 5] = Hour;
|
||||
Buffer[Pos + 6] = Min;
|
||||
Buffer[Pos + 7] = Sec;
|
||||
SetDIntAt(Buffer, Pos + 8, NanoSecs);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get/Set String (S7 String)
|
||||
// Thanks to Pablo Agirre
|
||||
public static string GetStringAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
int size = (int)Buffer[Pos + 1];
|
||||
return Encoding.UTF8.GetString(Buffer, Pos + 2, size);
|
||||
}
|
||||
public static void SetStringAt(byte[] Buffer, int Pos, int MaxLen, string Value)
|
||||
{
|
||||
int size = Value.Length;
|
||||
Buffer[Pos] = (byte)MaxLen;
|
||||
Buffer[Pos + 1] = (byte)size;
|
||||
Encoding.UTF8.GetBytes(Value, 0, size, Buffer, Pos + 2);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set Array of char (S7 ARRAY OF CHARS)
|
||||
public static string GetCharsAt(byte[] Buffer, int Pos, int Size)
|
||||
{
|
||||
return Encoding.UTF8.GetString(Buffer, Pos , Size);
|
||||
}
|
||||
public static void SetCharsAt(byte[] Buffer, int Pos, string Value)
|
||||
{
|
||||
int MaxLen = Buffer.Length - Pos;
|
||||
// Truncs the string if there's no room enough
|
||||
if (MaxLen > Value.Length) MaxLen = Value.Length;
|
||||
Encoding.UTF8.GetBytes(Value, 0, MaxLen, Buffer, Pos);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set Counter
|
||||
public static int GetCounter(ushort Value)
|
||||
{
|
||||
return BCDtoByte((byte)Value) * 100 + BCDtoByte((byte)(Value >> 8));
|
||||
}
|
||||
|
||||
public static int GetCounterAt(ushort[] Buffer, int Index)
|
||||
{
|
||||
return GetCounter(Buffer[Index]);
|
||||
}
|
||||
|
||||
public static ushort ToCounter(int Value)
|
||||
{
|
||||
return (ushort)(ByteToBCD(Value / 100) + (ByteToBCD(Value % 100) << 8));
|
||||
}
|
||||
|
||||
public static void SetCounterAt(ushort[] Buffer, int Pos, int Value)
|
||||
{
|
||||
Buffer[Pos] = ToCounter(Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Set Timer
|
||||
|
||||
public static S7Timer GetS7TimerAt(byte[] Buffer, int Pos)
|
||||
{
|
||||
return new S7Timer(new List<byte>(Buffer).GetRange(Pos, 12).ToArray());
|
||||
}
|
||||
|
||||
public static void SetS7TimespanAt(byte[] Buffer, int Pos, TimeSpan Value)
|
||||
{
|
||||
SetDIntAt(Buffer, Pos, (Int32)Value.TotalMilliseconds);
|
||||
}
|
||||
|
||||
public static TimeSpan GetS7TimespanAt(byte[] Buffer, int pos)
|
||||
{
|
||||
if (Buffer.Length < pos + 4)
|
||||
{
|
||||
return new TimeSpan();
|
||||
}
|
||||
|
||||
Int32 a;
|
||||
a = Buffer[pos + 0]; a <<= 8;
|
||||
a += Buffer[pos + 1]; a <<= 8;
|
||||
a += Buffer[pos + 2]; a <<= 8;
|
||||
a += Buffer[pos + 3];
|
||||
TimeSpan sp = new TimeSpan(0, 0, 0, 0, a);
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion [Help Functions]
|
||||
}
|
||||
}
|
||||
2330
Sharp7/S7Client.cs
Normal file
2330
Sharp7/S7Client.cs
Normal file
File diff suppressed because it is too large
Load Diff
117
Sharp7/S7Consts.cs
Normal file
117
Sharp7/S7Consts.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Sharp7
|
||||
{
|
||||
public static class S7Consts
|
||||
{
|
||||
#region [Exported Consts]
|
||||
// Error codes
|
||||
//------------------------------------------------------------------------------
|
||||
// ERRORS
|
||||
//------------------------------------------------------------------------------
|
||||
public const int errTCPSocketCreation = 0x00000001;
|
||||
public const int errTCPConnectionTimeout = 0x00000002;
|
||||
public const int errTCPConnectionFailed = 0x00000003;
|
||||
public const int errTCPReceiveTimeout = 0x00000004;
|
||||
public const int errTCPDataReceive = 0x00000005;
|
||||
public const int errTCPSendTimeout = 0x00000006;
|
||||
public const int errTCPDataSend = 0x00000007;
|
||||
public const int errTCPConnectionReset = 0x00000008;
|
||||
public const int errTCPNotConnected = 0x00000009;
|
||||
public const int errTCPUnreachableHost = 0x00002751;
|
||||
|
||||
public const int errIsoConnect = 0x00010000; // Connection error
|
||||
public const int errIsoInvalidPDU = 0x00030000; // Bad format
|
||||
public const int errIsoInvalidDataSize = 0x00040000; // Bad Datasize passed to send/recv : buffer is invalid
|
||||
|
||||
public const int errCliNegotiatingPDU = 0x00100000;
|
||||
public const int errCliInvalidParams = 0x00200000;
|
||||
public const int errCliJobPending = 0x00300000;
|
||||
public const int errCliTooManyItems = 0x00400000;
|
||||
public const int errCliInvalidWordLen = 0x00500000;
|
||||
public const int errCliPartialDataWritten = 0x00600000;
|
||||
public const int errCliSizeOverPDU = 0x00700000;
|
||||
public const int errCliInvalidPlcAnswer = 0x00800000;
|
||||
public const int errCliAddressOutOfRange = 0x00900000;
|
||||
public const int errCliInvalidTransportSize = 0x00A00000;
|
||||
public const int errCliWriteDataSizeMismatch = 0x00B00000;
|
||||
public const int errCliItemNotAvailable = 0x00C00000;
|
||||
public const int errCliInvalidValue = 0x00D00000;
|
||||
public const int errCliCannotStartPLC = 0x00E00000;
|
||||
public const int errCliAlreadyRun = 0x00F00000;
|
||||
public const int errCliCannotStopPLC = 0x01000000;
|
||||
public const int errCliCannotCopyRamToRom = 0x01100000;
|
||||
public const int errCliCannotCompress = 0x01200000;
|
||||
public const int errCliAlreadyStop = 0x01300000;
|
||||
public const int errCliFunNotAvailable = 0x01400000;
|
||||
public const int errCliUploadSequenceFailed = 0x01500000;
|
||||
public const int errCliInvalidDataSizeRecvd = 0x01600000;
|
||||
public const int errCliInvalidBlockType = 0x01700000;
|
||||
public const int errCliInvalidBlockNumber = 0x01800000;
|
||||
public const int errCliInvalidBlockSize = 0x01900000;
|
||||
public const int errCliNeedPassword = 0x01D00000;
|
||||
public const int errCliInvalidPassword = 0x01E00000;
|
||||
public const int errCliNoPasswordToSetOrClear = 0x01F00000;
|
||||
public const int errCliJobTimeout = 0x02000000;
|
||||
public const int errCliPartialDataRead = 0x02100000;
|
||||
public const int errCliBufferTooSmall = 0x02200000;
|
||||
public const int errCliFunctionRefused = 0x02300000;
|
||||
public const int errCliDestroying = 0x02400000;
|
||||
public const int errCliInvalidParamNumber = 0x02500000;
|
||||
public const int errCliCannotChangeParam = 0x02600000;
|
||||
public const int errCliFunctionNotImplemented = 0x02700000;
|
||||
//------------------------------------------------------------------------------
|
||||
// PARAMS LIST FOR COMPATIBILITY WITH Snap7.net.cs
|
||||
//------------------------------------------------------------------------------
|
||||
public const Int32 p_u16_LocalPort = 1; // Not applicable here
|
||||
public const Int32 p_u16_RemotePort = 2;
|
||||
public const Int32 p_i32_PingTimeout = 3;
|
||||
public const Int32 p_i32_SendTimeout = 4;
|
||||
public const Int32 p_i32_RecvTimeout = 5;
|
||||
public const Int32 p_i32_WorkInterval = 6; // Not applicable here
|
||||
public const Int32 p_u16_SrcRef = 7; // Not applicable here
|
||||
public const Int32 p_u16_DstRef = 8; // Not applicable here
|
||||
public const Int32 p_u16_SrcTSap = 9; // Not applicable here
|
||||
public const Int32 p_i32_PDURequest = 10;
|
||||
public const Int32 p_i32_MaxClients = 11; // Not applicable here
|
||||
public const Int32 p_i32_BSendTimeout = 12; // Not applicable here
|
||||
public const Int32 p_i32_BRecvTimeout = 13; // Not applicable here
|
||||
public const Int32 p_u32_RecoveryTime = 14; // Not applicable here
|
||||
public const Int32 p_u32_KeepAliveTime = 15; // Not applicable here
|
||||
// Area ID
|
||||
public const byte S7AreaPE = 0x81;
|
||||
public const byte S7AreaPA = 0x82;
|
||||
public const byte S7AreaMK = 0x83;
|
||||
public const byte S7AreaDB = 0x84;
|
||||
public const byte S7AreaCT = 0x1C;
|
||||
public const byte S7AreaTM = 0x1D;
|
||||
// Word Length
|
||||
public const int S7WLBit = 0x01;
|
||||
public const int S7WLByte = 0x02;
|
||||
public const int S7WLChar = 0x03;
|
||||
public const int S7WLWord = 0x04;
|
||||
public const int S7WLInt = 0x05;
|
||||
public const int S7WLDWord = 0x06;
|
||||
public const int S7WLDInt = 0x07;
|
||||
public const int S7WLReal = 0x08;
|
||||
public const int S7WLCounter = 0x1C;
|
||||
public const int S7WLTimer = 0x1D;
|
||||
// PLC Status
|
||||
public const int S7CpuStatusUnknown = 0x00;
|
||||
public const int S7CpuStatusRun = 0x08;
|
||||
public const int S7CpuStatusStop = 0x04;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct S7Tag
|
||||
{
|
||||
public Int32 Area;
|
||||
public Int32 DBNumber;
|
||||
public Int32 Start;
|
||||
public Int32 Elements;
|
||||
public Int32 WordLen;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
164
Sharp7/S7MultiVar.cs
Normal file
164
Sharp7/S7MultiVar.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Sharp7
|
||||
{
|
||||
public class S7MultiVar
|
||||
{
|
||||
#region [MultiRead/Write Helper]
|
||||
private S7Client FClient;
|
||||
private GCHandle[] Handles = new GCHandle[S7Client.MaxVars];
|
||||
private int Count = 0;
|
||||
private S7Client.S7DataItem[] Items = new S7Client.S7DataItem[S7Client.MaxVars];
|
||||
|
||||
|
||||
public int[] Results = new int[S7Client.MaxVars];
|
||||
|
||||
private bool AdjustWordLength(int Area, ref int WordLen, ref int Amount, ref int Start)
|
||||
{
|
||||
// Calc Word size
|
||||
int WordSize = S7.DataSizeByte(WordLen);
|
||||
if (WordSize == 0)
|
||||
return false;
|
||||
|
||||
if (Area == S7Consts.S7AreaCT)
|
||||
WordLen = S7Consts.S7WLCounter;
|
||||
if (Area == S7Consts.S7AreaTM)
|
||||
WordLen = S7Consts.S7WLTimer;
|
||||
|
||||
if (WordLen == S7Consts.S7WLBit)
|
||||
Amount = 1; // Only 1 bit can be transferred at time
|
||||
else
|
||||
{
|
||||
if ((WordLen != S7Consts.S7WLCounter) && (WordLen != S7Consts.S7WLTimer))
|
||||
{
|
||||
Amount = Amount * WordSize;
|
||||
Start = Start * 8;
|
||||
WordLen = S7Consts.S7WLByte;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public S7MultiVar(S7Client Client)
|
||||
{
|
||||
FClient = Client;
|
||||
for (int c = 0; c < S7Client.MaxVars; c++)
|
||||
Results[c] = (int)S7Consts.errCliItemNotAvailable;
|
||||
}
|
||||
~S7MultiVar()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
public bool Add<T>(S7Consts.S7Tag Tag, ref T[] Buffer, int Offset)
|
||||
{
|
||||
return Add(Tag.Area, Tag.WordLen, Tag.DBNumber, Tag.Start, Tag.Elements, ref Buffer, Offset);
|
||||
}
|
||||
|
||||
public bool Add<T>(S7Consts.S7Tag Tag, ref T[] Buffer)
|
||||
{
|
||||
return Add(Tag.Area, Tag.WordLen, Tag.DBNumber, Tag.Start, Tag.Elements, ref Buffer);
|
||||
}
|
||||
|
||||
public bool Add<T>(Int32 Area, Int32 WordLen, Int32 DBNumber, Int32 Start, Int32 Amount, ref T[] Buffer)
|
||||
{
|
||||
return Add(Area, WordLen, DBNumber, Start, Amount, ref Buffer, 0);
|
||||
}
|
||||
|
||||
public bool Add<T>(Int32 Area, Int32 WordLen, Int32 DBNumber, Int32 Start, Int32 Amount, ref T[] Buffer, int Offset)
|
||||
{
|
||||
if (Count < S7Client.MaxVars)
|
||||
{
|
||||
if (AdjustWordLength(Area, ref WordLen, ref Amount, ref Start))
|
||||
{
|
||||
Items[Count].Area = Area;
|
||||
Items[Count].WordLen = WordLen;
|
||||
Items[Count].Result = (int)S7Consts.errCliItemNotAvailable;
|
||||
Items[Count].DBNumber = DBNumber;
|
||||
Items[Count].Start = Start;
|
||||
Items[Count].Amount = Amount;
|
||||
GCHandle handle = GCHandle.Alloc(Buffer, GCHandleType.Pinned);
|
||||
#if WINDOWS_UWP || NETFX_CORE
|
||||
if (IntPtr.Size == 4)
|
||||
Items[Count].pData = (IntPtr)(handle.AddrOfPinnedObject().ToInt32() + Offset * Marshal.SizeOf<T>());
|
||||
else
|
||||
Items[Count].pData = (IntPtr)(handle.AddrOfPinnedObject().ToInt64() + Offset * Marshal.SizeOf<T>());
|
||||
#else
|
||||
if (IntPtr.Size == 4)
|
||||
Items[Count].pData = (IntPtr)(handle.AddrOfPinnedObject().ToInt32() + Offset * Marshal.SizeOf(typeof(T)));
|
||||
else
|
||||
Items[Count].pData = (IntPtr)(handle.AddrOfPinnedObject().ToInt64() + Offset * Marshal.SizeOf(typeof(T)));
|
||||
#endif
|
||||
Handles[Count] = handle;
|
||||
Count++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public int Read()
|
||||
{
|
||||
int FunctionResult;
|
||||
int GlobalResult = (int)S7Consts.errCliFunctionRefused;
|
||||
try
|
||||
{
|
||||
if (Count > 0)
|
||||
{
|
||||
FunctionResult = FClient.ReadMultiVars(Items, Count);
|
||||
if (FunctionResult == 0)
|
||||
for (int c = 0; c < S7Client.MaxVars; c++)
|
||||
Results[c] = Items[c].Result;
|
||||
GlobalResult = FunctionResult;
|
||||
}
|
||||
else
|
||||
GlobalResult = (int)S7Consts.errCliFunctionRefused;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Clear(); // handles are no more needed and MUST be freed
|
||||
}
|
||||
return GlobalResult;
|
||||
}
|
||||
|
||||
public int Write()
|
||||
{
|
||||
int FunctionResult;
|
||||
int GlobalResult = (int)S7Consts.errCliFunctionRefused;
|
||||
try
|
||||
{
|
||||
if (Count > 0)
|
||||
{
|
||||
FunctionResult = FClient.WriteMultiVars(Items, Count);
|
||||
if (FunctionResult == 0)
|
||||
for (int c = 0; c < S7Client.MaxVars; c++)
|
||||
Results[c] = Items[c].Result;
|
||||
GlobalResult = FunctionResult;
|
||||
}
|
||||
else
|
||||
GlobalResult = (int)S7Consts.errCliFunctionRefused;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Clear(); // handles are no more needed and MUST be freed
|
||||
}
|
||||
return GlobalResult;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (int c = 0; c < Count; c++)
|
||||
{
|
||||
if (Handles[c] != null)
|
||||
Handles[c].Free();
|
||||
}
|
||||
Count = 0;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
88
Sharp7/S7Timer.cs
Normal file
88
Sharp7/S7Timer.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Sharp7
|
||||
{
|
||||
public class S7Timer
|
||||
{
|
||||
#region S7Timer
|
||||
TimeSpan pt;
|
||||
TimeSpan et;
|
||||
bool input = false;
|
||||
bool q = false;
|
||||
public S7Timer(byte[] buff, int position)
|
||||
{
|
||||
if (position + 12 < buff.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTimer(new List<byte>(buff).GetRange(position, 16).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public S7Timer(byte[] buff)
|
||||
{
|
||||
SetTimer(buff);
|
||||
}
|
||||
|
||||
private void SetTimer(byte[] buff)
|
||||
{
|
||||
if (buff.Length != 12)
|
||||
{
|
||||
this.pt = new TimeSpan(0);
|
||||
this.et = new TimeSpan(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Int32 resPT;
|
||||
resPT = buff[0]; resPT <<= 8;
|
||||
resPT += buff[1]; resPT <<= 8;
|
||||
resPT += buff[2]; resPT <<= 8;
|
||||
resPT += buff[3];
|
||||
this.pt = new TimeSpan(0, 0, 0, 0, resPT);
|
||||
|
||||
Int32 resET;
|
||||
resET = buff[4]; resET <<= 8;
|
||||
resET += buff[5]; resET <<= 8;
|
||||
resET += buff[6]; resET <<= 8;
|
||||
resET += buff[7];
|
||||
this.et = new TimeSpan(0, 0, 0, 0, resET);
|
||||
|
||||
this.input = (buff[8] & 0x01) == 0x01;
|
||||
this.q = (buff[8] & 0x02) == 0x02;
|
||||
}
|
||||
}
|
||||
public TimeSpan PT
|
||||
{
|
||||
get
|
||||
{
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
public TimeSpan ET
|
||||
{
|
||||
get
|
||||
{
|
||||
return et;
|
||||
}
|
||||
}
|
||||
public bool IN
|
||||
{
|
||||
get
|
||||
{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
public bool Q
|
||||
{
|
||||
get
|
||||
{
|
||||
return q;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3754
Sharp7/Sharp7.cs
3754
Sharp7/Sharp7.cs
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Sharp7.cs" />
|
||||
<Compile Include="S7.cs" />
|
||||
<Compile Include="S7Client.cs" />
|
||||
<Compile Include="S7Consts.cs" />
|
||||
<Compile Include="S7MultiVar.cs" />
|
||||
<Compile Include="S7Timer.cs" />
|
||||
<Compile Include="MsgSocket.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -8,6 +8,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Multi-platform Ethernet S7 PLC communication suite (C# port of Snap7 Client by davenardella)</description>
|
||||
<projectUrl>https://github.com/fbarresi/Sharp7</projectUrl>
|
||||
<licenseUrl>https://raw.githubusercontent.com/fbarresi/Sharp7/master/LICENSE</licenseUrl>
|
||||
<copyright>Copyright 2018</copyright>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
Reference in New Issue
Block a user