384 lines
15 KiB
C#
384 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
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 IOT_ByteAreaByteSize;
|
|
private UInt16 IOT_WordAreaByteSize;
|
|
private UInt16 IOT_DWordAreaByteSize;
|
|
private UInt16 IOT_String_AreaByteSize;
|
|
|
|
|
|
private string SysLink = "";
|
|
private string DefCn = "";
|
|
private int iChannel;
|
|
private int iError;
|
|
|
|
private string IOT_ByteAreaAddressName;
|
|
private TS_REG IOT_ByteAreaAddress;
|
|
|
|
private string IOT_WordAreaAddressName;
|
|
private TS_REG IOT_WordAreaAddress;
|
|
|
|
private string IOT_DWordAreaAddressName;
|
|
private TS_REG IOT_DWordAreaAddress;
|
|
|
|
private string IOT_StringA_AreaAddressName;
|
|
private TS_REG IOT_StringA_AreaAddress;
|
|
private string IOT_StringB_AreaAddressName;
|
|
private TS_REG IOT_StringB_AreaAddress;
|
|
private string IOT_StringC_AreaAddressName;
|
|
private TS_REG IOT_StringC_AreaAddress;
|
|
private string IOT_StringD_AreaAddressName;
|
|
private TS_REG IOT_StringD_AreaAddress;
|
|
|
|
/// <summary>
|
|
/// Area IOT_Byte: memoria temp di UINT di 4 byte (32 bit)
|
|
/// </summary>
|
|
public UInt32[] PLC_MemoryAreaIOT_Byte_tmp;
|
|
/// <summary>
|
|
/// Area IOT_Word: memoria temp di UINT di 4 byte (32 bit)
|
|
/// </summary>
|
|
public UInt32[] PLC_MemoryAreaIOT_Word_tmp;
|
|
/// <summary>
|
|
/// memorie a 1 byte (8 bit) x area IOT.Byte
|
|
/// </summary>
|
|
public Byte[] PLC_MemoryAreaIOT_Byte;
|
|
/// <summary>
|
|
/// memorie a 2 byte (16 bit) x area IOT.Word
|
|
/// </summary>
|
|
public UInt16[] PLC_MemoryAreaIOT_Word;
|
|
/// <summary>
|
|
/// memorie a 4 byte (32 bit) x area IOT.DWord
|
|
/// </summary>
|
|
public UInt32[] PLC_MemoryAreaIOT_DWord;
|
|
/// <summary>
|
|
/// memorie TEMP x area IOT.String
|
|
/// </summary>
|
|
public UInt32[] PLC_MemoryAreaIOT_String_tmp;
|
|
/// <summary>
|
|
/// memorie a 1 byte (8 bit) x area IOT.String (singoli caratteri...)
|
|
/// </summary>
|
|
public Byte[] PLC_MemoryAreaIOT_String_row;
|
|
/// <summary>
|
|
/// memorie a 1 byte (8 bit) x area IOT.String (singoli caratteri...)
|
|
/// </summary>
|
|
public Byte[,] PLC_MemoryAreaIOT_String;
|
|
|
|
// 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, int IAS_Byte, int IAS_Word, int IAS_DWord, int IAS_String) : 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";
|
|
|
|
// nuove aree: da init mi passa le dimensioni delle memorie
|
|
IOT_ByteAreaByteSize = Convert.ToUInt16(IAS_Byte);
|
|
IOT_WordAreaByteSize = Convert.ToUInt16(IAS_Word);
|
|
IOT_DWordAreaByteSize = Convert.ToUInt16(IAS_DWord);
|
|
IOT_String_AreaByteSize = Convert.ToUInt16(IAS_String);
|
|
|
|
// indirizzo area IOT...
|
|
IOT_ByteAreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressByte", "IOT.BYTE");
|
|
IOT_WordAreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressWord", "IOT.WORD");
|
|
IOT_DWordAreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressDWord", "IOT.DWORD");
|
|
IOT_StringA_AreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressStringA", "IOT.ProgramNameAreaA");
|
|
IOT_StringB_AreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressStringB", "IOT.ProgramNameAreaB");
|
|
IOT_StringC_AreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressStringC", "IOT.ProgramNameAreaC");
|
|
IOT_StringD_AreaAddressName = fIni.ReadString("NC", "IOT_AreaAddressStringD", "IOT.ProgramNameAreaD");
|
|
|
|
/**************************************************
|
|
* Creazione buffers letture memoria
|
|
**************************************************/
|
|
// creo array x aree memoria IOT...
|
|
PLC_MemoryAreaIOT_Byte_tmp = new UInt32[(int)Math.Ceiling((decimal)IOT_ByteAreaByteSize / 4)];
|
|
PLC_MemoryAreaIOT_Byte = new Byte[IOT_ByteAreaByteSize];
|
|
PLC_MemoryAreaIOT_Word_tmp = new UInt32[(int)Math.Ceiling((decimal)IOT_WordAreaByteSize / 2)];
|
|
PLC_MemoryAreaIOT_Word = new UInt16[IOT_WordAreaByteSize];
|
|
PLC_MemoryAreaIOT_DWord = new UInt32[IOT_DWordAreaByteSize];
|
|
PLC_MemoryAreaIOT_String_tmp = new UInt32[(int)Math.Ceiling((decimal)IOT_String_AreaByteSize / 4)];
|
|
PLC_MemoryAreaIOT_String_row = new Byte[IOT_String_AreaByteSize * 4]; // HARD CODED 4 aree consecutive in riga...
|
|
PLC_MemoryAreaIOT_String = new Byte[4, IOT_String_AreaByteSize]; // HARD CODED 4 aree su vettore di 4 righe...
|
|
|
|
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>
|
|
/// Leggo il buffer di memorie BYTE
|
|
/// </summary>
|
|
public void ReadBufferByte()
|
|
{
|
|
// 2017.02: modifiche x nuova versione PLC: leggo intero buffer BYTE
|
|
iError = read_regbuffer(ref IOT_ByteAreaAddress, 0, IOT_ByteAreaByteSize, PLC_MemoryAreaIOT_Byte_tmp);
|
|
// ...e copio in array a byte...
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_Byte_tmp, 0, PLC_MemoryAreaIOT_Byte, 0, IOT_ByteAreaByteSize);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
/// <summary>
|
|
/// Leggo il buffer di memorie WORD
|
|
/// </summary>
|
|
public void ReadBufferWord()
|
|
{
|
|
// 2017.02: modifiche x nuova versione PLC: leggo intero buffer WORD
|
|
iError = read_regbuffer(ref IOT_WordAreaAddress, 0, IOT_WordAreaByteSize, PLC_MemoryAreaIOT_Word_tmp);
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_Word_tmp, 0, PLC_MemoryAreaIOT_Word, 0, IOT_WordAreaByteSize * 2);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
/// <summary>
|
|
/// Leggo il buffer di memorie DWORD
|
|
/// </summary>
|
|
public void ReadBufferDWord()
|
|
{
|
|
// leggo intero buffer DWORD
|
|
iError = read_regbuffer(ref IOT_DWordAreaAddress, 0, IOT_DWordAreaByteSize, PLC_MemoryAreaIOT_DWord);
|
|
}
|
|
/// <summary>
|
|
/// Leggo il buffer di memorie STRING
|
|
/// </summary>
|
|
public void ReadBufferString()
|
|
{
|
|
// leggo intero buffer StringA
|
|
iError = read_regbuffer(ref IOT_StringA_AreaAddress, 0, IOT_String_AreaByteSize, PLC_MemoryAreaIOT_String_tmp);
|
|
// ...e copio in array a byte...
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_String_tmp, 0, PLC_MemoryAreaIOT_String_row, 0, IOT_String_AreaByteSize);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
|
|
// leggo intero buffer StringB
|
|
iError = read_regbuffer(ref IOT_StringB_AreaAddress, 0, IOT_String_AreaByteSize, PLC_MemoryAreaIOT_String_tmp);
|
|
// ...e copio in array a byte...
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_String_tmp, 0, PLC_MemoryAreaIOT_String_row, IOT_String_AreaByteSize * 1, IOT_String_AreaByteSize);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
|
|
// leggo intero buffer StringC
|
|
iError = read_regbuffer(ref IOT_StringC_AreaAddress, 0, IOT_String_AreaByteSize, PLC_MemoryAreaIOT_String_tmp);
|
|
// ...e copio in array a byte...
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_String_tmp, 0, PLC_MemoryAreaIOT_String_row, IOT_String_AreaByteSize * 2, IOT_String_AreaByteSize);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
|
|
// leggo intero buffer StringD
|
|
iError = read_regbuffer(ref IOT_StringD_AreaAddress, 0, IOT_String_AreaByteSize, PLC_MemoryAreaIOT_String_tmp);
|
|
// ...e copio in array a byte...
|
|
try
|
|
{
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_String_tmp, 0, PLC_MemoryAreaIOT_String_row, IOT_String_AreaByteSize * 3, IOT_String_AreaByteSize);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
|
|
// copio in vettore 2D...
|
|
Buffer.BlockCopy(PLC_MemoryAreaIOT_String_row, 0, PLC_MemoryAreaIOT_String, 0, IOT_String_AreaByteSize * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Reads the buffer.
|
|
/// </summary>
|
|
public void ReadBuffer()
|
|
{
|
|
ReadBufferByte();
|
|
ReadBufferWord();
|
|
ReadBufferDWord();
|
|
ReadBufferString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connects to device.
|
|
/// </summary>
|
|
/// <returns>True if connection is ok</returns>
|
|
public bool Connect()
|
|
{
|
|
// inizializzazione comunicazione
|
|
iError = init_board(DefCn, iChannel);
|
|
|
|
// effetto le vere letture!
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_ByteAreaAddressName, ref IOT_ByteAreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_WordAreaAddressName, ref IOT_WordAreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_DWordAreaAddressName, ref IOT_DWordAreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_StringA_AreaAddressName, ref IOT_StringA_AreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_StringB_AreaAddressName, ref IOT_StringB_AreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_StringC_AreaAddressName, ref IOT_StringC_AreaAddress);
|
|
if (iError == 0)
|
|
iError = get_reg_by_name(IOT_StringD_AreaAddressName, ref IOT_StringD_AreaAddress);
|
|
|
|
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));
|
|
}
|
|
|
|
}
|
|
}
|