323 lines
12 KiB
C#
323 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
//using System.Windows.Threading;
|
|
using System.Threading;
|
|
using System.Runtime.InteropServices;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using IniFiles;
|
|
|
|
namespace SCMCncLib
|
|
{
|
|
#region ESA_DATA_STRUCTURES
|
|
// public unsafe struct TS_REG
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
|
|
struct TS_REG
|
|
{
|
|
byte board;
|
|
byte iBaseReg;
|
|
UInt16 wType;
|
|
UInt32 iSharedId;
|
|
UInt32 iNum;
|
|
UInt32 iMax;
|
|
UInt32 iSiz;
|
|
UInt32 iOff;
|
|
UInt32 ChkSum;
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Class for EsaGv Nc device
|
|
/// </summary>
|
|
public class thdNcEsaGvKvara : thdNcBase
|
|
{
|
|
private UInt16 ReadNumber;
|
|
private UInt16 WriteNumber;
|
|
private UInt16 VAreaByteSize;
|
|
private UInt16 EOKAreaByteSize;
|
|
private UInt16 ETKAreaByteSize;
|
|
private UInt16 AlarmByteSize;
|
|
|
|
|
|
private string SysLink = "";
|
|
private string DefCn = "";
|
|
private int iChannel;
|
|
private int iError;
|
|
|
|
|
|
private string StatusAddressName;
|
|
private TS_REG StatusAddress;
|
|
|
|
private string CommandsAddressName;
|
|
private TS_REG CommandsAddress;
|
|
|
|
private string VAreaAddressName;
|
|
private TS_REG VAreaAddress;
|
|
|
|
private string EOKAreaAddressName;
|
|
private TS_REG EOKAreaAddress;
|
|
|
|
private string ETKAreaAddressName;
|
|
private TS_REG ETKAreaAddress;
|
|
|
|
private string PlcErrAreaAddressName;
|
|
private TS_REG PlcErrAreaAddress;
|
|
|
|
/// <summary>
|
|
/// Memorie a 4 byte (32 bit)
|
|
/// </summary>
|
|
public UInt32[] PLC_MemoryRead;
|
|
public UInt32[] PLC_MemoryWrite;
|
|
|
|
/// <summary>
|
|
/// Area V: memoria temp di UINT di 4 byte (32 bit)
|
|
/// </summary>
|
|
public UInt32[] PLC_MemAreaV_tmp;
|
|
/// <summary>
|
|
/// memorie a 1 byte (8 bit) x area EOK (status e valori vari)
|
|
/// </summary>
|
|
public uint[] PLC_MemoryAreaEOK;
|
|
/// <summary>
|
|
/// memorie a 1 byte (32 bit) x area ETK (status e valori vari)
|
|
/// </summary>
|
|
public UInt32[] PLC_MemoryAreaETK;
|
|
/// <summary>
|
|
/// Area Allarmi: memoria temp di UINT di 4 byte (32 bit)
|
|
/// </summary>
|
|
public UInt32[] PLC_MemAreaAlarm_tmp;
|
|
/// <summary>
|
|
/// memorie a 4 byte (32 bit) x area V (status e valori vari)
|
|
/// </summary>
|
|
public Byte[] PLC_MemoryAreaV;
|
|
/// <summary>
|
|
/// memorie a 1 byte (8 bit) x area Allarmi (V[300] - 256 bit)
|
|
/// </summary>
|
|
public Byte[] PLC_MemoryAreaAllarmi;
|
|
|
|
// esa constants
|
|
#region ESA_PLC_CONSTANTS
|
|
private const UInt32 MAX_PATH = 256;
|
|
#endregion
|
|
|
|
#region ESA_DLL_IMPORT_FUNCTIONS
|
|
[DllImport("KvCom3x", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "_ConvComunicationChannel@4")]
|
|
private static extern int ConvComunicationChannel([MarshalAs(UnmanagedType.LPStr)] string sChannelType);
|
|
|
|
[DllImport("KvCom3x", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "_init_board@8")]
|
|
private static extern int init_board([MarshalAs(UnmanagedType.LPStr)]string defcn_name, int ChannelType);
|
|
|
|
[DllImport("KvCom3x", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "_exit_board@0")]
|
|
private static extern int exit_board();
|
|
|
|
[DllImport("KvCom3x", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "_get_reg_by_name@8")]
|
|
private static extern int get_reg_by_name([MarshalAs(UnmanagedType.LPStr)]string name, ref TS_REG pReg);
|
|
|
|
[DllImport("KvCom3x", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "_read_regbuffer@16")]
|
|
private static extern int read_regbuffer(ref TS_REG pReg, UInt16 Offset, UInt16 Count, [MarshalAs(UnmanagedType.LPArray)] UInt32[] pDst);
|
|
|
|
[DllImport("KvCom3x", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "_write_regbuffer@16")]
|
|
private static extern int write_regbuffer(ref TS_REG pReg, UInt16 Offset, UInt16 Count, [MarshalAs(UnmanagedType.LPArray)] UInt32[] pSrc);
|
|
|
|
[DllImport("VKEnv", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
|
private static extern void ENVGetProfileString(
|
|
[MarshalAs(UnmanagedType.LPStr)] string AppName,
|
|
[MarshalAs(UnmanagedType.LPStr)] string KeyName,
|
|
[MarshalAs(UnmanagedType.LPStr)] string Default,
|
|
//[MarshalAs(UnmanagedType.LPArray)] byte[] ReturnedString,
|
|
[MarshalAs(UnmanagedType.LPStr)] StringBuilder ReturnedString,
|
|
UInt32 nSize);
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// After calling this method the search path is:
|
|
/// 1 - The directory from which the application loaded
|
|
/// 2 - The directory specified by the lpPathName parameter
|
|
/// 3 - The system directory (The name of this directory is System32)
|
|
/// 4 - The 16-bit system directory (The name of this directory is System)
|
|
/// 5 - The Windows directory
|
|
/// 6 - The directories that are listed in the PATH environment variable
|
|
/// </summary>
|
|
/// <param name="lpPathName"></param>
|
|
/// <returns></returns>
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
static extern bool SetDllDirectory(string lpPathName);
|
|
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="thdNcEsaGvKvara"/> class.
|
|
/// </summary>
|
|
/// <param name="fIni">The f ini.</param>
|
|
public thdNcEsaGvKvara(IniFile fIni) : base(fIni)
|
|
{
|
|
DeviceType = NC_DEVICE_TYPE.ESAGV_KVARA;
|
|
|
|
StringBuilder tempS = new StringBuilder(Convert.ToInt32(MAX_PATH));
|
|
|
|
// set executable path
|
|
SetDllDirectory(fIni.ReadString("NC", "SysExe", "C:\\KVARA\\EXE"));
|
|
|
|
// communication type
|
|
string defValue = fIni.ReadString("NC", "SysLink", "SIMULATO");
|
|
ENVGetProfileString("SYS", "LINK", defValue, tempS, MAX_PATH);
|
|
//bufferH.Free();
|
|
SysLink = tempS.ToString();
|
|
|
|
// communication channel
|
|
iChannel = ConvComunicationChannel(SysLink);
|
|
// definition path
|
|
defValue = fIni.ReadString("NC", "SysDefCn", "C:\\KVARA\\DISCOI");
|
|
ENVGetProfileString("SYS", "DEFCN", defValue, tempS, MAX_PATH);
|
|
DefCn = tempS.ToString() + "\\defcn";
|
|
//StrCat(DefCn, "\\defcn");
|
|
|
|
|
|
ReadNumber = 265;
|
|
WriteNumber = 265;
|
|
VAreaByteSize = 32;
|
|
ETKAreaByteSize = 8;
|
|
EOKAreaByteSize = 32; // era 14aggiunto sino a 31 x avere 91...
|
|
AlarmByteSize = 32;
|
|
|
|
CommandsAddressName = fIni.ReadString("NC", "CommandsAddress", "SIMREAD[0]");
|
|
EOKAreaAddressName = fIni.ReadString("NC", "EOKAreaAddress", "EOK");
|
|
ETKAreaAddressName = fIni.ReadString("NC", "ETKAreaAddress", "ETK");
|
|
PlcErrAreaAddressName = fIni.ReadString("NC", "PlcErrAreaAddress", "V");
|
|
StatusAddressName = fIni.ReadString("NC", "StatusAddress", "SIMWRITE[0]");
|
|
VAreaAddressName = fIni.ReadString("NC", "VAreaAddress", "V");
|
|
|
|
/**************************************************
|
|
* Creazione buffers letture memoria
|
|
**************************************************/
|
|
|
|
// create read buffer 32bit
|
|
PLC_MemoryRead = new UInt32[ReadNumber];
|
|
// create write buffer 32bit
|
|
PLC_MemoryWrite = new UInt32[WriteNumber];
|
|
|
|
// creazione buffers a 32bit
|
|
PLC_MemAreaV_tmp = new UInt32[(int)Math.Ceiling((decimal)VAreaByteSize / 4)];
|
|
|
|
PLC_MemAreaAlarm_tmp = new UInt32[(int)Math.Ceiling((decimal)AlarmByteSize / 4)];
|
|
|
|
// creo array duali in bytes...
|
|
PLC_MemoryAreaV = new Byte[VAreaByteSize];
|
|
PLC_MemoryAreaAllarmi = new Byte[AlarmByteSize];
|
|
|
|
// creazione veri buffer già 32bit
|
|
PLC_MemoryAreaEOK = new uint[EOKAreaByteSize];
|
|
PLC_MemoryAreaETK = new UInt32[ETKAreaByteSize];
|
|
|
|
if (!Connect())
|
|
Disconnect();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Thread main execution
|
|
/// </summary>
|
|
public override void Execute()
|
|
{
|
|
while (!requestStop)
|
|
{
|
|
if (Connected)
|
|
{
|
|
// load data from NC
|
|
ReadBuffer();
|
|
// if requested make a pause
|
|
if (PlcDelay > 0)
|
|
Thread.Sleep(PlcDelay);
|
|
}
|
|
else if (!Connected)
|
|
{
|
|
// wait 5 sec and retry connection
|
|
Thread.Sleep(5000);
|
|
Connect();
|
|
}
|
|
else
|
|
Thread.Sleep(500);
|
|
}
|
|
|
|
if (Connected) Disconnect();
|
|
Finished = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the buffer.
|
|
/// </summary>
|
|
public void ReadBuffer()
|
|
{
|
|
// leggo da posizione memorie V/allarmi come TS_REG
|
|
iError = read_regbuffer(ref PlcErrAreaAddress, 300, AlarmByteSize, PLC_MemAreaAlarm_tmp);
|
|
|
|
// lettura buffer dal CN
|
|
iError = read_regbuffer(ref StatusAddress, 0, ReadNumber, PLC_MemoryRead);
|
|
|
|
// leggo da posizione memorie V come TS_REG
|
|
iError = read_regbuffer(ref VAreaAddress, 68, VAreaByteSize, PLC_MemAreaV_tmp);
|
|
|
|
// leggo da posizione memorie EOK TS_REG
|
|
iError = read_regbuffer(ref EOKAreaAddress, 60, EOKAreaByteSize, PLC_MemoryAreaEOK);
|
|
|
|
// copio in array a byte...
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemAreaV_tmp, 0, PLC_MemoryAreaV, 0, VAreaByteSize);
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemAreaAlarm_tmp, 0, PLC_MemoryAreaAllarmi, 0, AlarmByteSize);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connects to device.
|
|
/// </summary>
|
|
/// <returns>True if connection is ok</returns>
|
|
public bool Connect()
|
|
{
|
|
// inizializzazione comunicazione
|
|
iError = init_board(DefCn, iChannel);
|
|
|
|
// inizializzo i registri di lettura e scrittura
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(CommandsAddressName, ref CommandsAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(EOKAreaAddressName, ref EOKAreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(PlcErrAreaAddressName, ref PlcErrAreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(StatusAddressName, ref StatusAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(VAreaAddressName, ref VAreaAddress);
|
|
|
|
Connected = (iError == 0);
|
|
return Connected;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disconnects device.
|
|
/// </summary>
|
|
public void Disconnect()
|
|
{
|
|
iError = exit_board();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esa virtual Nc needs 2ms of multimedia timer to work in real time
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool CheckMultimediaTimer()
|
|
{
|
|
int minimumPeriod = TimePeriod.MinimumPeriod;
|
|
//int maximumPeriod = TimePeriod.MaximumPeriod;
|
|
return ((minimumPeriod <= 2) && (minimumPeriod > 0));
|
|
}
|
|
|
|
}
|
|
}
|