439a61cd59
FIx Fanuc
4218 lines
169 KiB
C#
4218 lines
169 KiB
C#
using CMS_CORE_Library.Models;
|
|
using CMS_CORE_Library.Utils;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using static CMS_CORE_Library.Fanuc.MEMORY_ADDRESS;
|
|
using static CMS_CORE_Library.Models.DataStructures;
|
|
using static CMS_CORE_Library.Nc;
|
|
using static CMS_CORE_Library.ToolConfigurations;
|
|
using static CMS_CORE_Library.Utils.Nc_Utils;
|
|
using static Focas1;
|
|
|
|
#pragma warning disable 1591
|
|
|
|
namespace CMS_CORE_Library.Fanuc
|
|
{
|
|
public class Nc_Fanuc : Nc
|
|
{
|
|
private int TimeOut;
|
|
private Focas1 FocasEnv;
|
|
private List<ushort> nLibHandle;
|
|
private string Cnc_name;
|
|
private string Cnc_SftVersion;
|
|
private string Cnc_SeriesNum;
|
|
private short Cnc_NumPath;
|
|
private byte FanucLanguage;
|
|
private DateTime Last_Static_Read;
|
|
|
|
private static int OFFSET_DECIMAL_DIGITS = 0;
|
|
private static int MAX_OFFSET_NUM = 0;
|
|
|
|
// Paths
|
|
private const string NC_SUPPORT_FILE_PATH = "//CNC_MEM/USER/PATH1/CMS/";
|
|
|
|
private const string PLC_MESSAGE_PATH = "C:/CMS/FANUC/";
|
|
|
|
private const string BLANK_PART_PROGRAM_PATH = NC_SUPPORT_FILE_PATH + "BLANK";
|
|
|
|
// Const
|
|
private const int TOOL_OFFSET = 300;
|
|
private const string M198_FILE_CONTENT = "%\n<ACTIVE_LOADER_{0}>" +
|
|
"\n" +
|
|
"M198<{1}>"+
|
|
"\n"+
|
|
"%";
|
|
private const string M198_FILE_NAME = "ACTIVE_LOADER_{0}";
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region Contructor & global methods
|
|
|
|
/**
|
|
* <summary>
|
|
* Instantiate The NC-Fanuc Class
|
|
* </summary>
|
|
* <param name="IpAddress">Remote Ip-Address of the Nc</param>
|
|
* <param name="RemotePort">Remote Port of the Nc</param>
|
|
* <param name="ConnectionTimeOut">Send/Recieve timeout connection [mS]</param>
|
|
* */
|
|
|
|
public Nc_Fanuc(string IpAddress, ushort RemotePort, ushort ConnectionTimeOut)
|
|
{
|
|
//Set internal valiables
|
|
Connected = false;
|
|
Ip = IpAddress;
|
|
Port = RemotePort;
|
|
TimeOut = ConnectionTimeOut / 1000;
|
|
|
|
//Istantiate the Focas Library
|
|
FocasEnv = new Focas1();
|
|
nLibHandle = new List<ushort>();
|
|
}
|
|
|
|
//Connect Method
|
|
public override CmsError NC_Connect()
|
|
{
|
|
// Try to connect to The NC
|
|
short nReturn = Focas1.cnc_allclibhndl3(Ip, Port, TimeOut, out ushort TempLibHandle);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
else
|
|
nLibHandle.Add(TempLibHandle);
|
|
|
|
// Read the Actual Paths
|
|
nReturn = Focas1.cnc_getpath(nLibHandle[0], out short ActivePath, out Cnc_NumPath);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Setup all Paths
|
|
for (short i = 0; i < Cnc_NumPath; i++)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
nReturn = Focas1.cnc_allclibhndl3(Ip, Port, TimeOut, out TempLibHandle);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
else
|
|
nLibHandle.Add(TempLibHandle);
|
|
}
|
|
|
|
nReturn = Focas1.cnc_setpath(nLibHandle[i], (short)(i + 1));
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
}
|
|
|
|
// Read offset decimal digits
|
|
if (OFFSET_DECIMAL_DIGITS == 0)
|
|
{
|
|
short[] input = new short[20];
|
|
short[] output = new short[20];
|
|
nReturn = Focas1.cnc_getfigure(nLibHandle[0], 1, out short val, input, output);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
OFFSET_DECIMAL_DIGITS = input[0];
|
|
}
|
|
|
|
// Read max number of offsets
|
|
if (MAX_OFFSET_NUM == 0)
|
|
{
|
|
ODBTLINF2 info = new ODBTLINF2();
|
|
nReturn = Focas1.cnc_rdtofsinfo2(nLibHandle[0], info);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
MAX_OFFSET_NUM = info.use_no;
|
|
}
|
|
|
|
// Setup the "Connected" value to TRUE
|
|
Connected = true;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Disconnect Method
|
|
public override CmsError NC_Disconnect()
|
|
{
|
|
if (Connected)
|
|
{
|
|
short nReturn;
|
|
|
|
//If is connected -> Disconncet
|
|
foreach (ushort handle in nLibHandle)
|
|
{
|
|
nReturn = Focas1.cnc_freelibhndl(handle);
|
|
}
|
|
|
|
//Setup the "Connected" value to FALSE
|
|
Connected = false;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_GetTranslatedPlcMessages(string language, ref Dictionary<int, string> messages)
|
|
{
|
|
string filePath;
|
|
try
|
|
{
|
|
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(language);
|
|
string langName = "";
|
|
if (cultureInfo.IsNeutralCulture)
|
|
langName = cultureInfo.EnglishName;
|
|
else
|
|
langName = cultureInfo.Parent.EnglishName;
|
|
|
|
//Setup the Path
|
|
filePath = PLC_MESSAGE_PATH + @"Messaggi_" + langName + @".txt";
|
|
|
|
if (!File.Exists(filePath))
|
|
return FILE_NOT_FOUND_ERROR;
|
|
|
|
// Read From Files
|
|
var fileLines = File.ReadAllLines(filePath);
|
|
|
|
// Parse strings
|
|
messages = fileLines
|
|
.Skip(1)
|
|
.Take(fileLines.Count() - 2)
|
|
.Select(line => line.Split(' '))
|
|
.ToDictionary(line =>
|
|
Convert.ToInt32(line[2]),
|
|
line => String.Join(" ", line.Skip(3)
|
|
)
|
|
);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
}
|
|
|
|
#endregion Contructor & global methods
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region High level methods
|
|
|
|
// Get the NC Language
|
|
public override CmsError NC_RLanguage(ref CultureInfo Language)
|
|
{
|
|
// Read static data
|
|
CmsError cmsError = ReadStaticNCData();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Language = ConvertToSTEPLanguage(FanucLanguage);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Set the NC Language
|
|
public override CmsError NC_WLanguage(CultureInfo Language)
|
|
{
|
|
// set but 7 to TRUE
|
|
byte langToWrite = (byte)(ConvertToNCLanguage(Language) | 128);
|
|
|
|
// write the byte
|
|
CmsError cmsError = MEM_RWByte(W, 0, PARAM_LING_FANUC_W.MemType, PARAM_LING_FANUC_W.Address, 0, ref langToWrite);
|
|
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the NC Serial Number
|
|
public override CmsError NC_RSerialNumber(ref string SN)
|
|
{
|
|
// Read static data
|
|
CmsError cmsError = ReadStaticNCData();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
SN = Cnc_SeriesNum;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the NC Software Version
|
|
public override CmsError NC_RSoftwareVersion(ref string SWV)
|
|
{
|
|
// Read static data
|
|
CmsError cmsError = ReadStaticNCData();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
SWV = Cnc_SftVersion;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the NC model Name
|
|
public override CmsError NC_RModelName(ref string ModelName)
|
|
{
|
|
// Read static data
|
|
CmsError cmsError = ReadStaticNCData();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
ModelName = Cnc_name;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the processes-count configurated
|
|
public override CmsError NC_RProcessesNum(ref ushort ProcNumber)
|
|
{
|
|
////Read static data
|
|
//CmsError cmsError = ReadStaticNCData();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
ProcNumber = (ushort)Cnc_NumPath;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the NC Time
|
|
public override CmsError NC_RDateTime(ref DateTime ActualTime)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.IODBTIMER TimerDate = new Focas1.IODBTIMER();
|
|
Focas1.IODBTIMER TimerTime = new Focas1.IODBTIMER();
|
|
short nReturn = 0;
|
|
|
|
//Setup the IODBTIMER
|
|
TimerDate.type = 0;
|
|
TimerTime.type = 1;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_gettimer(nLibHandle[0], TimerDate);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_gettimer(nLibHandle[0], TimerTime);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//Setup the out value
|
|
ActualTime = new DateTime(TimerDate.date.year, TimerDate.date.month, TimerDate.date.date, TimerTime.time.hour, TimerTime.time.minute, TimerTime.time.second);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the Machine Number
|
|
public override CmsError NC_RMachineNumber(ref string MachNumber)
|
|
{
|
|
ushort Value = 0;
|
|
|
|
// Read word
|
|
CmsError cmsError = MEM_RWWord(R, UNDEF_PROC, MATR_MACCH_FANUC.MemType, MATR_MACCH_FANUC.Address, ref Value);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
MachNumber = Value.ToString();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the NC Alarms
|
|
public override CmsError NC_RActiveAlarms(ref List<AlarmModel> alarms)
|
|
{
|
|
//// Check if the NC is Connected
|
|
//CmsError cmsError = CheckConnection();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
//alarms.Clear();
|
|
|
|
//Focas1.ODBALMMSG2 Messg = new Focas1.ODBALMMSG2();
|
|
//short nReturn = 0;
|
|
//short count = FANUC_MAXMSGCNC;
|
|
|
|
//// Get path index
|
|
//short path = GetHandleIndexFromPath(1);
|
|
//if (path < 0)
|
|
// return PROC_NOT_FOUND_ERROR;
|
|
|
|
////Execute the method
|
|
//nReturn = Focas1.cnc_rdalmmsg2(nLibHandle[path], -1, ref count, Messg);
|
|
|
|
////Throw Exception if there's an error
|
|
//if (nReturn != 0)
|
|
// return GetNcError(nReturn);
|
|
|
|
////Add Alarm in List
|
|
//alarms.Clear();
|
|
//if (count >= 1)
|
|
// AddNcAlarmToList((ushort)Messg.msg1.alm_no, Messg.msg1.alm_msg.Substring(0, Messg.msg1.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 2)
|
|
// AddNcAlarmToList((ushort)Messg.msg2.alm_no, Messg.msg2.alm_msg.Substring(0, Messg.msg2.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 3)
|
|
// AddNcAlarmToList((ushort)Messg.msg3.alm_no, Messg.msg3.alm_msg.Substring(0, Messg.msg3.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 4)
|
|
// AddNcAlarmToList((ushort)Messg.msg4.alm_no, Messg.msg4.alm_msg.Substring(0, Messg.msg4.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 5)
|
|
// AddNcAlarmToList((ushort)Messg.msg5.alm_no, Messg.msg5.alm_msg.Substring(0, Messg.msg5.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 6)
|
|
// AddNcAlarmToList((ushort)Messg.msg6.alm_no, Messg.msg6.alm_msg.Substring(0, Messg.msg6.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 7)
|
|
// AddNcAlarmToList((ushort)Messg.msg7.alm_no, Messg.msg7.alm_msg.Substring(0, Messg.msg7.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 8)
|
|
// AddNcAlarmToList((ushort)Messg.msg8.alm_no, Messg.msg8.alm_msg.Substring(0, Messg.msg8.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 9)
|
|
// AddNcAlarmToList((ushort)Messg.msg9.alm_no, Messg.msg9.alm_msg.Substring(0, Messg.msg9.msg_len), DateTime.Now, alarms);
|
|
//if (count >= 10)
|
|
// AddNcAlarmToList((ushort)Messg.msg10.alm_no, Messg.msg10.alm_msg.Substring(0, Messg.msg10.msg_len), DateTime.Now, alarms);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Check if the NC is in running state
|
|
public override CmsError NC_RIsRunning(ref bool running)
|
|
{
|
|
ushort nProcess = 0;
|
|
// Get the number of processes
|
|
CmsError cmsError = NC_RProcessesNum(ref nProcess);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
ushort i = 1;
|
|
running = false;
|
|
do
|
|
{
|
|
PROC_STATUS procStatus = PROC_STATUS.IDLE;
|
|
|
|
// Read process status
|
|
cmsError = PROC_RStatus(i, ref procStatus);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (procStatus == PROC_STATUS.RUN)
|
|
running = true;
|
|
i++;
|
|
} while (!running || i <= nProcess);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Set the Nc Active Page of the NC
|
|
public override CmsError NC_SetScreenVisible(SCREEN_PAGE screen)
|
|
{
|
|
short actualPage, nReturn;
|
|
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//Convert to Fanuc Ref
|
|
short pageToGo = (short)ConvertStepToFanucScreen(screen);
|
|
if (pageToGo == 0)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
//Read actual page
|
|
nReturn = Focas1.cnc_getcurscrn(nLibHandle[0], out actualPage);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//Write the new page
|
|
if (actualPage != pageToGo)
|
|
{
|
|
nReturn = Focas1.cnc_setcurscrn(nLibHandle[0], pageToGo);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get NC unit of measure
|
|
public override CmsError NC_RUnitOfMeasure(ref string unitOfMeasure)
|
|
{
|
|
bool val = false;
|
|
CmsError cmsError = MEM_RWBoolean(R, 0, MEMORY_TYPE.Fanuc_F, 2, 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
unitOfMeasure = val ? "inch" : "mm";
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion High level methods
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region PLC High-level data
|
|
|
|
public override CmsError PLC_RWManageWatchdog()
|
|
{
|
|
bool plcWatchdog = false;
|
|
CmsError cmsError = MEM_RWBoolean(R, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, 1, ref plcWatchdog);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (plcWatchdog)
|
|
{
|
|
plcWatchdog = false;
|
|
cmsError = MEM_RWBoolean(W, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, 1, ref plcWatchdog);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
cmsError = MEM_RWBoolean(R, 0, ACTIVE_WATCHDOG.MemType, ACTIVE_WATCHDOG.Address, 1, ref plcWatchdog);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
else
|
|
{
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get PMC Messages
|
|
public override CmsError PLC_RActiveMessages(ref List<PlcAlarmModel> alarms)
|
|
{
|
|
alarms.Clear();
|
|
List<int> readValues = new List<int>();
|
|
|
|
// Read on data from memory
|
|
CmsError cmsError = MEM_RWIntegerList(R, 0,
|
|
ALARMS_STATUS.MemType,
|
|
ALARMS_STATUS.Address,
|
|
(ALARMS_STATUS.Size / 4) + (ALARMS_DATA.Size / 2), // byte / 4
|
|
ref readValues);
|
|
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Convert integer array into bit array
|
|
bool[] statusBits = IntToBits(readValues.ToArray());
|
|
|
|
for (int i = 0; i < ALARMS_STATUS.Size * 8; i++)
|
|
{
|
|
// If alarm is active
|
|
if (statusBits[i])
|
|
{
|
|
// Calculate matching alarm byte info address
|
|
int dataByteAddress = (i * 16) + ALARMS_NUMBER;
|
|
|
|
var processList = new List<int>();
|
|
|
|
// Get processes on which alarm is active
|
|
for (int j = dataByteAddress; j < dataByteAddress + 6; j++)
|
|
{
|
|
if (statusBits[j])
|
|
processList.Add(j + 1 - dataByteAddress);
|
|
}
|
|
// Add alarm info into active alarms list
|
|
alarms.Add(new PlcAlarmModel()
|
|
{
|
|
Id = (uint)i + 1,
|
|
IsWarning = statusBits[dataByteAddress + 7],
|
|
RestorationIsActive = statusBits[dataByteAddress + 6],
|
|
Process = processList
|
|
});
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
|
|
////Check if the NC is Connected
|
|
//CmsError cmsError = CheckConnection();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
//Focas1.OPMSG3 Messg = new Focas1.OPMSG3();
|
|
//short nReturn = 0;
|
|
//short count = FANUC_MAXMSGPMC;
|
|
|
|
////Execute the method
|
|
//nReturn = Focas1.cnc_rdopmsg3(nLibHandle[0], -1, ref count, Messg);
|
|
|
|
////Throw Exception if there's an error
|
|
//if (nReturn != 0)
|
|
// return GetNcError(nReturn);
|
|
|
|
//// Add Alarm in List
|
|
//alarms.Clear();
|
|
|
|
//if (count >= 1 && Messg.msg1.datano >= 0)
|
|
// AddPlcAlarmsToList((ushort)Messg.msg1.datano, false, false, new List<int>() { 1 }, alarms);
|
|
|
|
//if (count >= 2 && Messg.msg2.datano >= 0)
|
|
// AddPlcAlarmsToList((ushort)Messg.msg2.datano, false, false, new List<int>() { 1 }, alarms);
|
|
|
|
//if (count >= 3 && Messg.msg3.datano >= 0)
|
|
// AddPlcAlarmsToList((ushort)Messg.msg3.datano, false, false, new List<int>() { 1 }, alarms);
|
|
|
|
//if (count >= 4 && Messg.msg4.datano >= 0)
|
|
// AddPlcAlarmsToList((ushort)Messg.msg4.datano, false, false, new List<int>() { 1 }, alarms);
|
|
|
|
//if (count >= 5 && Messg.msg5.datano >= 0)
|
|
// AddPlcAlarmsToList((ushort)Messg.msg5.datano, false, false, new List<int>() { 1 }, alarms);
|
|
}
|
|
|
|
public override CmsError PLC_WRefreshMessage(uint id)
|
|
{
|
|
// Set to 1 refresh strobe
|
|
CmsError cmsError = PLC_WStrobe(ALARM_ACK, ALARM_REFRESH_STROBE, id);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WRestoreMessage(uint id)
|
|
{
|
|
// Set to 1 restore strobe
|
|
CmsError cmsError = PLC_WStrobe(ALARM_ACK, ALARM_RESTORATION_STROBE, id);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WRefreshAllMessages()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get pre and post power on data
|
|
public override CmsError PLC_RPowerOnData(ref PreAndPostPowerOnModel powerOnModel)
|
|
{
|
|
int readValue = 0;
|
|
// Read pre power on and post power on data from memory
|
|
CmsError cmsError = MEM_RWInteger(R, 0, PRE_POST_POWER_ON.MemType, PRE_POST_POWER_ON.Address, ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] bits = new bool[32];
|
|
|
|
// Convert int into to true/false array
|
|
bits = IntToBits(readValue);
|
|
|
|
// Create adn set pre power on object
|
|
PrePowerOnModel prePowerOn = new PrePowerOnModel()
|
|
{
|
|
PowerOn = new PowerOnDataModel() { Id = 1, Active = bits[0], Clickable = bits[16] }, // id = N, bits = N, Clickable = N + 8 (Second bit)
|
|
AirPressure = new PowerOnDataModel() { Id = 2, Active = bits[1], Clickable = bits[17] },
|
|
ProtectionStatus = new PowerOnDataModel() { Id = 3, Active = bits[2], Clickable = bits[18] },
|
|
EmergencyButtons = new PowerOnDataModel() { Id = 4, Active = bits[3], Clickable = bits[19] },
|
|
SettingMode = new PowerOnDataModel() { Id = 5, Active = bits[4], Clickable = bits[20] },
|
|
StartingKey = new PowerOnDataModel() { Id = 6, Active = bits[5], Clickable = bits[21] }
|
|
};
|
|
// Create and set post power on object
|
|
PostPowerOnModel postPowerOn = new PostPowerOnModel()
|
|
{
|
|
AxisReset = new PowerOnDataModel() { Id = 9, Active = bits[8], Clickable = bits[24] }, // id = N - 8, bits = N, Clickable = N + 8 (Second bit)
|
|
WaterjetPump = new PowerOnDataModel() { Id = 10, Active = bits[9], Clickable = bits[25] }
|
|
};
|
|
|
|
powerOnModel = new PreAndPostPowerOnModel()
|
|
{
|
|
PostPowerOn = postPowerOn,
|
|
PrePowerOn = prePowerOn
|
|
};
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write power on data
|
|
public override CmsError PLC_WPowerOnData(uint id, bool value)
|
|
{
|
|
// Check bit range
|
|
if (id > 16)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Call restore message
|
|
CmsError cmsError = PLC_WStrobe(PRE_POST_POWER_ON_ACK, PRE_POST_POWER_ON_CLICKED, id);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get functionality data
|
|
public override CmsError PLC_RFunctionAccess(ref List<FunctionalityModel> functions)
|
|
{
|
|
List<int> readValues = new List<int>();
|
|
int numberOfIntegers = FUNCTION_ACCESS.Size / 4;
|
|
// Read functions access data from memory
|
|
CmsError cmsError = MEM_RWIntegerList(R, 0, FUNCTION_ACCESS.MemType, FUNCTION_ACCESS.Address, numberOfIntegers, ref readValues);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
functions = new List<FunctionalityModel>();
|
|
// Convert int into to true/false array
|
|
bool[] bits = IntToBits(readValues.ToArray());
|
|
|
|
// Convert array into structured data
|
|
for (int i = 0; i < bits.Count(); i++)
|
|
{
|
|
functions.Add(new FunctionalityModel()
|
|
{
|
|
Id = (uint)i + 1,
|
|
IsActive = bits[i]
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get axis reset procedure data
|
|
public override CmsError PLC_RAxesResetData(ref AxisResetDataModel axisResetData)
|
|
{
|
|
byte value = 0;
|
|
// Read byte from memory
|
|
CmsError cmsError = MEM_RWByte(R, 0, AXIS_RESET_PROCEDURE.MemType, AXIS_RESET_PROCEDURE.Address, 0, ref value);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Check last bit if is active
|
|
if ((value & 128) == 128)
|
|
{
|
|
// Set to 0 last bit( isActive bit x - 128 )
|
|
// From 0 to 6 bits represent percentage
|
|
// If higher than 100 then value = 100
|
|
byte percentage = value - 128 > 100 ? (byte)100 : (byte)(value - 128);
|
|
axisResetData = new AxisResetDataModel()
|
|
{
|
|
IsActive = true,
|
|
Percentage = percentage
|
|
};
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get all the machine counters
|
|
public override CmsError PLC_RMachineCounters(ref List<CounterModel> counters)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RNcSoftKeys(ref List<SoftKeysModel> ncSoftKeys)
|
|
{
|
|
CmsError cmsError = PLC_RSoftKeys(NC_SOFTKEYS_VALUE, NC_SOFTKEYS_CLICKABLE, ref ncSoftKeys);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RUserSoftKeys(ref List<SoftKeysModel> softKeys)
|
|
{
|
|
CmsError cmsError = PLC_RSoftKeys(USER_SOFTKEYS_VALUE, USER_SOFTKEYS_CLICKABLE, ref softKeys);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WNcSoftKey(uint id)
|
|
{
|
|
// Check id range
|
|
if (id > NC_SOFTKEYS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Write strobe into memory
|
|
CmsError cmsError = PLC_WStrobe(NC_SOFT_KEYS_ACK, NC_SOFT_KEYS_CLICKED, id);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WUserSoftKey(uint id)
|
|
{
|
|
// Check id range
|
|
if (id > USER_SOFTKEYS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Write strobe into memory
|
|
CmsError cmsError = PLC_WStrobe(USER_SOFT_KEYS_ACK, USER_SOFT_KEYS_CLICKED, id);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RHeadsData(List<HeadDataModel> heads, int number)
|
|
{
|
|
// Check parameters
|
|
if (number > MAX_HEADS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
heads.Clear();
|
|
|
|
List<int> readInts = new List<int>();
|
|
List<byte> readValues = new List<byte>();
|
|
// Find the size of a single head
|
|
int headsByte = (HEADS_DATA.Size / MAX_HEADS_NUMBER);
|
|
double headsInts = Math.Ceiling((double)(headsByte / 4) + 1);
|
|
|
|
// Read data for N heads
|
|
CmsError cmsError = MEM_RWIntegerList(R, 0, HEADS_DATA.MemType, 0, HEADS_DATA.Address, (int)headsInts * number, ref readInts);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
readValues = readInts.SelectMany(BitConverter.GetBytes).ToList();
|
|
|
|
// Parse and format read data
|
|
for (int i = 0; i < number; i++)
|
|
{
|
|
// Head address = posizion * size of single head in memory
|
|
var headOffset = i * headsByte;
|
|
heads.Add(new HeadDataModel()
|
|
{
|
|
Id = (uint)i + 1,
|
|
Process = readValues[headOffset],
|
|
Override = readValues[headOffset + 1],
|
|
Load_Abrasive = BitConverter.ToUInt16(readValues.ToArray(), headOffset + 2), // Uint 16 = 2byte
|
|
MountedTool_Vacum = BitConverter.ToInt16(readValues.ToArray(), headOffset + 4), // Uint 16 = 2byte
|
|
ActualSpeed_Pressure = BitConverter.ToInt32(readValues.ToArray(), headOffset + 6), // Int32 = 4byte
|
|
IsActive = (readValues[headOffset + 10] & 1) != 0, // bit 0
|
|
IsSelected = (readValues[headOffset + 10] & 2) != 0, // bit 1
|
|
OverrideEditable = (readValues[headOffset + 10] & 4) != 0 // bit 2
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WHeadOverride(uint id, HEAD_OVERRIDE_SIGN sign)
|
|
{
|
|
if (id > MAX_HEADS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
MEMORY_CELL currentStrobeCell = sign == HEAD_OVERRIDE_SIGN.PLUS ? HEADS_STROBE_INCREMENT : HEADS_STROBE_DECREMENT;
|
|
|
|
// Write strobe into memory
|
|
CmsError cmsError = PLC_WStrobe(HEADS_ACK, currentStrobeCell, id);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_ROperatorInputIsNeeded(ref List<M155InputIsNeededModel> value)
|
|
{
|
|
byte val = 0;
|
|
CmsError cmsError = MEM_RWByte(R, 0, M155_INPUT_NEEDED.MemType, M155_INPUT_NEEDED.Address, 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] bits = ByteToBits(val);
|
|
|
|
uint processId = 1;
|
|
foreach(bool bit in bits)
|
|
{
|
|
if (bit)
|
|
{
|
|
string actualLine = "";
|
|
// Read active program line
|
|
cmsError = PROC_ReadActiveLine(processId, ref actualLine);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
// Extract parameters
|
|
string[] parameters = ExtractM155ParametersFromNcCodeLine(actualLine);
|
|
byte i = 0;
|
|
// Populate buttons
|
|
Dictionary<byte, string> buttons = parameters.Skip(1)?.ToDictionary(x => i++, x => x);
|
|
|
|
// Create output model
|
|
value.Add(new M155InputIsNeededModel()
|
|
{
|
|
Process = processId,
|
|
IsNeeded = bit,
|
|
Message = parameters[0] ?? "",
|
|
Type = parameters.Count() > 1 ? M155_TYPE.MULTIPLE_BUTTONS : M155_TYPE.REAL, // if there aren't buttons is a simple request
|
|
Buttons = buttons
|
|
});
|
|
}
|
|
|
|
processId++;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WOperatorInputResponse(int process, double responseVal)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RMTConnectData(ref List<MtConnectDataIsNeededModel> value)
|
|
{
|
|
short nReturn = 0;
|
|
for (int i = 0; i < nLibHandle.Count(); i++)
|
|
{
|
|
// Read block number
|
|
nReturn = Focas1.cnc_rdblkcount(nLibHandle[i], out int blockNum);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
ushort length = 256;
|
|
char[] line = new char[256];
|
|
nReturn = Focas1.cnc_rdexecprog(nLibHandle[i], ref length, out short b, line);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RScadaValue(string memIndex, SCADA_MEM_TYPE memType, ref object value)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value)
|
|
{
|
|
string[] index = memIndex.Split('.');
|
|
|
|
if (index.Count() == 0)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
else if (index.Count() == 1)
|
|
{
|
|
if (memType == SCADA_MEM_TYPE.INT)
|
|
{
|
|
// READ INT
|
|
int val = 0;
|
|
CmsError cmsError = MEM_RWInteger(W, 0, MEMORY_TYPE.Demo, Convert.ToInt32(index[0]), ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
else if (memType == SCADA_MEM_TYPE.WORD)
|
|
{ // READ WORD
|
|
ushort val = 0;
|
|
CmsError cmsError = MEM_RWWord(W, 0, MEMORY_TYPE.Demo, Convert.ToInt32(index[0]), ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
else
|
|
{ // READ byte
|
|
byte val = 0;
|
|
CmsError cmsError = MEM_RWByte(W, 0, MEMORY_TYPE.Demo, Convert.ToInt32(index[0]), 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
}
|
|
else if (index.Count() == 2 && memType == SCADA_MEM_TYPE.BOOL)
|
|
{ // READ BOOL
|
|
bool val = false;
|
|
CmsError cmsError = MEM_RWBoolean(W, 0, MEMORY_TYPE.Demo, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion PLC High-level data
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region PROCESS (PATH) High-level data
|
|
|
|
// Get process part program data
|
|
public override CmsError PROC_RStatusAndData(ushort procNumber, ref ProcessDataModel processData)
|
|
{
|
|
processData.Id = procNumber;
|
|
// Read part program name
|
|
CmsError cmsError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
int readValue = 0;
|
|
// Read processes status from memory
|
|
cmsError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address + ((procNumber - 1) * 2), ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
byte[] bytes = BitConverter.GetBytes(readValue);
|
|
|
|
// Convert Byte into true/false array
|
|
BitArray bits = new BitArray(new byte[] { bytes[0] }); //1st byte -> 0 : Proccess type (AUX-WORK), 1: Process in alarm status, 2: Run, 3: Hold, 4: Read, 5: PartProgramVisible
|
|
|
|
// Get part program info visibility
|
|
processData.Visible = bits[0];
|
|
|
|
// Populate response structure
|
|
processData.Type = bits[1] ? "WORK" : "AUX";
|
|
processData.IsSelected = bits[2];
|
|
processData.IsInAlarm = bits[3];
|
|
|
|
// Choose process status
|
|
if (bytes[1] == 1)
|
|
processData.Status = "HOLD";
|
|
else
|
|
{
|
|
if (bytes[1] == 2)
|
|
processData.Status = "RUN";
|
|
else
|
|
processData.Status = "READY";
|
|
}
|
|
|
|
// Get Reps from 3nd-4th byte
|
|
processData.Reps = BitConverter.ToUInt16(bytes, 2);
|
|
|
|
return NO_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the process Alarms
|
|
public override CmsError PROC_RActiveAlarms(ushort procNumber, ref List<AlarmModel> alarms)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
alarms.Clear();
|
|
|
|
Focas1.ODBALMMSG2 Messg = new Focas1.ODBALMMSG2();
|
|
short nReturn = 0;
|
|
short count = FANUC_MAXMSGCNC;
|
|
|
|
// Get path index
|
|
short pathNumber = GetHandleIndexFromPath(procNumber);
|
|
if (pathNumber < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
// Execute the method
|
|
nReturn = Focas1.cnc_rdalmmsg2(nLibHandle[pathNumber], -1, ref count, Messg);
|
|
|
|
// Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Add Alarm in List
|
|
alarms.Clear();
|
|
if (count >= 1 && Messg.msg1.type != 15)
|
|
AddAlarmToList(Messg.msg1.alm_no, Messg.msg1.axis, Messg.msg1.alm_msg.Substring(0, Messg.msg1.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 2 && Messg.msg2.type != 15)
|
|
AddAlarmToList(Messg.msg2.alm_no, Messg.msg2.axis, Messg.msg2.alm_msg.Substring(0, Messg.msg2.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 3 && Messg.msg3.type != 15)
|
|
AddAlarmToList(Messg.msg3.alm_no, Messg.msg3.axis, Messg.msg3.alm_msg.Substring(0, Messg.msg3.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 4 && Messg.msg4.type != 15)
|
|
AddAlarmToList(Messg.msg4.alm_no, Messg.msg4.axis, Messg.msg4.alm_msg.Substring(0, Messg.msg4.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 5 && Messg.msg5.type != 15)
|
|
AddAlarmToList(Messg.msg5.alm_no, Messg.msg5.axis, Messg.msg5.alm_msg.Substring(0, Messg.msg5.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 6 && Messg.msg6.type != 15)
|
|
AddAlarmToList(Messg.msg6.alm_no, Messg.msg6.axis, Messg.msg6.alm_msg.Substring(0, Messg.msg6.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 7 && Messg.msg7.type != 15)
|
|
AddAlarmToList(Messg.msg7.alm_no, Messg.msg7.axis, Messg.msg7.alm_msg.Substring(0, Messg.msg7.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 8 && Messg.msg8.type != 15)
|
|
AddAlarmToList(Messg.msg8.alm_no, Messg.msg8.axis, Messg.msg8.alm_msg.Substring(0, Messg.msg8.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 9 && Messg.msg9.type != 15)
|
|
AddAlarmToList(Messg.msg9.alm_no, Messg.msg9.axis, Messg.msg9.alm_msg.Substring(0, Messg.msg9.msg_len), pathNumber, DateTime.Now, alarms);
|
|
if (count >= 10 && Messg.msg10.type != 15)
|
|
AddAlarmToList(Messg.msg10.alm_no, Messg.msg10.axis, Messg.msg10.alm_msg.Substring(0, Messg.msg10.msg_len), pathNumber, DateTime.Now, alarms);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get PP Lines
|
|
public override CmsError PROC_RPPLines(ushort procNumber, ref List<string> lines)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn = 0;
|
|
int linN;
|
|
ushort Lenght = 256;
|
|
short ReturnIndex = 1;
|
|
char[] Chars = new char[255];
|
|
string[] newLines;
|
|
|
|
short path = GetHandleIndexFromPath(procNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdblkcount(nLibHandle[path], out linN);
|
|
ReturnIndex = (short)linN;
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
path = GetHandleIndexFromPath(procNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdexecprog(nLibHandle[path], ref Lenght, out ReturnIndex, Chars);
|
|
newLines = new string(Chars).Replace("\0", string.Empty).Split('\n');
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//Setup the return values
|
|
lines.Clear();
|
|
foreach (string Line in newLines)
|
|
lines.Add(Line);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get Active PP Name
|
|
public override CmsError PROC_RSelectedPPName(ushort procNumber, ref string name)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn = 0;
|
|
Focas1.ODBEXEPRG partPrg = new Focas1.ODBEXEPRG();
|
|
|
|
// Get path index
|
|
short path = GetHandleIndexFromPath(procNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_exeprgname(nLibHandle[path], partPrg);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
name = new string(partPrg.name).Replace("\0", string.Empty);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the process status
|
|
public override CmsError PROC_RStatus(ushort procNumber, ref PROC_STATUS Status)
|
|
{
|
|
Focas1.ODBST statusInfo = new Focas1.ODBST();
|
|
short nReturn;
|
|
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Get path index
|
|
short path = GetHandleIndexFromPath(procNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_statinfo(nLibHandle[path], statusInfo);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Status = ConverToSTEPStatus(statusInfo);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the process Mode
|
|
public override CmsError PROC_RMode(ushort procNumber, ref PROC_MODE Mode)
|
|
{
|
|
Focas1.ODBST statusInfo = new Focas1.ODBST();
|
|
short nReturn = 0;
|
|
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Get path index
|
|
short path = GetHandleIndexFromPath(procNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_statinfo(nLibHandle[path], statusInfo);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Mode = ConverToSTEPMode(statusInfo);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PROC_RSelectedProcess(ref ushort procNumber)
|
|
{
|
|
CmsError cmsError;
|
|
bool readValue = false;
|
|
|
|
for (int i = 0; i < PROCESS_NUMBER; i++)
|
|
{
|
|
int memoryAddress = SELECTED_PROCESS.Address + i * (2);
|
|
// Read memory from plc
|
|
cmsError = MEM_RWBoolean(R, 0, SELECTED_PROCESS.MemType, memoryAddress, SELECTED_PROCESS.SubAddress, ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (readValue)
|
|
procNumber = (ushort)(i + 1);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PROC_WSelectProcess(ushort procNumber)
|
|
{
|
|
CmsError cmsError;
|
|
byte processNum = (byte)procNumber;
|
|
|
|
// Check parameter
|
|
if (processNum > PROCESS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Write process number
|
|
cmsError = MEM_RWByte(W, 0, SELECT_PROCESS.MemType, SELECT_PROCESS.Address, SELECT_PROCESS.SubAddress, ref processNum);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError PROC_ReadActiveLine(uint processId, ref string line)
|
|
{
|
|
uint lineL = 1;
|
|
uint txtL = 50;
|
|
short nReturn = Focas1.cnc_rdprogline2(nLibHandle[(int)processId - 1], 0, 1, line, ref lineL, ref txtL);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion PROCESS (PATH) High-level data
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region PROCESS-AXES (PATH) High-level data
|
|
|
|
//Get the Inrpolated position
|
|
public override CmsError AXES_RInterpPosition(ushort ProcNumber, ref Dictionary<string, double> Axes)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.ODBPOS axisFan = new Focas1.ODBPOS();
|
|
short nReturn;
|
|
short i;
|
|
short NumAxes = Focas1.MAX_AXIS;
|
|
|
|
// Get path index
|
|
short path = GetHandleIndexFromPath(ProcNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdposition(nLibHandle[path], FANUC_RELATIVEPOS, ref NumAxes, axisFan);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//If an axis goes out from Process Clear the List
|
|
if (Axes.Count > NumAxes)
|
|
Axes.Clear();
|
|
|
|
//Fill all the List
|
|
for (i = 1; i <= NumAxes; i++)
|
|
{
|
|
switch (i)
|
|
{
|
|
case 1: ReadRelativeAxisPos(axisFan.p1.rel, 1, ref Axes); break;
|
|
case 2: ReadRelativeAxisPos(axisFan.p2.rel, 2, ref Axes); break;
|
|
case 3: ReadRelativeAxisPos(axisFan.p3.rel, 3, ref Axes); break;
|
|
case 4: ReadRelativeAxisPos(axisFan.p4.rel, 4, ref Axes); break;
|
|
case 5: ReadRelativeAxisPos(axisFan.p5.rel, 5, ref Axes); break;
|
|
case 6: ReadRelativeAxisPos(axisFan.p6.rel, 6, ref Axes); break;
|
|
case 7: ReadRelativeAxisPos(axisFan.p7.rel, 7, ref Axes); break;
|
|
case 8: ReadRelativeAxisPos(axisFan.p8.rel, 8, ref Axes); break;
|
|
case 9: ReadRelativeAxisPos(axisFan.p9.rel, 9, ref Axes); break;
|
|
case 10: ReadRelativeAxisPos(axisFan.p10.rel, 10, ref Axes); break;
|
|
case 11: ReadRelativeAxisPos(axisFan.p11.rel, 11, ref Axes); break;
|
|
case 12: ReadRelativeAxisPos(axisFan.p12.rel, 12, ref Axes); break;
|
|
case 13: ReadRelativeAxisPos(axisFan.p13.rel, 13, ref Axes); break;
|
|
case 14: ReadRelativeAxisPos(axisFan.p14.rel, 14, ref Axes); break;
|
|
case 15: ReadRelativeAxisPos(axisFan.p15.rel, 15, ref Axes); break;
|
|
case 16: ReadRelativeAxisPos(axisFan.p16.rel, 16, ref Axes); break;
|
|
case 17: ReadRelativeAxisPos(axisFan.p17.rel, 17, ref Axes); break;
|
|
case 18: ReadRelativeAxisPos(axisFan.p18.rel, 18, ref Axes); break;
|
|
case 19: ReadRelativeAxisPos(axisFan.p19.rel, 19, ref Axes); break;
|
|
case 20: ReadRelativeAxisPos(axisFan.p20.rel, 20, ref Axes); break;
|
|
case 21: ReadRelativeAxisPos(axisFan.p21.rel, 21, ref Axes); break;
|
|
case 22: ReadRelativeAxisPos(axisFan.p22.rel, 22, ref Axes); break;
|
|
case 23: ReadRelativeAxisPos(axisFan.p23.rel, 23, ref Axes); break;
|
|
case 24: ReadRelativeAxisPos(axisFan.p24.rel, 24, ref Axes); break;
|
|
case 25: ReadRelativeAxisPos(axisFan.p25.rel, 25, ref Axes); break;
|
|
case 26: ReadRelativeAxisPos(axisFan.p26.rel, 26, ref Axes); break;
|
|
case 27: ReadRelativeAxisPos(axisFan.p27.rel, 27, ref Axes); break;
|
|
case 28: ReadRelativeAxisPos(axisFan.p28.rel, 28, ref Axes); break;
|
|
case 29: ReadRelativeAxisPos(axisFan.p29.rel, 29, ref Axes); break;
|
|
case 30: ReadRelativeAxisPos(axisFan.p30.rel, 30, ref Axes); break;
|
|
case 31: ReadRelativeAxisPos(axisFan.p31.rel, 31, ref Axes); break;
|
|
case 32: ReadRelativeAxisPos(axisFan.p32.rel, 32, ref Axes); break;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//Get the Machine position
|
|
public override CmsError AXES_RMachinePosition(ushort ProcNumber, ref Dictionary<string, double> Axes)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.ODBPOS axisFan = new Focas1.ODBPOS();
|
|
short nReturn;
|
|
short i;
|
|
short NumAxes = Focas1.MAX_AXIS;
|
|
|
|
// Get path index
|
|
short path = GetHandleIndexFromPath(ProcNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdposition(nLibHandle[path], FANUC_MACHINEPOS, ref NumAxes, axisFan);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//If an axis goes out from Process Clear the List
|
|
if (Axes.Count > NumAxes)
|
|
{
|
|
Axes.Clear();
|
|
}
|
|
|
|
//Fill all the List
|
|
for (i = 1; i <= NumAxes; i++)
|
|
{
|
|
switch (i)
|
|
{
|
|
case 1: ReadRelativeAxisPos(axisFan.p1.mach, 1, ref Axes); break;
|
|
case 2: ReadRelativeAxisPos(axisFan.p2.mach, 2, ref Axes); break;
|
|
case 3: ReadRelativeAxisPos(axisFan.p3.mach, 3, ref Axes); break;
|
|
case 4: ReadRelativeAxisPos(axisFan.p4.mach, 4, ref Axes); break;
|
|
case 5: ReadRelativeAxisPos(axisFan.p5.mach, 5, ref Axes); break;
|
|
case 6: ReadRelativeAxisPos(axisFan.p6.mach, 6, ref Axes); break;
|
|
case 7: ReadRelativeAxisPos(axisFan.p7.mach, 7, ref Axes); break;
|
|
case 8: ReadRelativeAxisPos(axisFan.p8.mach, 8, ref Axes); break;
|
|
case 9: ReadRelativeAxisPos(axisFan.p9.mach, 9, ref Axes); break;
|
|
case 10: ReadRelativeAxisPos(axisFan.p10.mach, 10, ref Axes); break;
|
|
case 11: ReadRelativeAxisPos(axisFan.p11.mach, 11, ref Axes); break;
|
|
case 12: ReadRelativeAxisPos(axisFan.p12.mach, 12, ref Axes); break;
|
|
case 13: ReadRelativeAxisPos(axisFan.p13.mach, 13, ref Axes); break;
|
|
case 14: ReadRelativeAxisPos(axisFan.p14.mach, 14, ref Axes); break;
|
|
case 15: ReadRelativeAxisPos(axisFan.p15.mach, 15, ref Axes); break;
|
|
case 16: ReadRelativeAxisPos(axisFan.p16.mach, 16, ref Axes); break;
|
|
case 17: ReadRelativeAxisPos(axisFan.p17.mach, 17, ref Axes); break;
|
|
case 18: ReadRelativeAxisPos(axisFan.p18.mach, 18, ref Axes); break;
|
|
case 19: ReadRelativeAxisPos(axisFan.p19.mach, 19, ref Axes); break;
|
|
case 20: ReadRelativeAxisPos(axisFan.p20.mach, 20, ref Axes); break;
|
|
case 21: ReadRelativeAxisPos(axisFan.p21.mach, 21, ref Axes); break;
|
|
case 22: ReadRelativeAxisPos(axisFan.p22.mach, 22, ref Axes); break;
|
|
case 23: ReadRelativeAxisPos(axisFan.p23.mach, 23, ref Axes); break;
|
|
case 24: ReadRelativeAxisPos(axisFan.p24.mach, 24, ref Axes); break;
|
|
case 25: ReadRelativeAxisPos(axisFan.p25.mach, 25, ref Axes); break;
|
|
case 26: ReadRelativeAxisPos(axisFan.p26.mach, 26, ref Axes); break;
|
|
case 27: ReadRelativeAxisPos(axisFan.p27.mach, 27, ref Axes); break;
|
|
case 28: ReadRelativeAxisPos(axisFan.p28.mach, 28, ref Axes); break;
|
|
case 29: ReadRelativeAxisPos(axisFan.p29.mach, 29, ref Axes); break;
|
|
case 30: ReadRelativeAxisPos(axisFan.p30.mach, 30, ref Axes); break;
|
|
case 31: ReadRelativeAxisPos(axisFan.p31.mach, 31, ref Axes); break;
|
|
case 32: ReadRelativeAxisPos(axisFan.p32.mach, 32, ref Axes); break;
|
|
}
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//Get the Distance To Go
|
|
public override CmsError AXES_RDistanceToGo(ushort ProcNumber, ref Dictionary<string, double> Axes)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.ODBPOS axisFan = new Focas1.ODBPOS();
|
|
short nReturn;
|
|
short i;
|
|
short NumAxes = Focas1.MAX_AXIS;
|
|
|
|
// Get path index
|
|
short path = GetHandleIndexFromPath(ProcNumber);
|
|
if (path < 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdposition(nLibHandle[GetHandleIndexFromPath(ProcNumber)], FANUC_DISTTOGO, ref NumAxes, axisFan);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//If an axis goes out from Process Clear the List
|
|
if (Axes.Count > NumAxes)
|
|
{
|
|
Axes.Clear();
|
|
}
|
|
|
|
//Fill all the List
|
|
for (i = 1; i <= NumAxes; i++)
|
|
{
|
|
switch (i)
|
|
{
|
|
case 1: ReadRelativeAxisPos(axisFan.p1.dist, 1, ref Axes); break;
|
|
case 2: ReadRelativeAxisPos(axisFan.p2.dist, 2, ref Axes); break;
|
|
case 3: ReadRelativeAxisPos(axisFan.p3.dist, 3, ref Axes); break;
|
|
case 4: ReadRelativeAxisPos(axisFan.p4.dist, 4, ref Axes); break;
|
|
case 5: ReadRelativeAxisPos(axisFan.p5.dist, 5, ref Axes); break;
|
|
case 6: ReadRelativeAxisPos(axisFan.p6.dist, 6, ref Axes); break;
|
|
case 7: ReadRelativeAxisPos(axisFan.p7.dist, 7, ref Axes); break;
|
|
case 8: ReadRelativeAxisPos(axisFan.p8.dist, 8, ref Axes); break;
|
|
case 9: ReadRelativeAxisPos(axisFan.p9.dist, 9, ref Axes); break;
|
|
case 10: ReadRelativeAxisPos(axisFan.p10.dist, 10, ref Axes); break;
|
|
case 11: ReadRelativeAxisPos(axisFan.p11.dist, 11, ref Axes); break;
|
|
case 12: ReadRelativeAxisPos(axisFan.p12.dist, 12, ref Axes); break;
|
|
case 13: ReadRelativeAxisPos(axisFan.p13.dist, 13, ref Axes); break;
|
|
case 14: ReadRelativeAxisPos(axisFan.p14.dist, 14, ref Axes); break;
|
|
case 15: ReadRelativeAxisPos(axisFan.p15.dist, 15, ref Axes); break;
|
|
case 16: ReadRelativeAxisPos(axisFan.p16.dist, 16, ref Axes); break;
|
|
case 17: ReadRelativeAxisPos(axisFan.p17.dist, 17, ref Axes); break;
|
|
case 18: ReadRelativeAxisPos(axisFan.p18.dist, 18, ref Axes); break;
|
|
case 19: ReadRelativeAxisPos(axisFan.p19.dist, 19, ref Axes); break;
|
|
case 20: ReadRelativeAxisPos(axisFan.p20.dist, 20, ref Axes); break;
|
|
case 21: ReadRelativeAxisPos(axisFan.p21.dist, 21, ref Axes); break;
|
|
case 22: ReadRelativeAxisPos(axisFan.p22.dist, 22, ref Axes); break;
|
|
case 23: ReadRelativeAxisPos(axisFan.p23.dist, 23, ref Axes); break;
|
|
case 24: ReadRelativeAxisPos(axisFan.p24.dist, 24, ref Axes); break;
|
|
case 25: ReadRelativeAxisPos(axisFan.p25.dist, 25, ref Axes); break;
|
|
case 26: ReadRelativeAxisPos(axisFan.p26.dist, 26, ref Axes); break;
|
|
case 27: ReadRelativeAxisPos(axisFan.p27.dist, 27, ref Axes); break;
|
|
case 28: ReadRelativeAxisPos(axisFan.p28.dist, 28, ref Axes); break;
|
|
case 29: ReadRelativeAxisPos(axisFan.p29.dist, 29, ref Axes); break;
|
|
case 30: ReadRelativeAxisPos(axisFan.p30.dist, 30, ref Axes); break;
|
|
case 31: ReadRelativeAxisPos(axisFan.p31.dist, 31, ref Axes); break;
|
|
case 32: ReadRelativeAxisPos(axisFan.p32.dist, 32, ref Axes); break;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//Get the Programmed Position
|
|
public override CmsError AXES_RProgrPosition(ushort ProcNumber, ref Dictionary<string, double> Axes)
|
|
{
|
|
//In fanuc is not implemented, so i need to build it
|
|
Dictionary<string, double> ActualMach = new Dictionary<string, double>();
|
|
Dictionary<string, double> ToGo = new Dictionary<string, double>();
|
|
KeyValuePair<string, double> val;
|
|
|
|
//Read the positions
|
|
CmsError cmsError = AXES_RMachinePosition(ProcNumber, ref ActualMach);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
cmsError = AXES_RDistanceToGo(ProcNumber, ref ToGo);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//If it has the same size
|
|
if (ActualMach.Count == ToGo.Count)
|
|
{
|
|
//If an axis goes out from Process Clear the List
|
|
if (Axes.Count > ActualMach.Count)
|
|
{
|
|
Axes.Clear();
|
|
}
|
|
|
|
foreach (KeyValuePair<string, double> axis in ActualMach)
|
|
{
|
|
val = Axes.FirstOrDefault(X => X.Key == axis.Key);
|
|
if (val.Key != null)
|
|
Axes[val.Key] = axis.Value + ToGo[val.Key];
|
|
else
|
|
Axes.Add(axis.Key, axis.Value + ToGo[axis.Key]);
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RFollowingError(ushort ProcNumber, ref Dictionary<string, double> Axes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RAxesNames(ushort process, ref List<AxisModel> axesData)
|
|
{
|
|
short numAxesRead = MAX_AXIS;
|
|
|
|
ODBEXAXISNAME sOdbExAxisName = new ODBEXAXISNAME();
|
|
// Read from NC
|
|
short nReturn = Focas1.cnc_exaxisname(nLibHandle[process - 1], 0, ref numAxesRead, sOdbExAxisName);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
// Parse data
|
|
if (numAxesRead >= 1)
|
|
axesData.Add(new AxisModel() { Id = 1, Name = sOdbExAxisName.axname1, IsSelectable = false });
|
|
if (numAxesRead >= 2)
|
|
axesData.Add(new AxisModel() { Id = 2, Name = sOdbExAxisName.axname2, IsSelectable = false });
|
|
if (numAxesRead >= 3)
|
|
axesData.Add(new AxisModel() { Id = 3, Name = sOdbExAxisName.axname3, IsSelectable = false });
|
|
if (numAxesRead >= 4)
|
|
axesData.Add(new AxisModel() { Id = 4, Name = sOdbExAxisName.axname4, IsSelectable = false });
|
|
if (numAxesRead >= 5)
|
|
axesData.Add(new AxisModel() { Id = 5, Name = sOdbExAxisName.axname5, IsSelectable = false });
|
|
if (numAxesRead >= 6)
|
|
axesData.Add(new AxisModel() { Id = 6, Name = sOdbExAxisName.axname6, IsSelectable = false });
|
|
if (numAxesRead >= 7)
|
|
axesData.Add(new AxisModel() { Id = 7, Name = sOdbExAxisName.axname7, IsSelectable = false });
|
|
if (numAxesRead >= 8)
|
|
axesData.Add(new AxisModel() { Id = 8, Name = sOdbExAxisName.axname8, IsSelectable = false });
|
|
if (numAxesRead >= 9)
|
|
axesData.Add(new AxisModel() { Id = 9, Name = sOdbExAxisName.axname9, IsSelectable = false });
|
|
if (numAxesRead >= 10)
|
|
axesData.Add(new AxisModel() { Id = 10, Name = sOdbExAxisName.axname10, IsSelectable = false });
|
|
if (numAxesRead >= 11)
|
|
axesData.Add(new AxisModel() { Id = 11, Name = sOdbExAxisName.axname11, IsSelectable = false });
|
|
if (numAxesRead >= 12)
|
|
axesData.Add(new AxisModel() { Id = 12, Name = sOdbExAxisName.axname12, IsSelectable = false });
|
|
if (numAxesRead >= 13)
|
|
axesData.Add(new AxisModel() { Id = 13, Name = sOdbExAxisName.axname13, IsSelectable = false });
|
|
if (numAxesRead >= 14)
|
|
axesData.Add(new AxisModel() { Id = 14, Name = sOdbExAxisName.axname14, IsSelectable = false });
|
|
if (numAxesRead >= 15)
|
|
axesData.Add(new AxisModel() { Id = 15, Name = sOdbExAxisName.axname15, IsSelectable = false });
|
|
if (numAxesRead >= 16)
|
|
axesData.Add(new AxisModel() { Id = 16, Name = sOdbExAxisName.axname16, IsSelectable = false });
|
|
if (numAxesRead >= 17)
|
|
axesData.Add(new AxisModel() { Id = 17, Name = sOdbExAxisName.axname17, IsSelectable = false });
|
|
if (numAxesRead >= 18)
|
|
axesData.Add(new AxisModel() { Id = 18, Name = sOdbExAxisName.axname18, IsSelectable = false });
|
|
if (numAxesRead >= 19)
|
|
axesData.Add(new AxisModel() { Id = 19, Name = sOdbExAxisName.axname19, IsSelectable = false });
|
|
if (numAxesRead >= 20)
|
|
axesData.Add(new AxisModel() { Id = 20, Name = sOdbExAxisName.axname20, IsSelectable = false });
|
|
if (numAxesRead >= 21)
|
|
axesData.Add(new AxisModel() { Id = 21, Name = sOdbExAxisName.axname21, IsSelectable = false });
|
|
if (numAxesRead >= 22)
|
|
axesData.Add(new AxisModel() { Id = 22, Name = sOdbExAxisName.axname22, IsSelectable = false });
|
|
if (numAxesRead >= 23)
|
|
axesData.Add(new AxisModel() { Id = 23, Name = sOdbExAxisName.axname23, IsSelectable = false });
|
|
if (numAxesRead >= 24)
|
|
axesData.Add(new AxisModel() { Id = 24, Name = sOdbExAxisName.axname24, IsSelectable = false });
|
|
if (numAxesRead >= 25)
|
|
axesData.Add(new AxisModel() { Id = 25, Name = sOdbExAxisName.axname25, IsSelectable = false });
|
|
if (numAxesRead >= 26)
|
|
axesData.Add(new AxisModel() { Id = 26, Name = sOdbExAxisName.axname26, IsSelectable = false });
|
|
if (numAxesRead >= 27)
|
|
axesData.Add(new AxisModel() { Id = 27, Name = sOdbExAxisName.axname27, IsSelectable = false });
|
|
if (numAxesRead >= 28)
|
|
axesData.Add(new AxisModel() { Id = 28, Name = sOdbExAxisName.axname28, IsSelectable = false });
|
|
if (numAxesRead >= 29)
|
|
axesData.Add(new AxisModel() { Id = 29, Name = sOdbExAxisName.axname29, IsSelectable = false });
|
|
if (numAxesRead >= 30)
|
|
axesData.Add(new AxisModel() { Id = 30, Name = sOdbExAxisName.axname30, IsSelectable = false });
|
|
if (numAxesRead >= 31)
|
|
axesData.Add(new AxisModel() { Id = 31, Name = sOdbExAxisName.axname31, IsSelectable = false });
|
|
if (numAxesRead >= 32)
|
|
axesData.Add(new AxisModel() { Id = 32, Name = sOdbExAxisName.axname32, IsSelectable = false });
|
|
|
|
axesData = axesData.Where(x => x.Name != "\f").ToList();
|
|
|
|
// Get from PLC which axis can be selected
|
|
List<byte> ids = new List<byte>();
|
|
CmsError cmsError = MEM_RWByteList(R, 0, AXES_BUTTON_VISIBLE.MemType, AXES_BUTTON_VISIBLE.Address, 0, AXES_BUTTON_VISIBLE.Size, ref ids);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Parse the data readed from PLC
|
|
foreach (byte id in ids)
|
|
{
|
|
if (id != 0)
|
|
{
|
|
// If axis exists, set it as selectable
|
|
var tmpAxis = axesData.Where(x => x.Id == id).FirstOrDefault();
|
|
if (tmpAxis != null)
|
|
tmpAxis.IsSelectable = true;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RSelectedAxis(ref byte axisId)
|
|
{
|
|
// Read byte from memory
|
|
CmsError cmsError = MEM_RWByte(R, 0, SELECTED_AXIS.MemType, SELECTED_AXIS.Address, SELECTED_AXIS.SubAddress, ref axisId);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_WSelectAxis(byte axisId)
|
|
{
|
|
// Write new axis id to memory
|
|
CmsError cmsError = MEM_RWByte(W, 0, SELECT_AXIS.MemType, SELECT_AXIS.Address, SELECT_AXIS.SubAddress, ref axisId);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion PROCESS-AXES (PATH) High-level data
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region NC Low-level function: single valiable in memory
|
|
|
|
// Read-Write a Boolean-Value inside the NC.
|
|
public override CmsError MEM_RWBoolean(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemBit, ref bool Value)
|
|
{
|
|
//Check if the Bit Number is Correct
|
|
CmsError cmsError = CheckBitRange(MemBit);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
byte ReadValue = 0;
|
|
byte pow = (byte)Math.Pow(2, MemBit);
|
|
|
|
//Read the Byte where is the bit
|
|
cmsError = MEM_RWByte(R, Process, MemType, MemIndex, 0, ref ReadValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//If i have to read -> Read the Bit
|
|
if (bWrite == R)
|
|
{
|
|
Value = (ReadValue & pow) == pow;
|
|
}
|
|
//If i have to Write -> Write the Bit
|
|
else
|
|
{
|
|
if (Value)
|
|
ReadValue = (byte)(ReadValue | (1 << MemBit));
|
|
else
|
|
ReadValue = (byte)(ReadValue & ~(1 << MemBit));
|
|
|
|
cmsError = MEM_RWByte(W, Process, MemType, MemIndex, 0, ref ReadValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Read-Write a Byte-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWByte(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemByte, ref byte Value)
|
|
{
|
|
List<byte> Values = new List<byte>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError cmsError = MEM_RWByteList(bWrite, Process, MemType, MemIndex, 0, 1, ref Values);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Value = Values.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a Int-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWInteger(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref int Value)
|
|
{
|
|
List<int> ListValue = new List<int>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError cmsError = MEM_RWIntegerList(bWrite, Process, MemType, MemIndex, 1, ref ListValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref uint Value)
|
|
{
|
|
List<uint> ListValue = new List<uint>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError cmsError = MEM_RWDWordList(bWrite, Process, MemType, MemIndex, 1, ref ListValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a Short-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref short Value)
|
|
{
|
|
List<short> ListValue = new List<short>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError cmsError = MEM_RWShortList(bWrite, Process, MemType, MemIndex, 1, ref ListValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref ushort Value)
|
|
{
|
|
List<ushort> ListValue = new List<ushort>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError cmsError = MEM_RWWordList(bWrite, Process, MemType, MemIndex, 1, ref ListValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
// Siemens Version of Memory-Access Methods
|
|
|
|
public override CmsError MEM_RWBoolean(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemBit, ref bool Value)
|
|
{
|
|
return MEM_RWBoolean(bWrite, Process, MemType, MemIndex, MemBit, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWByte(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByte, ref byte Value)
|
|
{
|
|
return MEM_RWByte(bWrite, Process, MemType, MemIndex, MemByte, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref ushort Value)
|
|
{
|
|
return MEM_RWWord(bWrite, Process, MemType, MemIndex, MemIndex, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref short Value)
|
|
{
|
|
return MEM_RWShort(bWrite, Process, MemType, MemIndex, MemIndex, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref uint Value)
|
|
{
|
|
return MEM_RWDWord(bWrite, Process, MemType, MemIndex, MemIndex, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWInteger(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref int Value)
|
|
{
|
|
return MEM_RWInteger(bWrite, Process, MemType, MemIndex, MemIndex, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByteStart, int Number, ref List<byte> Value)
|
|
{
|
|
return MEM_RWByteList(bWrite, Process, MemType, MemIndex, MemByteStart, Number, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<ushort> Value)
|
|
{
|
|
return MEM_RWWordList(bWrite, Process, MemType, MemIndex, Number, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<short> Value)
|
|
{
|
|
return MEM_RWShortList(bWrite, Process, MemType, MemIndex, Number, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<uint> Value)
|
|
{
|
|
return MEM_RWDWordList(bWrite, Process, MemType, MemIndex, Number, ref Value);
|
|
}
|
|
|
|
public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<int> Value)
|
|
{
|
|
return MEM_RWIntegerList(bWrite, Process, MemType, MemIndex, Number, ref Value);
|
|
}
|
|
|
|
#endregion NC Low-level function: single valiable in memory
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region NC Low-level function: variables List in memory
|
|
|
|
// Read-Write a Byte-Value-List inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemByteStart, int Number, ref List<byte> Value)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Check if the Memory area is corrected
|
|
cmsError = CheckMemoryArea(MemType.ToString());
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// The maximum number of variables read/writed at the same time is 5
|
|
// I have to iterate it
|
|
Focas1.IODBPMC0 Io = new Focas1.IODBPMC0();
|
|
Io.cdata = new byte[FANUC_MAXNVAR];
|
|
short nReturn;
|
|
int ActualNumber;
|
|
int FanucNumber;
|
|
int Iterat;
|
|
int LastNumber;
|
|
int ActualStartIndex;
|
|
int ActualEndIndex;
|
|
int j = 0;
|
|
int k = 0;
|
|
|
|
// Setup the 'Value' variable
|
|
if (bWrite)
|
|
Number = Value.Count();
|
|
else
|
|
Value.Clear();
|
|
|
|
// Setup the iterations
|
|
LastNumber = (Number % FANUC_MAXNVAR);
|
|
Iterat = Number / FANUC_MAXNVAR;
|
|
|
|
// Iterates
|
|
for (int i = 0; i <= Iterat; i++)
|
|
{
|
|
// Set the variables-index to iterate
|
|
ActualStartIndex = MemIndex + (i * FANUC_MAXNVAR);
|
|
if (i == Iterat && LastNumber == 0)
|
|
break;
|
|
else if (i == Iterat)
|
|
ActualEndIndex = ActualStartIndex + LastNumber - 1;
|
|
else
|
|
ActualEndIndex = ActualStartIndex + FANUC_MAXNVAR - 1;
|
|
|
|
// Set the variables-numbers to iterate
|
|
ActualNumber = (ActualEndIndex - ActualStartIndex + 1);
|
|
// Set the variables-number Fanuc
|
|
FanucNumber = ActualNumber + 8;
|
|
|
|
// Set the IODBPMC if you have to write
|
|
if (bWrite)
|
|
{
|
|
Io.datano_s = (short)ActualStartIndex;
|
|
Io.datano_e = (short)ActualEndIndex;
|
|
Io.type_a = (short)MemType;
|
|
Io.type_d = (short)FANUC_DType.BYTE;
|
|
//Fill the cdata
|
|
j = (i * FANUC_MAXNVAR);
|
|
for (k = 0; k < ActualNumber; k++)
|
|
Io.cdata[k] = Value[j + k];
|
|
}
|
|
|
|
// Execute the method
|
|
if (!bWrite)
|
|
nReturn = Focas1.pmc_rdpmcrng(nLibHandle[0], (short)MemType, (short)FANUC_DType.BYTE, (ushort)ActualStartIndex, (ushort)ActualEndIndex, (ushort)FanucNumber, Io);
|
|
else
|
|
nReturn = Focas1.pmc_wrpmcrng(nLibHandle[0], (ushort)FanucNumber, Io);
|
|
|
|
// Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Else add the variables in the List (is is a read-statement)
|
|
else if (!bWrite)
|
|
Value.AddRange(Io.cdata.Take(ActualNumber).ToArray());
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a Int-Value-List inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<int> Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
//The maximum number of variables read/writed at the same time is 5
|
|
//I have to iterate it
|
|
Focas1.IODBPMC2 Io = new Focas1.IODBPMC2
|
|
{
|
|
ldata = new int[FANUC_MAXNVAR]
|
|
};
|
|
|
|
short nReturn;
|
|
int ActualNumber;
|
|
int FanucNumber;
|
|
int Iterat;
|
|
int LastNumber;
|
|
int ActualStartIndex;
|
|
int ActualEndIndex;
|
|
int j = 0;
|
|
int k = 0;
|
|
|
|
//Check if the Memory area is corrected
|
|
cmsError = CheckMemoryArea(MemType.ToString());
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//Setup the 'Value' variable
|
|
if (bWrite)
|
|
Number = Value.Count();
|
|
else
|
|
Value.Clear();
|
|
|
|
//Setup the iterations
|
|
LastNumber = (Number % FANUC_MAXNVAR);
|
|
Iterat = Number / FANUC_MAXNVAR;
|
|
|
|
//Iterates
|
|
for (int i = 0; i <= Iterat; i++)
|
|
{
|
|
//Set the variables-index to iterate
|
|
ActualStartIndex = MemIndex + (i * FANUC_MAXNVAR * 4);
|
|
if (i == Iterat && LastNumber == 0)
|
|
break;
|
|
else if (i == Iterat)
|
|
ActualEndIndex = ActualStartIndex + (LastNumber * 4) - 1;
|
|
else
|
|
ActualEndIndex = ActualStartIndex + (FANUC_MAXNVAR * 4) - 1;
|
|
|
|
//Set the variables-numbers to iterate
|
|
ActualNumber = (ActualEndIndex - ActualStartIndex + 1) / 4;
|
|
//Set the variables-number Fanuc
|
|
FanucNumber = (ActualNumber * 4) + 8;
|
|
|
|
//Set the IODBPMC if you have to write
|
|
if (bWrite)
|
|
{
|
|
Io.datano_s = (short)ActualStartIndex;
|
|
Io.datano_e = (short)ActualEndIndex;
|
|
Io.type_a = (short)MemType;
|
|
Io.type_d = (short)FANUC_DType.LONG;
|
|
//Fill the cdata
|
|
j = (i * FANUC_MAXNVAR);
|
|
for (k = 0; k < ActualNumber; k++)
|
|
Io.ldata[k] = Value[j + k];
|
|
}
|
|
|
|
//Execute the method
|
|
if (!bWrite)
|
|
nReturn = Focas1.pmc_rdpmcrng(nLibHandle[0], (short)MemType, (short)FANUC_DType.LONG, (ushort)ActualStartIndex, (ushort)ActualEndIndex, (ushort)FanucNumber, Io);
|
|
else
|
|
nReturn = Focas1.pmc_wrpmcrng(nLibHandle[0], (ushort)FanucNumber, Io);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//Else add the variables in the List (is is a read-statement)
|
|
else if (!bWrite)
|
|
Value.AddRange(Io.ldata.Take(ActualNumber).ToArray());
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a DWord-Value-List inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<uint> Values)
|
|
{
|
|
List<int> WordValues = new List<int>();
|
|
|
|
//If i have to write convert the INT list into (2x) WORD
|
|
if (bWrite)
|
|
WordValues = Values.Select(i => (int)i).ToList();
|
|
|
|
//Exetute the function
|
|
CmsError cmsError = MEM_RWIntegerList(bWrite, Process, MemType, MemIndex, Number, ref WordValues);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//If i have to read, convert the WORD list into INT
|
|
if (!bWrite)
|
|
Values = WordValues.Select(i => (uint)i).ToList();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a Short-Value-List inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<short> Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//Check if the Memory area is corrected
|
|
cmsError = CheckMemoryArea(MemType.ToString());
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//The maximum number of variables read/writed at the same time is 5
|
|
//I have to iterate it
|
|
Focas1.IODBPMC1 Io = new Focas1.IODBPMC1
|
|
{
|
|
idata = new short[FANUC_MAXNVAR]
|
|
};
|
|
short nReturn;
|
|
int ActualNumber;
|
|
int FanucNumber;
|
|
int Iterat;
|
|
int LastNumber;
|
|
int ActualStartIndex;
|
|
int ActualEndIndex;
|
|
int j = 0;
|
|
int k = 0;
|
|
|
|
//Setup the 'Value' variable
|
|
if (bWrite)
|
|
Number = Value.Count();
|
|
else
|
|
Value.Clear();
|
|
|
|
//Setup the iterations
|
|
LastNumber = (Number % FANUC_MAXNVAR);
|
|
Iterat = Number / FANUC_MAXNVAR;
|
|
|
|
//Iterates
|
|
for (int i = 0; i <= Iterat; i++)
|
|
{
|
|
//Set the variables-index to iterate
|
|
ActualStartIndex = MemIndex + (i * FANUC_MAXNVAR * 2);
|
|
if (i == Iterat && LastNumber == 0)
|
|
break;
|
|
else if (i == Iterat)
|
|
ActualEndIndex = ActualStartIndex + (LastNumber * 2) - 1;
|
|
else
|
|
ActualEndIndex = ActualStartIndex + (FANUC_MAXNVAR * 2) - 1;
|
|
|
|
//Set the variables-numbers to iterate
|
|
ActualNumber = (ActualEndIndex - ActualStartIndex + 1) / 2;
|
|
//Set the variables-number Fanuc
|
|
FanucNumber = (ActualNumber * 2) + 8;
|
|
|
|
//Set the IODBPMC if you have to write
|
|
if (bWrite)
|
|
{
|
|
Io.datano_s = (short)ActualStartIndex;
|
|
Io.datano_e = (short)ActualEndIndex;
|
|
Io.type_a = (short)MemType;
|
|
Io.type_d = (short)FANUC_DType.WORD;
|
|
//Fill the cdata
|
|
j = (i * FANUC_MAXNVAR);
|
|
for (k = 0; k < ActualNumber; k++)
|
|
Io.idata[k] = Value[j + k];
|
|
}
|
|
|
|
//Execute the method
|
|
if (!bWrite)
|
|
nReturn = Focas1.pmc_rdpmcrng(nLibHandle[0], (short)MemType, (short)FANUC_DType.WORD, (ushort)ActualStartIndex, (ushort)ActualEndIndex, (ushort)FanucNumber, Io);
|
|
else
|
|
nReturn = Focas1.pmc_wrpmcrng(nLibHandle[0], (ushort)FanucNumber, Io);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
//Else add the variables in the List (is is a read-statement)
|
|
else if (!bWrite)
|
|
Value.AddRange(Io.idata.Take(ActualNumber).ToArray());
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Write a Word-Value-List inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<ushort> Values)
|
|
{
|
|
List<short> WordValues = new List<short>();
|
|
|
|
//If i have to write convert the INT list into (2x) WORD
|
|
if (bWrite)
|
|
WordValues = Values.Select(i => (short)i).ToList();
|
|
|
|
//Exetute the function
|
|
CmsError cmsError = MEM_RWShortList(bWrite, Process, MemType, MemIndex, Number, ref WordValues);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//If i have to read, convert the WORD list into INT
|
|
if (!bWrite)
|
|
Values = WordValues.Select(i => (ushort)i).ToList();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion NC Low-level function: variables List in memory
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region NC Low-level function: Parameters
|
|
|
|
// Get NC Bit Parameter
|
|
public override CmsError NC_RParam(short Index, short Bit, ref bool Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.IODBPSD_1 outpar = new Focas1.IODBPSD_1();
|
|
short nReturn;
|
|
short axes_num = 0;
|
|
short size = 5;
|
|
byte mask = (byte)Math.Pow(2, Bit);
|
|
|
|
//Check if the Bit Number is Correct
|
|
cmsError = CheckBitRange(Bit);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdparam(nLibHandle[0], Index, axes_num, size, outpar);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Value = ((outpar.cdata & mask) == mask) ? true : false;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get NC Byte Parameter
|
|
public override CmsError NC_RParam(short Index, ref byte Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.IODBPSD_1 outpar = new Focas1.IODBPSD_1();
|
|
short nReturn;
|
|
short axes_num = 0;
|
|
short size = 5;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdparam(nLibHandle[0], Index, axes_num, size, outpar);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Value = outpar.cdata;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get NC Word Parameter
|
|
public override CmsError NC_RParam(short Index, ref short Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.IODBPSD_1 outpar = new Focas1.IODBPSD_1();
|
|
short nReturn;
|
|
short axes_num = 0;
|
|
short size = 6;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdparam(nLibHandle[0], Index, axes_num, size, outpar);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Value = outpar.idata;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get NC DWord Parameter
|
|
public override CmsError NC_RParam(short Index, ref int Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.IODBPSD_1 outpar = new Focas1.IODBPSD_1();
|
|
short nReturn;
|
|
short axes_num = 0;
|
|
short size = 8;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdparam(nLibHandle[0], Index, axes_num, size, outpar);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Value = outpar.ldata;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get NC Real Parameter
|
|
public override CmsError NC_RParam(short Index, ref double Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Focas1.IODBPSD_2 outpar = new Focas1.IODBPSD_2();
|
|
short nReturn;
|
|
short axes_num = 0;
|
|
short size = 12;
|
|
double Divider = 1;
|
|
|
|
//Execute the method
|
|
nReturn = Focas1.cnc_rdparam(nLibHandle[0], Index, axes_num, size, outpar);
|
|
|
|
//Throw Exception if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Divider = Math.Pow(10, outpar.rdata.dec_val);
|
|
|
|
Value = outpar.rdata.prm_val / Divider;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion NC Low-level function: Parameters
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region File Management
|
|
|
|
public override CmsError FILES_RGetFileList(string path, ref List<PreviewFileModel> files)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
ODBPDFDRV baseDir = new ODBPDFDRV();
|
|
short nReturn = cnc_rdpdf_drive(nLibHandle[0], baseDir);
|
|
|
|
path = "//" + baseDir.drive1 + "/USER/PATH1/";
|
|
|
|
ODBPDFNFIL dataNum = new ODBPDFNFIL();
|
|
nReturn = Focas1.cnc_rdpdf_subdirn(nLibHandle[0], path, dataNum);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
IDBPDFSDIR currDirInput = new IDBPDFSDIR();
|
|
ODBPDFSDIR currDirOutData = new ODBPDFSDIR();
|
|
|
|
short maxDir = 1;
|
|
|
|
// Check if there are directories
|
|
if (dataNum.dir_num > 0)
|
|
{
|
|
// Setup input data
|
|
currDirInput.dummy = 0;
|
|
currDirInput.path = path;
|
|
|
|
for (short i = 0; i < dataNum.dir_num; i++)
|
|
{
|
|
// Update index
|
|
currDirInput.req_num = i;
|
|
// Read directory data
|
|
nReturn = cnc_rdpdf_subdir(nLibHandle[0], ref maxDir, currDirInput, currDirOutData);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Add to list read data
|
|
files.Add(new PreviewFileModel()
|
|
{
|
|
AbsolutePath = path + currDirOutData.d_f,
|
|
IsDirectory = true,
|
|
Name = currDirOutData.d_f,
|
|
Path = path
|
|
});
|
|
}
|
|
}
|
|
|
|
// Check if there are files
|
|
if (dataNum.file_num > 0)
|
|
{
|
|
IDBPDFADIR funcInput = new IDBPDFADIR();
|
|
ODBPDFADIR fileData = new ODBPDFADIR();
|
|
|
|
// Setup input data
|
|
funcInput.path = path;
|
|
funcInput.type = 1;
|
|
funcInput.size_kind = 1;
|
|
funcInput.dummy = 0;
|
|
|
|
for (short i = 0; i < dataNum.file_num; i++)
|
|
{
|
|
funcInput.req_num = i; // Update file index
|
|
// Read file data
|
|
nReturn = Focas1.cnc_rdpdf_alldir(nLibHandle[0], ref maxDir, funcInput, fileData);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Add to list read data
|
|
files.Add(new PreviewFileModel()
|
|
{
|
|
AbsolutePath = (path + fileData.d_f).Replace('/', '\\'),
|
|
IsDirectory = false,
|
|
Name = fileData.d_f,
|
|
Path = path.Replace('/', '\\')
|
|
});
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RGetFileInfo(string path, ref InfoFile fileInfo)
|
|
{
|
|
string partProgramContent = "";
|
|
// Read NC part program content
|
|
CmsError cmsError = ReadPartProgramContent(path, ref partProgramContent);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Add to list read data
|
|
fileInfo = new InfoFile()
|
|
{
|
|
AbsolutePath = path,
|
|
Name = Path.GetFileName(path),
|
|
Content = partProgramContent.Split('\n').ToList()
|
|
};
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WSetActiveProgram(int processId, string filePath, ref ActiveProgramDataModel data)
|
|
{
|
|
// Check if the NC is connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
if (filePath.StartsWith("//CNC_MEM"))
|
|
{
|
|
// Select main data
|
|
short nReturn = Focas1.cnc_pdf_slctmain(nLibHandle[processId - 1], filePath);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
}
|
|
else
|
|
{
|
|
// Populate string template with parameters
|
|
string fileContent = string.Format(M198_FILE_CONTENT, processId, Path.GetFileName(filePath));
|
|
string tmpM198FilePath = string.Format(NC_SUPPORT_FILE_PATH + M198_FILE_NAME, processId);
|
|
|
|
// Create new file
|
|
cmsError = WritePPInCmsFolder(NC_SUPPORT_FILE_PATH, fileContent);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Select main data
|
|
short nReturn = Focas1.cnc_pdf_slctmain(nLibHandle[processId - 1], tmpM198FilePath);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RActiveProgramData(int processId, ref ActiveProgramDataModel data)
|
|
{
|
|
// Check if the NC is connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
char[] filePath = new char[240];
|
|
// Read main program data
|
|
short nReturn = Focas1.cnc_pdf_rdmain(nLibHandle[processId - 1], filePath);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Clean the read path
|
|
string path = new string(filePath).TrimEnd('\0');
|
|
|
|
// If program is CMS blank then simulates that there aren't programs
|
|
if (path == BLANK_PART_PROGRAM_PATH)
|
|
return NO_ERROR;
|
|
|
|
ushort length = 200;
|
|
char[] text = new char[201]; // TODO TEST
|
|
nReturn = Focas1.cnc_rdexecprog(nLibHandle[processId - 1], ref length, out short block, text);
|
|
|
|
string lines = new string(text.Take(length).ToArray());
|
|
|
|
data = new ActiveProgramDataModel()
|
|
{
|
|
Path = path,
|
|
IsoLines = lines.Split('\n').ToList(),
|
|
TimeLeft = new DateTime()
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WDeactivateProgram(int processId)
|
|
{
|
|
// Check if the NC is connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
// Select main data
|
|
short nReturn = Focas1.cnc_pdf_slctmain(nLibHandle[processId - 1], BLANK_PART_PROGRAM_PATH);
|
|
if (nReturn != 0)
|
|
{
|
|
// Check error type
|
|
Focas1.ODBERR errorDetails = new Focas1.ODBERR();
|
|
nReturn = Focas1.cnc_getdtailerr(nLibHandle[0], errorDetails);
|
|
|
|
// If file not exist error is equal to 2
|
|
if (errorDetails.err_no == 2)
|
|
{
|
|
// Create standard file
|
|
cmsError = WritePPInCmsFolder(NC_SUPPORT_FILE_PATH, "%\n<BLANK>\n%");
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
// Deactivate again
|
|
return FILES_WDeactivateProgram(processId);
|
|
}
|
|
else
|
|
return GetNcError(nReturn);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_UploadPartProgram(string localPath, string name, ref string newFilePath)
|
|
{
|
|
File.Copy(localPath + name, PART_PRG_PATH + name, true);
|
|
|
|
newFilePath = PART_PRG_PATH + name;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RProgramToFile(string partProgramPath, FileStream localFile)
|
|
{
|
|
string partProgramContent = "";
|
|
|
|
// Read NC part program content
|
|
CmsError cmsError = ReadPartProgramContent(partProgramPath, ref partProgramContent);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
// Write content into local file
|
|
Nc_Utils.WriteLocalFile(partProgramContent, ref localFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return CmsError.InternalError(ex.Message);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WProgramFromFile(string partProgramPath, FileStream localFile)
|
|
{
|
|
string partProgramContent = "";
|
|
|
|
try
|
|
{
|
|
// Read local file content
|
|
partProgramContent = Nc_Utils.ReadLocalFile(localFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return CmsError.InternalError(ex.Message);
|
|
}
|
|
|
|
return WritePartProgramContent(partProgramPath, partProgramContent);
|
|
}
|
|
|
|
public override CmsError FILES_CopyProgram(string partProgramPath, string newPartProgramPath, bool failIfExist)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn;
|
|
|
|
// If the 2 path are the same
|
|
if (partProgramPath == newPartProgramPath)
|
|
return GetNcError(5); // TODO FIX
|
|
|
|
if (failIfExist)
|
|
{
|
|
// Copy Nc part program to the new path
|
|
nReturn = Focas1.cnc_pdf_copy(nLibHandle[0], partProgramPath, newPartProgramPath);
|
|
|
|
//Throw Exception if there's an error
|
|
ErrorHandler(nReturn);
|
|
}
|
|
else
|
|
{
|
|
// Try a copy and if error is 4 delete file and retry
|
|
// Find a function to check if file exist, delete and copy.
|
|
// Read and put file
|
|
// TODO
|
|
//
|
|
nReturn = Focas1.cnc_pdf_copy(nLibHandle[0], partProgramPath, newPartProgramPath);
|
|
|
|
if (nReturn == 5)
|
|
{
|
|
Focas1.ODBERR errorDetails = new Focas1.ODBERR();
|
|
Focas1.cnc_getdtailerr(nLibHandle[0], errorDetails);
|
|
|
|
if (errorDetails.err_no == 4)
|
|
{
|
|
FILES_DeleteProgram(newPartProgramPath, "");
|
|
|
|
nReturn = Focas1.cnc_pdf_copy(nLibHandle[0], partProgramPath, newPartProgramPath);
|
|
|
|
ErrorHandler(nReturn);
|
|
}
|
|
}
|
|
else if (nReturn != 0)
|
|
{
|
|
return GetNcError(nReturn);
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_DeleteProgram(string partProgramPath, string partProgramName)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn;
|
|
|
|
nReturn = Focas1.cnc_pdf_del(nLibHandle[0], partProgramPath + partProgramName);
|
|
|
|
ErrorHandler(nReturn);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RQueueData(ref List<QueueStatusModel> statusList)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RQueueDataByProcess(ref QueueStatusModel status, int processId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WStartQueue()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WStopQueue()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// QUEUE
|
|
public override CmsError FILES_WLoadNextPartProgram(string localPath, string ncFileName)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// JOB
|
|
public override CmsError FILES_WUploadJobFilesAndActivate(int processId, string jobExtractedPath, string fileToActivate)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RGetProgramType(ref PROGRAM_TYPE_ENUM programType)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion File Management
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region Siemens Tools Management
|
|
|
|
public override CmsError TOOLS_RConfiguration(ref ToolTableConfiguration config)
|
|
{
|
|
// Set limits
|
|
config.MaxTools = NC_MAX_TOOL_NUMER;
|
|
config.MaxEdgesPerTools = NC_MAX_EDGES_PER_TOOL;
|
|
config.MaxToolsPerFamily = NC_MAX_TOOLS_PER_FAMILY;
|
|
config.MaxMultitools = NC_MAX_MULTITOOLS_NUMBER;
|
|
config.MaxToolsPerMultitools = NC_MAX_TOOLS_PER_MULTITOOL;
|
|
|
|
// Set options
|
|
//config.MultitoolOptionActive = MULTITOOL_OPTION_ACTIVE;
|
|
//config.FamilyOptionActive = true;
|
|
//config.MagPositionOptionActive = true;
|
|
|
|
// Set fields configurations
|
|
config.ToolsConfiguration = NcToolFieldsConfig;
|
|
config.FamiliesConfiguration = NcFamilyFieldsConfig;
|
|
config.ShanksConfiguration = NcShankFieldsConfig;
|
|
config.MagazinePosConfiguration = NcMagazinePosFieldsConfig;
|
|
config.EdgesConfiguration = NcOffsetFieldsConfiguration;
|
|
config.MagPositionOptionActive = true;
|
|
config.MaxOffsets = 10;
|
|
|
|
// Setup magazine list
|
|
List<NcMagazineConfigModel> conf = new List<NcMagazineConfigModel>();
|
|
CmsError cmsError = TOOLS_RMagazineConfig(ref conf);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Get magazine status
|
|
Dictionary<int, bool> magazineStatus = new Dictionary<int, bool>();
|
|
cmsError = TOOLS_RMagazineStatus(ref magazineStatus);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
config.Magazines = conf.Select(x => new SiemensMagazineConfigModel()
|
|
{
|
|
Id = x.Id,
|
|
Type = ConvertToSiemensMagazineType(x.Type),
|
|
Name = x.Id.ToString(),
|
|
LoadingIsActive = true,// magazineStatus[x.Id],
|
|
MaxPositions = x.MaxPositions
|
|
}).ToList();
|
|
|
|
config.EdgesConfiguration.EdgesAdditionalParamsConfiguration = new Dictionary<int, List<string>>();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RToolsData(ref List<SiemensToolModel> toolTable)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RShanksData(ref List<ShankModel> shanksData)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RFamilyData(ref List<FamilyModel> families)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazinePositions(ref List<PositionModel> positions)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAddTool(ref SiemensToolModel tool)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAddFamily(ref FamilyModel family)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAddShank(ref ShankModel shank)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateFamilyData(string oldName, string newName)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdatePosition(PositionModel position)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateTool(ref SiemensToolModel tool)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteTool(int id)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteShank(int id)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteFamily(string name)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteEdge(int toolId, int edgeId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAddEdge(int toolId, ref EdgeModel edge)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateEdge(int toolId, ref EdgeModel newEdge)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateShank(ref ShankModel shank)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMountedTools(int magazineId, ref List<MountedToolModel> magazinePos)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RAvailableTools(ref List<ShankModel> multiTools, ref List<SiemensToolModel> tools)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WLoadToolInMagazine(int magazine, NewToolInMagazineModel newMagazineTool, ref MountedToolModel newMountedTool)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUnloadToolFromMagazine(int magazineId, int positionId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WLoadToolIntoShank(int shankId, int positionId, int toolId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUnloadToolFromShank(int shankId, int positionId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction)
|
|
{
|
|
byte actionId = 0;
|
|
CmsError cmsError = MEM_RWByte(R, 0, MAGAZINE_ACTION.MemType, MAGAZINE_ACTION.Address, 0, ref actionId);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (actionId != 0)
|
|
{
|
|
// Read action data
|
|
List<ushort> wordList = new List<ushort>();
|
|
cmsError = MEM_RWWordList(R, 0, MAGAZINE_ACTION.MemType, MAGAZINE_ACTION.Address + 1, 6, ref wordList);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
MagazineActionToolModel tool = new MagazineActionToolModel()
|
|
{
|
|
Id = wordList[0]
|
|
};
|
|
|
|
MagazineActionToolModel secondTool = new MagazineActionToolModel()
|
|
{
|
|
Id = wordList[1]
|
|
};
|
|
|
|
// Populate model with new data
|
|
magazineAction = new MagazineActionModel()
|
|
{
|
|
Action = (MAGAZINE_ACTIONS)actionId,
|
|
Tool = tool,
|
|
SecondTool = secondTool,
|
|
OriginMagazine = wordList[2],
|
|
OriginPosition = wordList[3],
|
|
DestinationMagazine = wordList[4],
|
|
DestinationPosition = wordList[5]
|
|
};
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion Siemens Tools Management
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region Nc Tool Manager
|
|
|
|
public override CmsError TOOLS_RMagazineConfig(ref List<NcMagazineConfigModel> config)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Read data -> 5 status word (10 byte), 10 magazine max position word
|
|
List<ushort> readShorts = new List<ushort>();
|
|
cmsError = MEM_RWWordList(R, 0, MAGAZINE_TYPES.MemType, MAGAZINE_TYPES.Address, 30, ref readShorts);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
List<byte> types = new List<byte>();
|
|
// Convert into list o fbytes
|
|
types = readShorts.SelectMany(BitConverter.GetBytes).ToList();
|
|
|
|
config = new List<NcMagazineConfigModel>();
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
// Check if there are positions (skip the 5 status word)
|
|
if (readShorts[i + 10] > 0)
|
|
config.Add(new NcMagazineConfigModel()
|
|
{
|
|
Id = (byte)(i + 1),
|
|
MaxPositions = readShorts[i + 10],
|
|
Type = (NC_MAGAZINE_TYPE)types[i]
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WOptions(ToolManagerOptionsModel options)
|
|
{
|
|
// Convert class into a single ushort
|
|
bool[] boolValues = new bool[13]
|
|
{
|
|
options.FamilyOpt,
|
|
options.ShankOpt,
|
|
options.MagPosTypeOpt,
|
|
options.OffsetOpt,
|
|
options.ReviveOpt,
|
|
options.GammaOpt,
|
|
options.LifeOpt,
|
|
options.TcpOpt,
|
|
options.CoolingOpt,
|
|
options.MultidimensionalShankOpt,
|
|
options.SelfAdaptivePathOpt,
|
|
options.DynamicCompensationOpt,
|
|
options.BallufOpt
|
|
};
|
|
|
|
ushort intValue = 0;
|
|
// Convert array into a ushort
|
|
for (int i = 0; i < boolValues.Length; i++)
|
|
{
|
|
if (boolValues[i])
|
|
intValue += (ushort)(1 << i);
|
|
}
|
|
|
|
// Write & return
|
|
return MEM_RWWord(W, 0, TOOL_MANAGER_OPTIONS.MemType, TOOL_MANAGER_OPTIONS.Address, ref intValue);
|
|
}
|
|
|
|
public override CmsError TOOLS_ROffset(short offsetId, ref OffsetModel offset)
|
|
{
|
|
if (offsetId > MAX_OFFSET_NUM)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
offset = new OffsetModel() { Id = offsetId };
|
|
ODBTOFS offsetData = new ODBTOFS();
|
|
for (short i = 0; i < 4; i++)
|
|
{
|
|
// Read data
|
|
short nReturn = Focas1.cnc_rdtofs(nLibHandle[0], offsetId, i, 8, offsetData);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Change decimal digits
|
|
double valueRead = offsetData.data;
|
|
valueRead /= Math.Pow(10, OFFSET_DECIMAL_DIGITS);
|
|
|
|
// Switch param and set return object
|
|
switch (i)
|
|
{
|
|
case 0: offset.WearRadius = valueRead; break;
|
|
case 1: offset.Radius = valueRead; break;
|
|
case 2: offset.WearLength = valueRead; break;
|
|
case 3: offset.Length = valueRead; break;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WOffset(short offsetId, OffsetModel offset)
|
|
{
|
|
if (offsetId > MAX_OFFSET_NUM)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
double val = 0;
|
|
for (short i = 0; i < 4; i++)
|
|
{
|
|
// Switch param and set return object
|
|
switch (i)
|
|
{
|
|
case 0: val = offset.WearRadius; break;
|
|
case 1: val = offset.Radius; break;
|
|
case 2: val = offset.WearLength; break;
|
|
case 3: val = offset.Length; break;
|
|
}
|
|
|
|
// Change double to int
|
|
int valueToWrite = (int)(val * Math.Pow(10, OFFSET_DECIMAL_DIGITS));
|
|
|
|
// Read data
|
|
short nReturn = Focas1.cnc_wrtofs(nLibHandle[0], offsetId, i, 8, valueToWrite);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStartEditData()
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
ushort status = 0;
|
|
// Read tool manager status
|
|
cmsError = MEM_RWWord(R, 0, TOOL_MANAGER_STATUS.MemType, TOOL_MANAGER_STATUS.Address, ref status);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] bits = new bool[16];
|
|
|
|
// Convert int into to true/false array
|
|
bits = IntToBits(status);
|
|
// 1 = Non-editable tables, 2 = reading in progess
|
|
if (!bits[1] || bits[2])
|
|
return MAGAZINE_BUSY_ERROR;
|
|
|
|
// Write busy tool manager status
|
|
bool bitToWrite = true;
|
|
cmsError = MEM_RWBoolean(W, 0, TOOL_MANAGER_COMMAND.MemType, TOOL_MANAGER_COMMAND.Address, 1, ref bitToWrite);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//cmsError = CreateBackup();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStopEditData()
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//cmsError = DeleteBackup();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
// Release tool manager status
|
|
bool bitToWrite = false;
|
|
cmsError = MEM_RWBoolean(W, 0, TOOL_MANAGER_COMMAND.MemType, TOOL_MANAGER_COMMAND.Address, 1, ref bitToWrite);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//// Set reload command
|
|
//cmsError = PLC_WStrobe(TOOL_MANAGER_STATUS, TOOL_MANAGER_COMMAND, 1);
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateTools(List<NcToolModel> toolsList)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Create new values of the tools table
|
|
List<int> newMemoryValues = TOOLS_CreateNewToolTableMemoryData(toolsList, TOOL_TABLE_INDEX);
|
|
// Write in memory
|
|
return MEM_RWIntegerList(W, 0, TOOL_TABLE_INDEX.MemType, TOOL_TABLE_INDEX.Address, newMemoryValues.Count(), ref newMemoryValues);
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateFamilies(List<NcFamilyModel> familyList)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Create new values of the family table
|
|
List<int> newMemoryValues = TOOLS_CreateNewToolTableMemoryData(familyList, FAMILY_TABLE_INDEX);
|
|
|
|
return MEM_RWIntegerList(W, 0, FAMILY_TABLE_INDEX.MemType, FAMILY_TABLE_INDEX.Address, newMemoryValues.Count(), ref newMemoryValues);
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateShanks(List<NcShankModel> shankList)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Create new values of the shank table
|
|
List<int> newMemoryValues = TOOLS_CreateNewToolTableMemoryData(shankList, SHANK_TABLE_INDEX);
|
|
|
|
// Write in memory
|
|
return MEM_RWIntegerList(W, 0, SHANK_TABLE_INDEX.MemType, SHANK_TABLE_INDEX.Address, newMemoryValues.Count(), ref newMemoryValues);
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateMagazinePositions(List<NcMagazinePositionModel> magPosList)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
|
|
return cmsError;
|
|
// Create new values of the magazine positions table
|
|
List<int> newMemoryValues = TOOLS_CreateNewToolTableMemoryData(magPosList, MAG_POS_TABLE_INDEX);
|
|
|
|
// Write in memory
|
|
return MEM_RWIntegerList(W, 0, MAG_POS_TABLE_INDEX.MemType, MAG_POS_TABLE_INDEX.Address, newMemoryValues.Count(), ref newMemoryValues);
|
|
}
|
|
|
|
public override CmsError TOOLS_WStartEditTooling(int magazineId)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Read tool manager status
|
|
bool status = false;
|
|
cmsError = MEM_RWBoolean(R, 0, MAGAZINES_ENABLED_CMD.MemType, MAGAZINES_ENABLED_CMD.Address, magazineId - 1, ref status);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// If magazine is busy
|
|
if (!status)
|
|
return MAGAZINE_BUSY_ERROR;
|
|
|
|
// Write busy
|
|
bool bitToWrite = true;
|
|
cmsError = MEM_RWBoolean(W, 0, MAGAZINES_TOOLING_CMD.MemType, MAGAZINES_TOOLING_CMD.Address, magazineId - 1, ref bitToWrite);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//// Create backup files
|
|
//cmsError = CreateBackup();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStopEditTooling(int magazineId)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Set magazine as free
|
|
bool write = false;
|
|
cmsError = MEM_RWBoolean(W, 0, MAGAZINES_TOOLING_CMD.MemType, MAGAZINES_TOOLING_CMD.Address, magazineId - 1, ref write);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//// Delete backup files
|
|
//cmsError = DeleteBackup();
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
// Set reload command
|
|
cmsError = PLC_WStrobe(TOOL_MANAGER_STATUS, TOOL_MANAGER_COMMAND, 1);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WRestoreBackup()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RUpdatedToolsData(ref Dictionary<int, byte> updatedStatus, ref Dictionary<int, uint> updatedLives)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
updatedStatus = new Dictionary<int, byte>();
|
|
updatedLives = new Dictionary<int, uint>();
|
|
|
|
// Read 20 bit of status, read 20 bit of tool life
|
|
List<int> readInt = new List<int>();
|
|
cmsError = MEM_RWIntegerList(R, 0, TOOL_STATUS_UPDATED_CMD.MemType, TOOL_STATUS_UPDATED_CMD.Address, 2, ref readInt);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Convert int into to true/false array
|
|
bool[] bits = IntToBits(readInt.ToArray());
|
|
ushort toolId = 0;
|
|
byte status = 0;
|
|
uint life = 0;
|
|
|
|
int strobeByteIndex = 0;
|
|
int ackByteIndex = 0;
|
|
|
|
for (int i = 0; i < bits.Length; i++)
|
|
{
|
|
if (bits[i])
|
|
{
|
|
// If i >= 32 reset bit index
|
|
int bitIndex = i >= 32 ? i - 32 : i;
|
|
|
|
// mountedToolIndex =
|
|
int mountedToolIndex = (HEADS_DATA.Address + 4) + (bitIndex * 12);
|
|
cmsError = MEM_RWWord(R, 0, HEADS_DATA.MemType, mountedToolIndex, ref toolId);
|
|
|
|
if (i < 32)
|
|
{
|
|
// Read new status value
|
|
int statusByteIndex = i % 2;
|
|
int statusIndex = TOOL_STATUS_UPDATED_DATA.Address + (i / 2); // Index = starting address + (headIndex / 2) -> because Osai uses 16bit format
|
|
cmsError = MEM_RWByte(R, 0, TOOL_STATUS_UPDATED_DATA.MemType, statusIndex, statusByteIndex, ref status);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Insert into the list
|
|
updatedStatus.Add(toolId, status);
|
|
|
|
// Setup ack/strobe indexes
|
|
// if i > 15 then index = next word
|
|
strobeByteIndex = i > 15 ? TOOL_STATUS_UPDATED_CMD.Address + 1 : TOOL_STATUS_UPDATED_CMD.Address;
|
|
ackByteIndex = i > 15 ? TOOL_STATUS_UPDATED_ACK.Address + 1 : TOOL_STATUS_UPDATED_ACK.Address;
|
|
}
|
|
else
|
|
{
|
|
// Read new life value
|
|
int lifeIndex = TOOL_LIFE_UPDATED_DATA.Address + ((i - 32) * 2); // Index = starting address + (headIndex * 2) -> because Osai uses 16bit format
|
|
cmsError = MEM_RWDWord(R, 0, TOOL_LIFE_UPDATED_DATA.MemType, lifeIndex, ref life);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Insert into the new lives list
|
|
updatedLives.Add(toolId, life);
|
|
|
|
// Setup ack/strobe indexes
|
|
// if i > (32) + 15 then StrobeAckIndex is in the second word
|
|
strobeByteIndex = i > 47 ? TOOL_LIFE_UPDATED_CMD.Address + 1 : TOOL_LIFE_UPDATED_CMD.Address;
|
|
ackByteIndex = i > 47 ? TOOL_LIFE_UPDATED_ACK.Address + 1 : TOOL_LIFE_UPDATED_CMD.Address;
|
|
}
|
|
|
|
// Manage ack and strobe
|
|
bitIndex = bitIndex % 16;
|
|
cmsError = ManageActivePLCAcknowledge(strobeByteIndex, bitIndex, ackByteIndex, bitIndex, MEMORY_TYPE.Osai_MW);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RStoredData()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineStatus(ref Dictionary<int, bool> magazineStatus)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Read tool manager status
|
|
int status = 0;
|
|
cmsError = MEM_RWInteger(R, 0, MAGAZINES_ENABLED_CMD.MemType, MAGAZINES_ENABLED_CMD.Address, ref status);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] bits = IntToBits(status);
|
|
|
|
for (int i = 0; i < bits.Length; i++)
|
|
{
|
|
magazineStatus.Add(i + 1, bits[i]);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError TOOLS_RPositionOfNextShortId(int id, int startIndex, out int offset)
|
|
{
|
|
offset = 0;
|
|
|
|
// Read 300 bytes
|
|
List<int> ints = new List<int>();
|
|
CmsError cmsError = MEM_RWIntegerList(false, 0, Nc.MEMORY_TYPE.Fanuc_D, startIndex, 150, ref ints);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
ushort[] shorts = new ushort[300];
|
|
// Copy into ushorts
|
|
Buffer.BlockCopy(ints.ToArray(), 0, shorts, 0, ints.Count * sizeof(ushort));
|
|
// Find id
|
|
offset = Array
|
|
.FindIndex(shorts, x => x == id);
|
|
|
|
// if not found, get last number
|
|
if (offset == -1)
|
|
{
|
|
offset = 0;
|
|
for (int i = 0; i < shorts.Count(); i++)
|
|
if (shorts[i] != 0)
|
|
offset = i + 1;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError TOOLS_RPositionOfNextByteId(int id, int startIndex, out int offset)
|
|
{
|
|
offset = 0;
|
|
|
|
// Read 300 bytes
|
|
List<int> ints = new List<int>();
|
|
CmsError cmsError = MEM_RWIntegerList(false, 0, Nc.MEMORY_TYPE.Fanuc_D, startIndex, 75, ref ints);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
byte[] bytes = new byte[300];
|
|
// Copy into ushorts
|
|
Buffer.BlockCopy(ints.ToArray(), 0, bytes, 0, ints.Count * sizeof(ushort));
|
|
|
|
offset = 0;
|
|
// Search last populated value
|
|
for (int i = 0; i < bytes.Count(); i++)
|
|
if (bytes[i] != 0)
|
|
offset = i + 1;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError TOOLS_WObjectInMemory<T>(T item, int startTableIndex, int objOffset) where T : class
|
|
{
|
|
PropertyInfo[] properties = typeof(T).GetProperties();
|
|
|
|
CmsError cmsError = NO_ERROR;
|
|
int nextFieldIndex = startTableIndex;
|
|
|
|
foreach (PropertyInfo property in properties)
|
|
{
|
|
// Get the size of the property
|
|
int size = Marshal.SizeOf(property.PropertyType);
|
|
|
|
// Add obj index to the parameter memory
|
|
int currentFieldIndex = nextFieldIndex + objOffset * size;
|
|
|
|
// Write based on the size
|
|
switch (size)
|
|
{
|
|
case 1:
|
|
{
|
|
byte b = Convert.ToByte(property.GetValue(item));
|
|
cmsError = MEM_RWByte(W, 0, MEMORY_TYPE.Fanuc_D, currentFieldIndex, 0, ref b);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
{
|
|
ushort u = Convert.ToUInt16(property.GetValue(item));
|
|
cmsError = MEM_RWWord(W, 0, MEMORY_TYPE.Fanuc_D, currentFieldIndex, ref u);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
{
|
|
uint w = Convert.ToUInt32(property.GetValue(item));
|
|
cmsError = MEM_RWDWord(W, 0, MEMORY_TYPE.Fanuc_D, currentFieldIndex, ref w);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Calculate the starting index of the next field
|
|
nextFieldIndex += size * TOOL_OFFSET;
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
private List<int> TOOLS_CreateNewToolTableMemoryData<T>(List<T> items, MEMORY_CELL tableInfo) where T : class
|
|
{
|
|
PropertyInfo[] properties = typeof(T).GetProperties();
|
|
byte[] values = new byte[tableInfo.Size];
|
|
|
|
// Start from the begin of the table
|
|
int nextFieldIndex = 0;
|
|
// Index of the
|
|
int objOffset = 0;
|
|
|
|
foreach (T item in items)
|
|
{
|
|
foreach (PropertyInfo property in properties)
|
|
{
|
|
// Get the size of the property
|
|
int size = Marshal.SizeOf(property.PropertyType);
|
|
|
|
// Add obj index to the parameter memory
|
|
int currentFieldIndex = nextFieldIndex + objOffset * size;
|
|
|
|
// Choose action based on the size
|
|
switch (size)
|
|
{
|
|
case 1:
|
|
{
|
|
byte b = Convert.ToByte(property.GetValue(item));
|
|
values[currentFieldIndex] = b;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
{
|
|
ushort u = Convert.ToUInt16(property.GetValue(item));
|
|
// Split ushort into 2 bytes
|
|
byte[] bytesVal = NumberToByte(u);
|
|
// Overwrite bytes with new values
|
|
values[currentFieldIndex] = bytesVal[0];
|
|
values[currentFieldIndex + 1] = bytesVal[1];
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
{
|
|
uint i = Convert.ToUInt32(property.GetValue(item));
|
|
// Split uint into 4 bytes
|
|
byte[] bytesVal = NumberToByte(i);
|
|
// Overwrite bytes
|
|
values[currentFieldIndex] = bytesVal[0];
|
|
values[currentFieldIndex + 1] = bytesVal[1];
|
|
values[currentFieldIndex + 2] = bytesVal[2];
|
|
values[currentFieldIndex + 3] = bytesVal[3];
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Calculate the starting index of the next field
|
|
nextFieldIndex += size * TOOL_OFFSET;
|
|
}
|
|
|
|
// Increment offset
|
|
objOffset++;
|
|
|
|
// Reset counters
|
|
nextFieldIndex = 0;
|
|
}
|
|
|
|
return ListOfByteToListOf<int>(values, BitConverter.ToInt32);
|
|
}
|
|
|
|
private string GenerateCsvStringFromModel<T>(List<T> items) where T : class
|
|
{
|
|
var output = "";
|
|
var delimiter = ';';
|
|
var properties = typeof(T).GetProperties();
|
|
|
|
using (var sw = new StringWriter())
|
|
{
|
|
foreach (var item in items)
|
|
{
|
|
var row = properties
|
|
.Select(n => n.GetValue(item, null))
|
|
.Select(n => n?.ToString())
|
|
.Aggregate((a, b) => a + delimiter + b);
|
|
|
|
sw.WriteLine(row);
|
|
}
|
|
output = sw.ToString();
|
|
}
|
|
return output;
|
|
}
|
|
|
|
private CmsError ManageActivePLCAcknowledge(int strobeByte, int strobeBit, int ackByte, int ackBit, MEMORY_TYPE memType)
|
|
{
|
|
int n = 1200; // 30 seconds
|
|
bool readValue = false;
|
|
bool writeValue = true;
|
|
bool ok = false;
|
|
// Set ack to 1
|
|
CmsError cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackBit, ref writeValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
do
|
|
{
|
|
// Check strobe
|
|
cmsError = MEM_RWBoolean(R, 0, memType, strobeByte, strobeBit, ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// If true reset acknowledge
|
|
if (!readValue)
|
|
{
|
|
writeValue = false;
|
|
// Reset acknowledge
|
|
cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackBit, ref writeValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
// Exit from cycle
|
|
n = 0;
|
|
ok = true;
|
|
}
|
|
else
|
|
{
|
|
// Decrement
|
|
n--;
|
|
// Wait befor next cycle
|
|
Thread.Sleep(25);
|
|
}
|
|
} while (n > 0);
|
|
|
|
// If loop timeout goes in timeout
|
|
if (!ok)
|
|
{
|
|
// Reset acknowledge
|
|
writeValue = false;
|
|
cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackBit, ref writeValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
#endregion Nc Tool Manager
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region Subordinate Private Functions
|
|
|
|
#region Memory private Functions
|
|
|
|
private CmsError PLC_WStrobe(MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id)
|
|
{
|
|
CmsError cmsError;
|
|
bool readValue = false;
|
|
bool writeValue = true;
|
|
|
|
SetupAckStrobeAddresses(ackCell.Address, strobeCell.Address, id, out int ackWord, out int strobeWord, out int bitIndex);
|
|
|
|
// Check Strobe
|
|
cmsError = MEM_RWBoolean(R, 0, strobeCell.MemType, strobeWord, bitIndex, ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// If strobe == 1 return
|
|
if (readValue)
|
|
return NO_ERROR;
|
|
|
|
// Check ACK
|
|
cmsError = MEM_RWBoolean(R, 0, ackCell.MemType, ackWord, bitIndex, ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// If PLC it's performing another request then return
|
|
if (readValue)
|
|
return NO_ERROR;
|
|
|
|
// Write strobe into memory
|
|
cmsError = MEM_RWBoolean(W, 0, strobeCell.MemType, strobeWord, bitIndex, ref writeValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Reset wait ack = 1 and reset the strobe
|
|
cmsError = ResetStrobe(bitIndex, strobeWord, ackWord, ackCell.MemType);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private void SetupAckStrobeAddresses(int ackAddress, int strobeAddress, uint id, out int ackWord, out int strobeWord, out int bit)
|
|
{
|
|
ackWord = ackAddress + (((int)id - 1) / 8);
|
|
strobeWord = strobeAddress + (((int)id - 1) / 8);
|
|
bit = (((int)id - 1) % 8);
|
|
}
|
|
|
|
private CmsError ResetStrobe(int bit, int strobeByte, int ackByte, MEMORY_TYPE memType)
|
|
{
|
|
int n = 1200; // 30 seconds
|
|
bool readValue = false;
|
|
bool writeValue = false;
|
|
bool ok = false;
|
|
|
|
CmsError cmsError;
|
|
do
|
|
{
|
|
// Check ACK
|
|
cmsError = MEM_RWBoolean(R, 0, memType, ackByte, bit, ref readValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// If true reset strobe
|
|
if (readValue)
|
|
{
|
|
// Reset strobe
|
|
cmsError = MEM_RWBoolean(W, 0, memType, strobeByte, bit, ref writeValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
// Exit from cycle
|
|
n = 0;
|
|
ok = true;
|
|
}
|
|
else
|
|
{
|
|
// Decrement
|
|
n--;
|
|
// Wait befor next cycle
|
|
Thread.Sleep(25);
|
|
}
|
|
} while (n > 0);
|
|
|
|
// If loop timeout goes in timeout
|
|
if (!ok)
|
|
{
|
|
// Reset strobe
|
|
cmsError = MEM_RWBoolean(W, 0, memType, strobeByte, bit, ref writeValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
private CmsError PLC_RSoftKeys(MEMORY_CELL softKeyStatusMemory, MEMORY_CELL softKeysClickableMemory, ref List<SoftKeysModel> softKeys)
|
|
{
|
|
softKeys = new List<SoftKeysModel>();
|
|
List<int> readValue = new List<int>();
|
|
|
|
int memorySizeToRead = (softKeyStatusMemory.Size + softKeysClickableMemory.Size);
|
|
// Offset between status and clickable data
|
|
int offset = softKeyStatusMemory.Size * 8;
|
|
|
|
// Read on data from memory
|
|
CmsError cmsError = MEM_RWIntegerList(R, 0,
|
|
softKeyStatusMemory.MemType,
|
|
softKeyStatusMemory.Address,
|
|
memorySizeToRead / 4,
|
|
ref readValue);
|
|
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] bits = IntToBits(readValue.ToArray());
|
|
|
|
// Convert array into structured data
|
|
for (ushort i = 0; i < bits.Count() / 2; i++)
|
|
{
|
|
softKeys.Add(new SoftKeysModel()
|
|
{
|
|
Id = (uint)i + 1,
|
|
Value = bits[i],
|
|
Active = bits[i + offset]
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#endregion Memory private Functions
|
|
|
|
private Focas1.page_code ConvertStepToFanucScreen(SCREEN_PAGE page)
|
|
{
|
|
switch (page)
|
|
{
|
|
case SCREEN_PAGE.Fanuc_Pos: return Focas1.page_code.ABS;
|
|
case SCREEN_PAGE.Fanuc_Prog: return Focas1.page_code.PROG;
|
|
case SCREEN_PAGE.Fanuc_Offset: return Focas1.page_code.OFFSET;
|
|
case SCREEN_PAGE.Fanuc_Message: return Focas1.page_code.ALARM;
|
|
case SCREEN_PAGE.Fanuc_System: return Focas1.page_code.PARAM;
|
|
case SCREEN_PAGE.Fanuc_Custom1: return Focas1.page_code.TMAC1;
|
|
case SCREEN_PAGE.Fanuc_Custom2: return Focas1.page_code.TMAC2;
|
|
case SCREEN_PAGE.Fanuc_Graph: return Focas1.page_code.GRAPH;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
private CmsError ErrorHandler(short exNum)
|
|
{
|
|
if (exNum != 0)
|
|
return GetNcError(exNum);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private void ReadRelativeAxisPos(Focas1.POSELM pos, int axisId, ref Dictionary<string, double> Axes)
|
|
{
|
|
//If is setted VISIBLE add to List
|
|
if (pos.disp != 0)
|
|
{
|
|
// string AxName;
|
|
double AxVal;
|
|
KeyValuePair<string, double> val;
|
|
|
|
//Read the name and Value
|
|
// AxName = pos.name.ToString() + pos.suff.ToString().Trim('\0');
|
|
AxVal = pos.data / Math.Pow(10, pos.dec);
|
|
|
|
// Fill in the list
|
|
val = Axes.FirstOrDefault(X => X.Key == axisId.ToString());
|
|
if (val.Key != null)
|
|
Axes[val.Key] = AxVal;
|
|
else
|
|
Axes.Add(axisId.ToString(), AxVal);
|
|
}
|
|
}
|
|
|
|
// Convert to Step Language
|
|
private CultureInfo ConvertToSTEPLanguage(byte language)
|
|
{
|
|
switch (language)
|
|
{
|
|
case 0: return new CultureInfo("en");
|
|
case 1: return new CultureInfo("ja");
|
|
case 2: return new CultureInfo("de");
|
|
case 3: return new CultureInfo("fr");
|
|
case 4: return new CultureInfo("zh-CHT");
|
|
case 5: return new CultureInfo("it");
|
|
case 6: return new CultureInfo("ko");
|
|
case 7: return new CultureInfo("es");
|
|
case 8: return new CultureInfo("nl");
|
|
case 9: return new CultureInfo("da");
|
|
case 10: return new CultureInfo("pt");
|
|
case 11: return new CultureInfo("pl");
|
|
case 12: return new CultureInfo("hu");
|
|
case 13: return new CultureInfo("sv");
|
|
case 14: return new CultureInfo("cs");
|
|
case 15: return new CultureInfo("zh-CHS");
|
|
case 16: return new CultureInfo("ru");
|
|
case 17: return new CultureInfo("tr");
|
|
case 18: return new CultureInfo("bg");
|
|
case 19: return new CultureInfo("ro");
|
|
case 20: return new CultureInfo("sk");
|
|
case 21: return new CultureInfo("fi");
|
|
default: return new CultureInfo("en");
|
|
}
|
|
}
|
|
|
|
// Convert to NC Language
|
|
private byte ConvertToNCLanguage(CultureInfo language)
|
|
{
|
|
switch (language.Name)
|
|
{
|
|
case "en": return 0;
|
|
case "ja": return 1;
|
|
case "de": return 2;
|
|
case "fr": return 3;
|
|
case "zh-CHT": return 4;
|
|
case "it": return 5;
|
|
case "ko": return 6;
|
|
case "es": return 7;
|
|
case "nl": return 8;
|
|
case "da": return 9;
|
|
case "pt": return 10;
|
|
case "pl": return 11;
|
|
case "hu": return 12;
|
|
case "sv": return 13;
|
|
case "cs": return 14;
|
|
case "zh-CHS": return 15;
|
|
case "ru": return 16;
|
|
case "tr": return 17;
|
|
case "bg": return 18;
|
|
case "ro": return 19;
|
|
case "sk": return 20;
|
|
case "fi": return 21;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
// Manage the Status Process
|
|
private PROC_STATUS ConverToSTEPStatus(Focas1.ODBST status)
|
|
{
|
|
if (status.emergency != 0)
|
|
return PROC_STATUS.EMERG;
|
|
|
|
if (status.alarm != 0)
|
|
return PROC_STATUS.ERROR;
|
|
|
|
switch (status.run)
|
|
{
|
|
case 0: return PROC_STATUS.IDLE;
|
|
case 1: return PROC_STATUS.HOLD;
|
|
case 2: return PROC_STATUS.RUN;
|
|
case 3: return PROC_STATUS.RUN;
|
|
case 4: return PROC_STATUS.RUN;
|
|
case 5: return PROC_STATUS.RUN;
|
|
case 7: return PROC_STATUS.RUN;
|
|
case 8: return PROC_STATUS.RESET;
|
|
}
|
|
return PROC_STATUS.ERROR;
|
|
}
|
|
|
|
// Manage the Status Mode
|
|
private PROC_MODE ConverToSTEPMode(Focas1.ODBST status)
|
|
{
|
|
switch (status.aut)
|
|
{
|
|
case 0: return PROC_MODE.MDI;
|
|
case 1: return PROC_MODE.AUTO;
|
|
case 2: return PROC_MODE.ERROR;
|
|
case 3: return PROC_MODE.EDIT;
|
|
case 4: return PROC_MODE.HANDLE;
|
|
case 5: return PROC_MODE.JOG;
|
|
case 6: return PROC_MODE.TEACH;
|
|
case 7: return PROC_MODE.TEACH;
|
|
case 8: return PROC_MODE.JOGINC;
|
|
case 9: return PROC_MODE.REF;
|
|
case 10: return PROC_MODE.REMOTE;
|
|
}
|
|
return PROC_MODE.ERROR;
|
|
}
|
|
|
|
// Get the Right Process
|
|
private short GetHandleIndexFromPath(ushort path)
|
|
{
|
|
//Check it is too big
|
|
if (path > Cnc_NumPath)
|
|
return -1;
|
|
|
|
//Check it is too small
|
|
if (path <= 0)
|
|
return -1;
|
|
|
|
//Return
|
|
return (short)(path - 1);
|
|
}
|
|
|
|
// Read Static Data
|
|
private CmsError ReadStaticNCData()
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn1, nReturn2;
|
|
Focas1.ODBSYS node = new Focas1.ODBSYS();
|
|
Focas1.ODBSYSEX nodeex = new Focas1.ODBSYSEX();
|
|
ulong SerialNumber = 0;
|
|
|
|
//Read oly one time every 10 seconds
|
|
if (DateTime.Now - Last_Static_Read > new TimeSpan(NC_MIN_SEC_READ_STATIC_DATA * TimeSpan.TicksPerSecond))
|
|
{
|
|
//Read Language from NC PARAM
|
|
cmsError = NC_RParam((short)PARAM_LING_FANUC.Address, ref FanucLanguage);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Execute the method
|
|
nReturn1 = Focas1.cnc_sysinfo(nLibHandle[0], node);
|
|
|
|
nReturn2 = Focas1.cnc_rdcncid(nLibHandle[0], out SerialNumber);
|
|
|
|
// Throw Exception if there's an error
|
|
if (nReturn1 != 0)
|
|
{
|
|
return GetNcError(nReturn1);
|
|
}
|
|
else if (nReturn2 != 0 && nReturn2 != 1)
|
|
{
|
|
return GetNcError(nReturn2);
|
|
}
|
|
else
|
|
{
|
|
Cnc_name = "NOME_CN";
|
|
Cnc_SftVersion = "VERSIONE_SW";
|
|
//Setup the name
|
|
// Cnc_name = GetName(node.cnc_type, node.mt_type);
|
|
|
|
//Setup the Software version
|
|
//Cnc_SftVersion = new string(node.version);
|
|
|
|
//Setup the Number Series
|
|
Cnc_SeriesNum = SerialNumber.ToString();
|
|
|
|
Last_Static_Read = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Manage the Exception Launch
|
|
private CmsError GetNcError(short exNum)
|
|
{
|
|
if (exNum == (short)Focas1.focas_ret.EW_SOCKET)
|
|
{
|
|
NC_Disconnect();
|
|
return NOT_CONNECTED_ERROR;
|
|
}
|
|
|
|
return CmsError.NcError(GetErrorMessage(exNum));
|
|
}
|
|
|
|
// Check if NC is connected
|
|
private CmsError CheckConnection()
|
|
{
|
|
if (!NC_IsConnected())
|
|
return NOT_CONNECTED_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Check if Memory Area is corrected
|
|
private CmsError CheckMemoryArea(string AreaName)
|
|
{
|
|
if (!AreaName.StartsWith(FANUC_MEMTYPE) && !AreaName.StartsWith(UNDEFINED_MEMTYPE))
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Check if NC is connected
|
|
private CmsError CheckBitRange(int bitnum)
|
|
{
|
|
if (bitnum < 0 || bitnum > 7)
|
|
return BIT_NOT_IN_RANGE_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Convert the internal Name var in Readable STEP Name
|
|
private string GetName(char[] Cnc_Type, char[] Mt_Type)
|
|
{
|
|
string name = "Fanuc ";
|
|
switch (string.Join("", Cnc_Type))
|
|
{
|
|
case "15": name += "15 Series"; break;
|
|
case "16": name += "16 Series"; break;
|
|
case "18": name += "18 Series"; break;
|
|
case "21": name += "21 Series"; break;
|
|
case "30": name += "30i Series"; break;
|
|
case "31": name += "31i Series"; break;
|
|
case "32": name += "21i Series"; break;
|
|
case "35": name += "35i Series"; break;
|
|
case "0": name += "0i Series"; break;
|
|
}
|
|
name += " " + string.Join("", Mt_Type);
|
|
return name;
|
|
}
|
|
|
|
// Write Part program content
|
|
private CmsError WritePartProgramContent(string partProgramPath, string partProgramContent)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn;
|
|
|
|
// Start write
|
|
nReturn = Focas1.cnc_dwnstart4(nLibHandle[0], 0, partProgramPath);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// int lenghtMax = fileData.Length;
|
|
|
|
int lenght = partProgramContent.Length;
|
|
// Write program
|
|
nReturn = Focas1.cnc_download4(nLibHandle[0], ref lenght, partProgramContent);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Stop writing
|
|
nReturn = Focas1.cnc_dwnend4(nLibHandle[0]);
|
|
if (nReturn != 0)
|
|
{
|
|
Focas1.ODBERR errorDetails = new Focas1.ODBERR();
|
|
nReturn = Focas1.cnc_getdtailerr(nLibHandle[0], errorDetails);
|
|
|
|
// I error is == 5 the filepath exist and the file is selected by NC
|
|
if (errorDetails.err_no == 5)
|
|
return PROGRAM_IS_SELECTED_ERROR;
|
|
|
|
return GetNcError(nReturn);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError WritePPInCmsFolder(string partProgramPath, string partProgramContent)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn;
|
|
|
|
// Start write
|
|
nReturn = Focas1.cnc_dwnstart4(nLibHandle[0], 0, partProgramPath);
|
|
if (nReturn != 0)
|
|
{
|
|
// If path doesn't exist than create the CMS folder
|
|
if (nReturn == 5)
|
|
{
|
|
nReturn = Focas1.cnc_pdf_add(nLibHandle[0], NC_SUPPORT_FILE_PATH);
|
|
|
|
nReturn = Focas1.cnc_dwnstart4(nLibHandle[0], 0, partProgramPath);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
}
|
|
else
|
|
return GetNcError(nReturn);
|
|
}
|
|
nReturn = Focas1.cnc_dwnend4(nLibHandle[0]);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
|
|
return WritePartProgramContent(partProgramPath, partProgramContent);
|
|
}
|
|
|
|
// Read Part program content
|
|
private CmsError ReadPartProgramContent(string partProgramPath, ref string partProgramContent)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool fileEnded = false;
|
|
short nReturn;
|
|
int lenght = 256;
|
|
|
|
// Start read process
|
|
nReturn = Focas1.cnc_upstart4(nLibHandle[0], 0, partProgramPath);
|
|
|
|
// Return if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
do
|
|
{
|
|
// Local buffer
|
|
char[] tmpContentBuffer = new char[256]; // TODO find function to read size file
|
|
|
|
// Read file
|
|
nReturn = Focas1.cnc_upload4(nLibHandle[0], ref lenght, tmpContentBuffer);
|
|
|
|
// If File ended
|
|
switch (nReturn)
|
|
{
|
|
case (short)Focas1.focas_ret.EW_RESET:
|
|
{
|
|
fileEnded = true;
|
|
}
|
|
break;
|
|
|
|
case Focas1.EW_OK:
|
|
{
|
|
// Add the characters into string with all the content
|
|
partProgramContent += new string(tmpContentBuffer);
|
|
}
|
|
break;
|
|
|
|
case (short)Focas1.focas_ret.EW_BUFFER:
|
|
{
|
|
continue;
|
|
}
|
|
default:
|
|
{
|
|
return GetNcError(nReturn);
|
|
}
|
|
}
|
|
|
|
if (lenght <= 256)
|
|
fileEnded = true;
|
|
|
|
} while ((nReturn == (short)Focas1.focas_ret.EW_OK || nReturn == (short)Focas1.focas_ret.EW_BUFFER) && !fileEnded);
|
|
|
|
// End read
|
|
nReturn = Focas1.cnc_upend4(nLibHandle[0]);
|
|
|
|
// Return if there's an error
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
partProgramContent = partProgramContent.Replace("\0", string.Empty);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Manage the Exception Launch
|
|
private CmsError ManageException(Exception ex)
|
|
{
|
|
Connected = false;
|
|
|
|
return CmsError.InternalError(ex.Message);
|
|
}
|
|
|
|
// Convert the internal error in a readable-String error
|
|
private string GetErrorMessage(short Value)
|
|
{
|
|
string ErrororOwner = "";
|
|
ErrororOwner = "Fanuc-Core-Error: ";
|
|
Focas1.focas_ret Val = (Focas1.focas_ret)Value;
|
|
switch (Val)
|
|
{
|
|
case Focas1.focas_ret.EW_PROTOCOL: return ErrororOwner + "protocol error";
|
|
case Focas1.focas_ret.EW_SOCKET: return ErrororOwner + "Windows socket error";
|
|
case Focas1.focas_ret.EW_NODLL: return ErrororOwner + "DLL not exist error";
|
|
case Focas1.focas_ret.EW_BUS: return ErrororOwner + "bus error";
|
|
case Focas1.focas_ret.EW_SYSTEM2: return ErrororOwner + "system error";
|
|
case Focas1.focas_ret.EW_HSSB: return ErrororOwner + "hssb communication error";
|
|
case Focas1.focas_ret.EW_HANDLE: return ErrororOwner + "Windows library handle error";
|
|
case Focas1.focas_ret.EW_VERSION: return ErrororOwner + "CNC/PMC version missmatch";
|
|
case Focas1.focas_ret.EW_UNEXP: return ErrororOwner + "abnormal error";
|
|
case Focas1.focas_ret.EW_SYSTEM: return ErrororOwner + "system error";
|
|
case Focas1.focas_ret.EW_PARITY: return ErrororOwner + "shared RAM parity error";
|
|
case Focas1.focas_ret.EW_MMCSYS: return ErrororOwner + "emm386 or mmcsys install error";
|
|
case Focas1.focas_ret.EW_RESET: return ErrororOwner + "reset or stop occured error";
|
|
case Focas1.focas_ret.EW_BUSY: return ErrororOwner + "busy error";
|
|
case Focas1.focas_ret.EW_FUNC: return ErrororOwner + "command prepare error / pmc not exist";
|
|
case Focas1.focas_ret.EW_LENGTH: return ErrororOwner + "data block length error";
|
|
case Focas1.focas_ret.EW_NUMBER: return ErrororOwner + "data number / address range error";
|
|
case Focas1.focas_ret.EW_ATTRIB: return ErrororOwner + "data type / attribute error";
|
|
case Focas1.focas_ret.EW_DATA: return ErrororOwner + "data error";
|
|
case Focas1.focas_ret.EW_NOOPT: return ErrororOwner + "no option error";
|
|
case Focas1.focas_ret.EW_PROT: return ErrororOwner + "write protect error";
|
|
case Focas1.focas_ret.EW_OVRFLOW: return ErrororOwner + "memory overflow error";
|
|
case Focas1.focas_ret.EW_PARAM: return ErrororOwner + "cnc parameter not correct error";
|
|
case Focas1.focas_ret.EW_BUFFER: return ErrororOwner + "buffer error";
|
|
case Focas1.focas_ret.EW_PATH: return ErrororOwner + "path error";
|
|
case Focas1.focas_ret.EW_MODE: return ErrororOwner + "cnc mode error";
|
|
case Focas1.focas_ret.EW_REJECT: return ErrororOwner + "execution rejected error";
|
|
case Focas1.focas_ret.EW_DTSRVR: return ErrororOwner + "data server error";
|
|
case Focas1.focas_ret.EW_ALARM: return ErrororOwner + "alarm has been occurred";
|
|
case Focas1.focas_ret.EW_STOP: return ErrororOwner + "CNC is not running";
|
|
case Focas1.focas_ret.EW_PASSWD: return ErrororOwner + "protection data error";
|
|
}
|
|
return ErrororOwner + "Generic Error On Function, Error Number: " + Val;
|
|
}
|
|
|
|
#endregion Subordinate Private Functions
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
internal static class MEMORY_ADDRESS
|
|
{
|
|
internal const int STARTING_ADDRESS = 20000;
|
|
|
|
internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS, 1);
|
|
internal static MEMORY_CELL ACTIVE_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2, 1);
|
|
internal static MEMORY_CELL FUNCTION_ACCESS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 5, 8);
|
|
|
|
// Alarms
|
|
internal static MEMORY_CELL ALARMS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 13, 128);
|
|
internal static MEMORY_CELL ALARMS_DATA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 141, 1024);
|
|
internal static MEMORY_CELL ALARM_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2189, 128);
|
|
internal static MEMORY_CELL ALARM_RESTORATION_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2317, 128);
|
|
internal static MEMORY_CELL ALARM_REFRESH_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2445, 128);
|
|
|
|
// Power on
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2573, 2);
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2575, 2);
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2577, 2);
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2579, 2);
|
|
|
|
internal static MEMORY_CELL PROCESS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2581, 0, 24);
|
|
internal static MEMORY_CELL SELECTED_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2581, 2, 24);
|
|
internal static MEMORY_CELL SELECT_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2605, 1);
|
|
|
|
internal static MEMORY_CELL AXIS_RESET_PROCEDURE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2607, 7, 1);
|
|
|
|
internal static MEMORY_CELL NC_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2608, 0, 4);
|
|
internal static MEMORY_CELL NC_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2612, 0, 4);
|
|
internal static MEMORY_CELL NC_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2616, 4);
|
|
internal static MEMORY_CELL NC_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2620, 4);
|
|
|
|
internal static MEMORY_CELL SELECTED_AXIS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2624, 0, 1);
|
|
internal static MEMORY_CELL SELECT_AXIS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2625, 1, 1);
|
|
|
|
internal static MEMORY_CELL USER_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2626, 0, 16);
|
|
internal static MEMORY_CELL USER_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2642, 0, 16);
|
|
internal static MEMORY_CELL USER_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2658, 16);
|
|
internal static MEMORY_CELL USER_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2674, 16);
|
|
|
|
internal static MEMORY_CELL HEADS_DATA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2690, 240);
|
|
internal static MEMORY_CELL HEADS_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2921, 4);
|
|
internal static MEMORY_CELL HEADS_STROBE_INCREMENT = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2924, 4);
|
|
internal static MEMORY_CELL HEADS_STROBE_DECREMENT = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2927, 4);
|
|
|
|
internal static MEMORY_CELL COUNTERS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2930, 0, 44);
|
|
internal static MEMORY_CELL COUNTER_IS_RESETTABLE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2998, 0, 2);
|
|
internal static MEMORY_CELL COUNTER_IS_RESETTABLE_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3000, 0, 2);
|
|
internal static MEMORY_CELL COUNTER_IS_RESETTABLE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3002, 0, 2);
|
|
|
|
internal static MEMORY_CELL M155_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3004, 1);
|
|
internal static MEMORY_CELL MTCONNECT_DATA_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3031, 1);
|
|
internal static MEMORY_CELL AXES_BUTTON_VISIBLE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3033, 16);
|
|
|
|
|
|
// Tool manager areas
|
|
internal static MEMORY_CELL MAGAZINE_ACTION = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4000, 16);
|
|
|
|
internal static MEMORY_CELL TOOL_MANAGER_COMMAND = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4013, 2);
|
|
|
|
internal static MEMORY_CELL TOOL_MANAGER_STATUS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4015, 2);
|
|
|
|
internal static MEMORY_CELL TOOL_MANAGER_OPTIONS = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4017, 2);
|
|
|
|
internal static MEMORY_CELL TOOL_STATUS_UPDATED_CMD = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4037, 4);
|
|
internal static MEMORY_CELL TOOL_LIFE_UPDATED_CMD = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4041, 4);
|
|
internal static MEMORY_CELL TOOL_STATUS_UPDATED_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4045, 4);
|
|
internal static MEMORY_CELL TOOL_LIFE_UPDATED_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4049, 4);
|
|
|
|
internal static MEMORY_CELL TOOL_STATUS_UPDATED_DATA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4053, 10);
|
|
internal static MEMORY_CELL TOOL_LIFE_UPDATED_DATA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4073, 80);
|
|
|
|
internal static MEMORY_CELL MAGAZINE_TYPES = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4153, 0);
|
|
internal static MEMORY_CELL MAGAZINE_POSITIONS_NUMBER = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4173, 0);
|
|
|
|
internal static MEMORY_CELL MAGAZINES_ENABLED_CMD = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4213, 4);
|
|
internal static MEMORY_CELL MAGAZINES_TOOLING_CMD = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4217, 4);
|
|
|
|
// Tool table indexes
|
|
internal static MEMORY_CELL TOOL_TABLE_INDEX = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 10000, 6900);
|
|
internal static MEMORY_CELL FAMILY_TABLE_INDEX = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 17000, 7500);
|
|
internal static MEMORY_CELL SHANK_TABLE_INDEX = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 24600, 3300);
|
|
internal static MEMORY_CELL MAG_POS_TABLE_INDEX = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 28000, 1200);
|
|
}
|
|
} |