5671 lines
227 KiB
C#
5671 lines
227 KiB
C#
using CMS_CORE_Library.Models;
|
|
using CMS_CORE_Library.Utils;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
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 NC_PROGRAM_PATH = "//CNC_MEM/USER/";
|
|
|
|
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);
|
|
// Use ISO-639-2
|
|
string threeLetterIso = "";
|
|
if (cultureInfo.IsNeutralCulture)
|
|
threeLetterIso = cultureInfo.ThreeLetterISOLanguageName;
|
|
else
|
|
threeLetterIso = cultureInfo.Parent.ThreeLetterISOLanguageName;
|
|
|
|
//Setup the Path
|
|
filePath = PLC_MESSAGE_PATH + @"Messaggi_" + threeLetterIso + @".txt";
|
|
|
|
if (!File.Exists(filePath))
|
|
return FILE_NOT_FOUND_ERROR;
|
|
|
|
// Read From Files
|
|
var fileLines = File.ReadAllLines(filePath, Encoding.Default);
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
public override CmsError NC_GetAvailableLanguages(ref ICollection<CultureInfo> languages)
|
|
{
|
|
try
|
|
{
|
|
foreach (string file in Directory.GetFiles(PLC_MESSAGE_PATH))
|
|
{
|
|
if (Path.GetExtension(file) == ".txt")
|
|
{
|
|
string fileName = Path.GetFileNameWithoutExtension(file);
|
|
|
|
var splittedFileName = fileName.Split('_');
|
|
if (splittedFileName.Count() == 2)
|
|
{
|
|
// Get lang from threeletter
|
|
var lang = GetCultureFromThreeLetter(splittedFileName[1]);
|
|
|
|
if (lang != null)
|
|
languages.Add(lang);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#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 bit 7 to TRUE
|
|
//byte langToWrite = (byte)(ConvertToNCLanguage(Language, out bool isSpecial) | 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;
|
|
|
|
//// Set reset bit
|
|
//bool b = false;
|
|
//int n = 25;
|
|
//do
|
|
//{
|
|
// // Wait before read
|
|
// Thread.Sleep(200);
|
|
|
|
// cmsError = MEM_RWBoolean(R, 0, MEMORY_TYPE.Fanuc_F, 545, 0, ref b);
|
|
// // Decrement
|
|
// n--;
|
|
//} while (!b && n > 0);
|
|
|
|
//b = false;
|
|
//cmsError = MEM_RWBoolean(W, 0, PARAM_LING_FANUC_W.MemType, PARAM_LING_FANUC_W.Address, 7, ref b);
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
/////// FANUC METODO
|
|
//
|
|
//byte lang = ConvertToNCLanguage(Language, out bool isSpecial);
|
|
//ushort hndl;
|
|
|
|
////Execute the method
|
|
//short nReturn = Focas1.cnc_allclibhndl3(Ip, Port, 5, out hndl);
|
|
|
|
//nReturn = Focas1.cnc_chglang(hndl, lang);
|
|
////Throw Exception if there's an error
|
|
//if (nReturn != 0)
|
|
// return GetNcError(nReturn);
|
|
|
|
//nReturn = Focas1.cnc_freelibhndl(hndl);
|
|
|
|
//// Write if the selected language is special
|
|
//CmsError cmsError = MEM_RWBoolean(W, 0, SPECIAL_LANGUAGE_BIT.MemType, SPECIAL_LANGUAGE_BIT.Address, SPECIAL_LANGUAGE_BIT.SubAddress, ref isSpecial);
|
|
//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(bool hasLetters, ref string MachNumber)
|
|
{
|
|
if (!hasLetters)
|
|
{
|
|
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();
|
|
}
|
|
else
|
|
{
|
|
// New method to read the machine number
|
|
List<byte> lists = new List<byte>();
|
|
CmsError cmsError = MEM_RWByteList(R, 0, NEW_MATR_MACCH.MemType, NEW_MATR_MACCH.Address, 0, 4, ref lists);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
MachNumber = Encoding.ASCII.GetString(lists.ToArray());
|
|
}
|
|
|
|
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 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;
|
|
|
|
// Set page
|
|
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 ? INCHES : MILLIMETERS;
|
|
|
|
// Read offset decimal digits
|
|
short[] input = new short[20];
|
|
short[] output = new short[20];
|
|
short nReturn = Focas1.cnc_getfigure(nLibHandle[0], 1, out short v, input, output);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
OFFSET_DECIMAL_DIGITS = input[0];
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_WMDICommand(int processId, string mdiString)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
short nReturn = Focas1.cnc_wrmdiprog(nLibHandle[processId - 1], (short)mdiString.Count(), mdiString.ToArray());
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
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, 0, ref plcWatchdog);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (plcWatchdog)
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
|
|
plcWatchdog = true;
|
|
return MEM_RWBoolean(W, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, 0, ref plcWatchdog);
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
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 PLC_WNcSoftKey(REFRESH_ALL_ALARMS_SFKEY_INDEX);
|
|
}
|
|
|
|
// 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] },
|
|
BarriersNotOk = new PowerOnDataModel() { Id = 7, Active = bits[6], Clickable = bits[22] }
|
|
};
|
|
// 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;
|
|
}
|
|
|
|
// MACHINE COUNTERS
|
|
// Get all the machine counters
|
|
public override CmsError PLC_RMachineCounters(ref List<CounterModel> counters)
|
|
{
|
|
List<uint> val = new List<uint>();
|
|
// Read ints
|
|
CmsError cmsError = MEM_RWDWordList(R, 0, COUNTERS_DATA.MemType, COUNTERS_DATA.Address, COUNTERS_DATA.Size / 4, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Set return value
|
|
uint i = 0;
|
|
counters = val.Select(x => new CounterModel()
|
|
{
|
|
Id = i++,
|
|
Value = x
|
|
})
|
|
.ToList();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WResetMachineCounters(uint counter)
|
|
{
|
|
bool isResettable = false;
|
|
CmsError cmsError = MEM_RWBoolean(R, 0, COUNTER_IS_RESETTABLE.MemType, COUNTER_IS_RESETTABLE.Address, (int)(counter - 1), ref isResettable);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (!isResettable)
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
|
|
cmsError = PLC_WStrobe(COUNTER_IS_RESETTABLE_ACK, COUNTER_IS_RESETTABLE_STROBE, counter);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
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<uint> readHours = new List<uint>();
|
|
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();
|
|
|
|
// Read Worked time heads
|
|
cmsError = MEM_RWDWordList(R, 0, HEADS_WORKED_TIMES.MemType, HEADS_WORKED_TIMES.Address, number, ref readHours);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// 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],
|
|
Param3 = BitConverter.ToInt16(readValues.ToArray(), headOffset + 2), // Uint 16 = 2byte
|
|
Param2 = BitConverter.ToInt16(readValues.ToArray(), headOffset + 4), // Uint 16 = 2byte
|
|
Param1 = 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
|
|
Configured = (readValues[headOffset + 10] & 8) != 0, // bit 3
|
|
Rotation = (readValues[headOffset + 10] & 16) == 0 ? ROTATION.CLOCKWHISE : ROTATION.COUNTERCLOCKWHISE, // bit 4
|
|
WorkedTime = readHours[i]
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RWorkedTimeHead(int head, ref uint time)
|
|
{
|
|
int index = (head - 1) * 4;
|
|
|
|
// Read Worked time
|
|
CmsError cmsError = MEM_RWDWord(R, 0, HEADS_WORKED_TIMES.MemType, HEADS_WORKED_TIMES.Address + index, ref time);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WResetWorkedTimeHead(int head)
|
|
{
|
|
byte usControlWord = 0;
|
|
|
|
if (head <= 0 || head > MAX_HEADS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Read status
|
|
CmsError cmsError = MEM_RWByte(R, 0, HEAD_RESET_WORKED_TIME.MemType, HEAD_RESET_WORKED_TIME.Address, 0, ref usControlWord);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Re-Write it status
|
|
usControlWord = Convert.ToByte((usControlWord & 0xE0) | (head & 0X1F));
|
|
cmsError = MEM_RWByte(W, 0, HEAD_RESET_WORKED_TIME.MemType, HEAD_RESET_WORKED_TIME.Address, 0, ref usControlWord);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RWorkedTimeMachine(ref uint time)
|
|
{
|
|
// Read Worked time
|
|
CmsError cmsError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, ref time);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WResetWorkedTimeMachine(uint time)
|
|
{
|
|
uint actTime = 0;
|
|
|
|
// Read actual Value
|
|
CmsError cmsError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, ref actTime);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Per richiedere l'azzeramento del timer invio 4 volte il segnale velocemente al PLC
|
|
// Il PLC resetta il bit e aspetta quello successivo entro 500ms, se no abortisce
|
|
// Sfrutto cos� la velocit� dei sw, cosa che un "nemico" a mano se provasse a forzare il bit non avrebbe
|
|
bool bitValue = true;
|
|
int nTry = 0;
|
|
|
|
for (int i = 0; i <= 4; i++)
|
|
{
|
|
//Scrivo il bit
|
|
bitValue = true;
|
|
nTry = 0;
|
|
cmsError = MEM_RWBoolean(W, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, 0, ref bitValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//Aspetto che venga abbassato
|
|
do
|
|
{
|
|
Thread.Sleep(50);
|
|
nTry += 1;
|
|
cmsError = MEM_RWBoolean(R, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, 0, ref bitValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
} while (bitValue && nTry <= 10);
|
|
|
|
//se il valore � rimasto a 1 il plc non l'ha preso in carico, e abortisco
|
|
if (bitValue)
|
|
{
|
|
bitValue = true;
|
|
cmsError = MEM_RWBoolean(W, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, 0, ref bitValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
else
|
|
{
|
|
//Se l'ha abbassato scrivo il nuovo dato
|
|
cmsError = MEM_RWDWord(W, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, ref time);
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
string[] parameters;
|
|
string actualLine = "";
|
|
|
|
for (uint processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
|
|
{
|
|
if (bits[processId - 1])
|
|
{
|
|
// Read active program line
|
|
cmsError = PROC_ReadActiveLine(processId, ref actualLine);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Parse line & get parameters
|
|
parameters = ExtractM155ParametersFromNcCodeLine(actualLine, '(', ')');
|
|
if (parameters.Count() == 0)
|
|
{
|
|
value.Add(new M155InputIsNeededModel()
|
|
{
|
|
Process = processId,
|
|
IsNeeded = bits[processId - 1],
|
|
Message = "",
|
|
Type = M155_TYPE.REAL,
|
|
Buttons = new Dictionary<byte, string>()
|
|
});
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
byte i = 1;
|
|
|
|
if (parameters[0].ToUpper().Trim() == "SHOWVAL")
|
|
{
|
|
// Skip first parameter because it's the message string
|
|
// Set button with -> id = 1..5 -> value = parameter value
|
|
Dictionary<byte, string> buttons = parameters.Skip(2)?.ToDictionary(x => i++, x => x);
|
|
|
|
// Read value from custom macro
|
|
double macroVal = 0;
|
|
ReadMacroValue((int)processId, M155_RESPONSE_MEMORY, true, ref macroVal);
|
|
|
|
value.Add(new M155InputIsNeededModel()
|
|
{
|
|
Process = processId,
|
|
IsNeeded = bits[processId - 1],
|
|
Message = parameters[1] ?? "",
|
|
Type = M155_TYPE.SHOW_VAL, // if there aren't buttons is a simple request
|
|
Value = macroVal,
|
|
Buttons = buttons
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// Skip first parameter because it's the message string
|
|
// Set button with -> id = 1..5 -> value = parameter value
|
|
Dictionary<byte, string> buttons = parameters.Skip(1)?.ToDictionary(x => i++, x => x);
|
|
|
|
value.Add(new M155InputIsNeededModel()
|
|
{
|
|
Process = processId,
|
|
IsNeeded = bits[processId - 1],
|
|
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
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WOperatorInputResponse(int processId, double responseVal)
|
|
{
|
|
CmsError cmsError = WriteMacroValue(processId, M155_RESPONSE_MEMORY, responseVal);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return PLC_WStrobe(M155_INPUT_ACK, M155_INPUT_STROBE, (uint)processId);
|
|
}
|
|
|
|
public override CmsError PLC_RM156Data(ref List<M156InputIsNeededModel> value)
|
|
{
|
|
byte val = 0;
|
|
List<byte> vals = new List<byte>();
|
|
CmsError cmsError = MEM_RWByte(R, 0, M156_INPUT_NEEDED.MemType, M156_INPUT_NEEDED.Address, 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
cmsError = MEM_RWByteList(R, 0, M156_INPUT_ID_LIST.MemType, M156_INPUT_ID_LIST.Address, 0, M156_INPUT_ID_LIST.Size, ref vals);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] bits = ByteToBits(val);
|
|
|
|
for (int processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
|
|
{
|
|
if (bits[processId - 1])
|
|
{
|
|
double responseVal = 0;
|
|
// Read machine variable Geferson 23/12/2020 si legge sempre dalla M155
|
|
cmsError =
|
|
ReadMacroValue((int)processId, M155_RESPONSE_MEMORY, true, ref responseVal);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Parse line & get parameters
|
|
value.Add(new M156InputIsNeededModel()
|
|
{
|
|
Process = (uint)processId,
|
|
Id = vals.ElementAt(processId - 1),
|
|
Value = responseVal
|
|
});
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WM156Response(int process, double responseVal)
|
|
{
|
|
CmsError cmsError = WriteMacroValue(process, M155_RESPONSE_MEMORY, responseVal);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return PLC_WStrobe(M156_INPUT_ACK, M156_INPUT_STROBE, (uint)process);
|
|
//CmsError cmsError = MEM_RWDouble(W, 0, MEMORY_TYPE.Osai_GD, 900 + (process - 1), ref responseVal);
|
|
//if (cmsError.IsError())
|
|
// return cmsError;
|
|
|
|
//return PLC_WStrobe(M156_INPUT_ACK, M156_INPUT_STROBE, (uint)process);
|
|
}
|
|
|
|
public override CmsError PLC_RM157Data(ref List<M157DataModel> value)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WM157Timer(int process, ushort timerVal)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError WriteMacroValue(int processId, int memIndex, double val)
|
|
{
|
|
int num = 1;
|
|
short nReturn = Focas1.cnc_wrmacror2(nLibHandle[processId - 1], memIndex, ref num, val);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError ReadMacroValue(int processId, int memIndex, bool isCustom, ref double val)
|
|
{
|
|
if (isCustom)
|
|
{
|
|
// Read custom machine variable
|
|
IODBMR readVal = new IODBMR()
|
|
{
|
|
datano_s = (short)memIndex,
|
|
datano_e = (short)(memIndex)
|
|
};
|
|
// Fanuc standard length
|
|
short length = 8 + 8;
|
|
short nReturn = Focas1.cnc_rdmacror(nLibHandle[processId - 1], readVal.datano_s, readVal.datano_e, length, readVal);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
val = readVal.data.data1.mcr_val * Math.Pow(10, (-1 * readVal.data.data1.dec_val));
|
|
}
|
|
else
|
|
{
|
|
// Read machine variable
|
|
ODBPM readVal = new ODBPM();
|
|
short nReturn = Focas1.cnc_rdpmacro(nLibHandle[processId - 1], memIndex, readVal);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
val = readVal.mcr_val * Math.Pow(10, (-1 * readVal.dec_val));
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RM154Data(ref List<M154DataModel> data, ref bool MTCOnOff)
|
|
{
|
|
MTCOnOff = false;
|
|
CmsError cmsError = MEM_RWBoolean(R, 0, M154_SWITCH_ONOFF.MemType, M154_SWITCH_ONOFF.Address, M154_SWITCH_ONOFF.SubAddress, ref MTCOnOff);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
byte val = 0;
|
|
cmsError = MEM_RWByte(R, 0, M154_STROBE.MemType, M154_STROBE.Address, 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Convert a byte to an array of booleans
|
|
bool[] bits = ByteToBits(val);
|
|
string[] parameters;
|
|
string tmpStr = "";
|
|
|
|
for (uint processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
|
|
{
|
|
if (bits[processId - 1])
|
|
{
|
|
// Read active program line
|
|
cmsError = PROC_ReadActiveLine(processId, ref tmpStr);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Parse parameters
|
|
parameters = ExtractM154ParametersFromNcCodeLine(tmpStr);
|
|
data.Add(new M154DataModel()
|
|
{
|
|
Process = processId,
|
|
IsNeeded = bits[processId - 1],
|
|
Parameters = parameters
|
|
});
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_W154ManageAck(int processId)
|
|
{
|
|
return PLC_ManageActiveAck(M154_STROBE.Address, processId - 1, M154_ACK.Address, processId - 1, M154_STROBE.MemType);
|
|
}
|
|
|
|
public override CmsError PLC_RScadaValue(string memIndex, SCADA_MEM_TYPE memType, ref object value)
|
|
{
|
|
if (memType == SCADA_MEM_TYPE.BOOL)
|
|
{
|
|
if (memIndex.ToUpper() == "FALSE")
|
|
{
|
|
value = false;
|
|
return NO_ERROR;
|
|
}
|
|
else if (memIndex.ToUpper() == "TRUE")
|
|
{
|
|
value = true;
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
|
|
// Split memory string
|
|
string[] index = memIndex.Split('_');
|
|
CmsError cmsError = NO_ERROR;
|
|
MEMORY_TYPE Type = MEMORY_TYPE.Fanuc_R;
|
|
|
|
if (index.Count() != 2)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
switch (index[0].ToUpper())
|
|
{
|
|
case "R": Type = MEMORY_TYPE.Fanuc_R; break;
|
|
case "D": Type = MEMORY_TYPE.Fanuc_D; break;
|
|
};
|
|
|
|
index = index[1].Split('.');
|
|
|
|
try
|
|
{
|
|
if (index.Count() == 1)
|
|
{
|
|
if (memType == SCADA_MEM_TYPE.INT)
|
|
{
|
|
// read INT
|
|
int val = 0;
|
|
cmsError = MEM_RWInteger(R, 0, Type, Convert.ToInt32(index[0]), ref val);
|
|
|
|
value = val;
|
|
}
|
|
else if (memType == SCADA_MEM_TYPE.WORD)
|
|
{ // read WORD
|
|
short val = 0;
|
|
cmsError = MEM_RWShort(R, 0, Type, Convert.ToInt32(index[0]), ref val);
|
|
|
|
value = val;
|
|
}
|
|
else
|
|
{ // read BYTE
|
|
byte val = 0;
|
|
cmsError = MEM_RWByte(R, 0, Type, Convert.ToInt32(index[0]), 0, ref val);
|
|
|
|
value = val;
|
|
}
|
|
}
|
|
else if (index.Count() == 2 && memType == SCADA_MEM_TYPE.BOOL)
|
|
{ // read BOOL
|
|
bool val = false;
|
|
cmsError = MEM_RWBoolean(R, 0, Type, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
|
|
value = val;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value)
|
|
{
|
|
string[] index = memIndex.Split('_');
|
|
MEMORY_TYPE fanucMemtype = MEMORY_TYPE.Fanuc_R;
|
|
|
|
if (index.Count() != 2)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
switch (index[0].ToUpper())
|
|
{
|
|
case "R": fanucMemtype = MEMORY_TYPE.Fanuc_R; break;
|
|
case "D": fanucMemtype = MEMORY_TYPE.Fanuc_D; break;
|
|
};
|
|
|
|
index = index[1].Split('.');
|
|
|
|
if (index.Count() == 0)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
else if (index.Count() == 1)
|
|
{
|
|
if (memType == SCADA_MEM_TYPE.INT)
|
|
{
|
|
// WRITE INT
|
|
int val = Convert.ToInt32(value);
|
|
CmsError cmsError = MEM_RWInteger(W, 0, fanucMemtype, Convert.ToInt32(index[0]), ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
else if (memType == SCADA_MEM_TYPE.WORD)
|
|
{ // WRITE WORD
|
|
short val = Convert.ToInt16(value);
|
|
CmsError cmsError = MEM_RWShort(W, 0, fanucMemtype, Convert.ToInt32(index[0]), ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
else
|
|
{ // WRITE byte
|
|
byte val = Convert.ToByte(value);
|
|
CmsError cmsError = MEM_RWByte(W, 0, fanucMemtype, Convert.ToInt32(index[0]), 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
}
|
|
else if (index.Count() == 2 && memType == SCADA_MEM_TYPE.BOOL)
|
|
{ // WRITE BOOL
|
|
bool val = Convert.ToBoolean(value);
|
|
CmsError cmsError = MEM_RWBoolean(W, 0, fanucMemtype, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
value = val;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RScadaSiemens(ref List<ScadaObjectModel> objects)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WAssistedToolingCmd(ushort toolId, ushort familyId, ushort shankId, ushort magazineId, ushort positionId, ASSISTED_TOOLING_ACTION action)
|
|
{
|
|
List<ushort> values = new List<ushort>()
|
|
{
|
|
toolId,
|
|
magazineId,
|
|
positionId,
|
|
familyId,
|
|
shankId
|
|
};
|
|
|
|
// Write data
|
|
CmsError cmsError = MEM_RWWordList(W, 1, ASSISTED_TOOLING_DATA.MemType, ASSISTED_TOOLING_DATA.Address, 3, ref values);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Write action
|
|
byte val = (byte)action;
|
|
cmsError = MEM_RWByte(W, 1, ASSISTED_TOOLING_DATA.MemType, ASSISTED_TOOLING_DATA.Address + (values.Count() * 2), 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Write strobe to start procedure
|
|
return PLC_WStrobe(PLC_ASSISTED_TOOLING_STROBE, HMI_ASSISTED_TOOLING_STROBE, (uint)HMI_ASSISTED_TOOLING_STROBE.SubAddress + 1);
|
|
}
|
|
|
|
public override CmsError PLC_RAssistedToolingData(ref AssistedToolingModel data)
|
|
{
|
|
byte procFinalValue = 0;
|
|
// Read procedure final value
|
|
CmsError cmsError = MEM_RWByte(R, 0, PLC_ASSISTED_TOOLING_STROBE.MemType, PLC_ASSISTED_TOOLING_STROBE.Address, 0, ref procFinalValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Bit:
|
|
// 0: ack 1: strobe 2: unload 3: load
|
|
// Check if the procedure is finished
|
|
if (GetBitValue(procFinalValue, 1))
|
|
{
|
|
List<ushort> values = new List<ushort>();
|
|
|
|
// Read actual data
|
|
cmsError = MEM_RWWordList(R, 1, ASSISTED_TOOLING_DATA.MemType, ASSISTED_TOOLING_DATA.Address, 3, ref values);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Set action
|
|
ASSISTED_TOOLING_ACTION action = ASSISTED_TOOLING_ACTION.NONE;
|
|
if (GetBitValue(procFinalValue, 2))
|
|
action = ASSISTED_TOOLING_ACTION.UNLOAD;
|
|
|
|
if (GetBitValue(procFinalValue, 3))
|
|
action = ASSISTED_TOOLING_ACTION.EXCHANGE;
|
|
|
|
data = new AssistedToolingModel()
|
|
{
|
|
IsActive = true,
|
|
ToolId = values[0],
|
|
MagazineId = values[1],
|
|
PositionId = values[2],
|
|
Action = action
|
|
};
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WTerminateAssistedToolingProcedure()
|
|
{
|
|
// Terminate procedure with ACK-STROBE method
|
|
CmsError cmsError = PLC_ManageActiveAck(PLC_ASSISTED_TOOLING_STROBE.Address, PLC_ASSISTED_TOOLING_STROBE.SubAddress,
|
|
HMI_ASSISTED_TOOLING_ACK.Address, HMI_ASSISTED_TOOLING_ACK.SubAddress,
|
|
PLC_ASSISTED_TOOLING_STROBE.MemType);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WExpiredCandy(bool value)
|
|
{
|
|
bool newVal = false;
|
|
|
|
//Scrivo il dato
|
|
CmsError cmsError = MEM_RWBoolean(W, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, 5, ref value);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
else
|
|
{
|
|
//Leggo il dato
|
|
cmsError = PLC_RExpiredCandy(ref newVal);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
//Se i 2 dati coincidono ritorno OK
|
|
if (value == newVal)
|
|
return NO_ERROR;
|
|
else
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
}
|
|
|
|
public override CmsError PLC_RExpiredCandy(ref bool value)
|
|
{
|
|
CmsError cmsError = MEM_RWBoolean(R, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, 5, ref value);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WCandy(long value)
|
|
{
|
|
// Long is formed by a integer + word
|
|
// Write Word
|
|
ushort word = (ushort)((value & 0xFFFF));
|
|
CmsError cmsError = MEM_RWWord(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, ref word);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
int integer = (int)((value & 0xFFFFFFFF0000) >> 16);
|
|
// Write Integer (+1 is used because osai uses word)
|
|
cmsError = MEM_RWInteger(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address + 2, ref integer);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Rieggo il dato
|
|
long newVal = 0;
|
|
cmsError = PLC_RCandy(ref newVal);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Se i 2 dati coincidono ritorno OK
|
|
if (value == newVal)
|
|
return NO_ERROR;
|
|
else
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RCandy(ref long value)
|
|
{
|
|
// Long is formed by a integer + word
|
|
|
|
// Read first int
|
|
uint firtInt = (uint)value;
|
|
CmsError cmsError = MEM_RWDWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, ref firtInt);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Read word
|
|
ushort word = 0;
|
|
cmsError = MEM_RWWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address + 4, ref word);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Build Long value
|
|
value = ((long)word << 32) + firtInt;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RActiveClient(ref int clientId)
|
|
{
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
byte readValues = 0;
|
|
cmsError = MEM_RWByte(R, 0, ACTIVE_CLIENT.MemType, ACTIVE_CLIENT.Address, 0, ref readValues);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Convert integer array into bit array
|
|
bool[] statusBits = ByteToBits(readValues);
|
|
// check which bit is set
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if (statusBits[i])
|
|
clientId = i + 1;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RToolMovement(ref MovementBetweenMagazinesModel toolMovement)
|
|
{
|
|
List<ushort> values = new List<ushort>();
|
|
CmsError cmsError = MEM_RWWordList(R, 0, TOOL_MOVEMENT_AREA.MemType, TOOL_MOVEMENT_AREA.Address, TOOL_MOVEMENT_AREA.Size / 2, ref values);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (GetBitValue(values[0], 8))
|
|
{
|
|
byte[] bytes = NumberToByte(values[1]);
|
|
toolMovement = new MovementBetweenMagazinesModel()
|
|
{
|
|
OldMagazineId = bytes[0],
|
|
NewMagazineId = bytes[1],
|
|
OldPositionId = values[2],
|
|
NewPositionId = values[3],
|
|
Action = (MOVEMENT_TYPE)BitConverter.GetBytes(values[5])[0]
|
|
};
|
|
|
|
return PLC_ManageActiveAck(TOOL_MOVEMENT_AREA.Address + 1, 0, TOOL_MOVEMENT_AREA.Address, 0, TOOL_MOVEMENT_AREA.MemType);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WTerminateMovementProcedure(MOVEMENT_RESPONSE resp)
|
|
{
|
|
byte val = (byte)resp;
|
|
CmsError cmsError = MEM_RWByte(W, 0, TOOL_MOVEMENT_HMI_RESPONSE.MemType, TOOL_MOVEMENT_HMI_RESPONSE.Address, 0, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return PLC_WStrobe(TOOL_MOVEMENT_AREA, TOOL_MOVEMENT_STROBE_END, 2);
|
|
}
|
|
|
|
#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)
|
|
{
|
|
Boolean Cut = false;
|
|
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;
|
|
|
|
//Read CUT variable
|
|
byte CutRaw = 0;
|
|
int address = (1000 * (procNumber - 1)) + 2;
|
|
cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Fanuc_F, address, 0, ref CutRaw);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Cut = (CutRaw & 0x40) == 0x40;
|
|
|
|
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];
|
|
processData.CanLoadProgram = bits[4];
|
|
processData.IsInPieceWork = Cut;
|
|
|
|
// 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;
|
|
}
|
|
|
|
// 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;
|
|
|
|
char[] tmp = new char[244];
|
|
nReturn = Focas1.cnc_pdf_rdmain(nLibHandle[path], tmp);
|
|
|
|
name = new string(tmp);
|
|
|
|
//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(tmp).Replace("\0", string.Empty);
|
|
|
|
name = Path.GetFileName(name);
|
|
|
|
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);
|
|
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 < MAX_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);
|
|
}
|
|
|
|
if (procNumber == 0)
|
|
return SELECTED_PROCESS_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PROC_WSelectProcess(ushort procNumber)
|
|
{
|
|
CmsError cmsError;
|
|
byte processNum = (byte)procNumber;
|
|
|
|
// Check parameter
|
|
if (processNum > MAX_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);
|
|
ushort length = 200;
|
|
char[] text = new char[201];
|
|
short nReturn = Focas1.cnc_rdexecprog(nLibHandle[(int)processId - 1], ref length, out short block, text);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
string lines = new string(text.Take(length).ToArray());
|
|
|
|
if (!string.IsNullOrEmpty(lines))
|
|
line = lines.Split('\n').FirstOrDefault();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PROC_RSelectedProcessData(int processId, ref SelectedProcessData processData)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (processId <= 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
short number = 1;
|
|
ODBGCD odb = new ODBGCD();
|
|
|
|
// Read active origin
|
|
short nReturn = Focas1.cnc_rdgcode(nLibHandle[processId - 1], 13, 1, ref number, odb);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
short origin = 0;
|
|
short offsetId = 0;
|
|
if (odb.gcd0.code != "")
|
|
// Convert fanuc string "G(N)" into a int
|
|
origin = Convert.ToInt16(odb.gcd0.code.TrimStart('G'));
|
|
|
|
// Read if there is an active offset
|
|
nReturn = Focas1.cnc_rdgcode(nLibHandle[processId - 1], 7, 1, ref number, odb);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
// If G != G49 there is a active offset
|
|
if (!odb.gcd0.code.Contains("49"))
|
|
{
|
|
double macroVal = 0;
|
|
// Read offset id
|
|
ReadMacroValue(processId, 4111, false, ref macroVal);
|
|
offsetId = (short)macroVal;
|
|
}
|
|
|
|
// Read operator's message #3006 & #3017
|
|
Focas1.OPMSG3 Messg = new Focas1.OPMSG3();
|
|
short count = FANUC_MAXMSGPMC;
|
|
|
|
// Execute the method
|
|
nReturn = Focas1.cnc_rdopmsg3(nLibHandle[0], -1, ref count, Messg);
|
|
|
|
// Check return value
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
string msg = "";
|
|
// Check if message exist & if is an operator type (type == 4)
|
|
if (count >= 5 && Messg.msg5.datano >= 0 && Messg.msg5.type == 4)
|
|
msg = Messg.msg5.data;
|
|
|
|
OffsetModel offsetData = new OffsetModel();
|
|
if (offsetId != 0)
|
|
// Read offset data
|
|
cmsError = TOOLS_ROffset(offsetId, ref offsetData);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
byte rapid = 0, work = 0;
|
|
|
|
// Choose & read work override // jogIsActive ? (processId - 1) * 1000 + 10 :
|
|
int mem = (processId - 1) * 1000 + 12;
|
|
cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Fanuc_G, mem, 0, ref work);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (work != 0)
|
|
work = (byte)(((work - 256) + 1) * -1);
|
|
|
|
// Read rapid
|
|
cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Fanuc_G, 96, 0, ref rapid);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (rapid != 0)
|
|
rapid = (byte)(((rapid - 256) + 1) * -1);
|
|
|
|
ODBACT feed = new ODBACT();
|
|
nReturn = Focas1.cnc_actf(nLibHandle[0], feed);
|
|
// Check return value
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
processData = new SelectedProcessData()
|
|
{
|
|
ActiveOffsetId = offsetId,
|
|
Origin = origin,
|
|
ProcessMessage = msg,
|
|
OffsetData = offsetData,
|
|
RapidOverride = rapid,
|
|
WorkOverride = work,
|
|
FeedOverride = (double)feed.data / 10
|
|
};
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
public override CmsError PROC_RFeed(ushort ProcNumber, ref float Feed)
|
|
{
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (ProcNumber <= 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
|
|
ODBACT feedRaw = new ODBACT();
|
|
short nReturn = Focas1.cnc_actf(nLibHandle[ProcNumber - 1], feedRaw);
|
|
// Check return value
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
Feed = feedRaw.data / 10.0f;
|
|
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);
|
|
|
|
short[] types = new short[] { 0, 1, 2, 3 };
|
|
|
|
ODBAXDT axisData = new ODBAXDT();
|
|
nReturn = Focas1.cnc_rdaxisdata(nLibHandle[process - 1], 1, types, 4, ref numAxesRead, axisData);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Parse data
|
|
if (numAxesRead >= 1)
|
|
axesData.Add(new AxisModel() { Id = 1, Name = sOdbExAxisName.axname1, IsSelectable = false, Type = axisData.data1.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 2)
|
|
axesData.Add(new AxisModel() { Id = 2, Name = sOdbExAxisName.axname2, IsSelectable = false, Type = axisData.data2.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 3)
|
|
axesData.Add(new AxisModel() { Id = 3, Name = sOdbExAxisName.axname3, IsSelectable = false, Type = axisData.data3.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 4)
|
|
axesData.Add(new AxisModel() { Id = 4, Name = sOdbExAxisName.axname4, IsSelectable = false, Type = axisData.data4.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 5)
|
|
axesData.Add(new AxisModel() { Id = 5, Name = sOdbExAxisName.axname5, IsSelectable = false, Type = axisData.data5.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 6)
|
|
axesData.Add(new AxisModel() { Id = 6, Name = sOdbExAxisName.axname6, IsSelectable = false, Type = axisData.data6.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 7)
|
|
axesData.Add(new AxisModel() { Id = 7, Name = sOdbExAxisName.axname7, IsSelectable = false, Type = axisData.data7.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 8)
|
|
axesData.Add(new AxisModel() { Id = 8, Name = sOdbExAxisName.axname8, IsSelectable = false, Type = axisData.data8.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 9)
|
|
axesData.Add(new AxisModel() { Id = 9, Name = sOdbExAxisName.axname9, IsSelectable = false, Type = axisData.data9.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 10)
|
|
axesData.Add(new AxisModel() { Id = 10, Name = sOdbExAxisName.axname10, IsSelectable = false, Type = axisData.data10.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 11)
|
|
axesData.Add(new AxisModel() { Id = 11, Name = sOdbExAxisName.axname11, IsSelectable = false, Type = axisData.data11.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 12)
|
|
axesData.Add(new AxisModel() { Id = 12, Name = sOdbExAxisName.axname12, IsSelectable = false, Type = axisData.data12.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 13)
|
|
axesData.Add(new AxisModel() { Id = 13, Name = sOdbExAxisName.axname13, IsSelectable = false, Type = axisData.data13.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 14)
|
|
axesData.Add(new AxisModel() { Id = 14, Name = sOdbExAxisName.axname14, IsSelectable = false, Type = axisData.data14.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 15)
|
|
axesData.Add(new AxisModel() { Id = 15, Name = sOdbExAxisName.axname15, IsSelectable = false, Type = axisData.data15.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 16)
|
|
axesData.Add(new AxisModel() { Id = 16, Name = sOdbExAxisName.axname16, IsSelectable = false, Type = axisData.data16.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 17)
|
|
axesData.Add(new AxisModel() { Id = 17, Name = sOdbExAxisName.axname17, IsSelectable = false, Type = axisData.data17.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 18)
|
|
axesData.Add(new AxisModel() { Id = 18, Name = sOdbExAxisName.axname18, IsSelectable = false, Type = axisData.data18.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 19)
|
|
axesData.Add(new AxisModel() { Id = 19, Name = sOdbExAxisName.axname19, IsSelectable = false, Type = axisData.data19.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 20)
|
|
axesData.Add(new AxisModel() { Id = 20, Name = sOdbExAxisName.axname20, IsSelectable = false, Type = axisData.data20.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 21)
|
|
axesData.Add(new AxisModel() { Id = 21, Name = sOdbExAxisName.axname21, IsSelectable = false, Type = axisData.data21.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 22)
|
|
axesData.Add(new AxisModel() { Id = 22, Name = sOdbExAxisName.axname22, IsSelectable = false, Type = axisData.data22.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 23)
|
|
axesData.Add(new AxisModel() { Id = 23, Name = sOdbExAxisName.axname23, IsSelectable = false, Type = axisData.data23.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 24)
|
|
axesData.Add(new AxisModel() { Id = 24, Name = sOdbExAxisName.axname24, IsSelectable = false, Type = axisData.data24.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 25)
|
|
axesData.Add(new AxisModel() { Id = 25, Name = sOdbExAxisName.axname25, IsSelectable = false, Type = axisData.data25.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 26)
|
|
axesData.Add(new AxisModel() { Id = 26, Name = sOdbExAxisName.axname26, IsSelectable = false, Type = axisData.data26.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 27)
|
|
axesData.Add(new AxisModel() { Id = 27, Name = sOdbExAxisName.axname27, IsSelectable = false, Type = axisData.data27.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 28)
|
|
axesData.Add(new AxisModel() { Id = 28, Name = sOdbExAxisName.axname28, IsSelectable = false, Type = axisData.data28.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 29)
|
|
axesData.Add(new AxisModel() { Id = 29, Name = sOdbExAxisName.axname29, IsSelectable = false, Type = axisData.data29.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 30)
|
|
axesData.Add(new AxisModel() { Id = 30, Name = sOdbExAxisName.axname30, IsSelectable = false, Type = axisData.data30.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 31)
|
|
axesData.Add(new AxisModel() { Id = 31, Name = sOdbExAxisName.axname31, IsSelectable = false, Type = axisData.data31.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
if (numAxesRead >= 32)
|
|
axesData.Add(new AxisModel() { Id = 32, Name = sOdbExAxisName.axname32, IsSelectable = false, Type = axisData.data32.unit == 2 ? AXIS_TYPE.ROTATING : AXIS_TYPE.LINEAR });
|
|
|
|
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;
|
|
|
|
// Remove not visible axes
|
|
axesData = axesData.Where(x => ids.Contains((byte)x.Id)).ToList();
|
|
|
|
// Set to true (old compatibility)
|
|
foreach (var axis in axesData)
|
|
{
|
|
axis.IsSelectable = true;
|
|
}
|
|
|
|
//// 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;
|
|
}
|
|
|
|
public override CmsError AXES_ROrigin(int numberOfAxes)
|
|
{
|
|
double d = 0;
|
|
uint G55Index = 5241;
|
|
int G56Index = 5261;
|
|
int G57Index = 5281;
|
|
int G58Index = 5301;
|
|
int G59Index = 5321;
|
|
|
|
List<AxisModel> axesNames = new List<AxisModel>();
|
|
CmsError cmsError = AXES_RAxesNames(1, ref axesNames);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
Dictionary<string, double> axesNamesDict;
|
|
|
|
axesNamesDict = axesNames.ToDictionary(x => x.Id.ToString(), x => (double)0);
|
|
|
|
Dictionary<string, Dictionary<string, double>> value
|
|
= new Dictionary<string, Dictionary<string, double>>();
|
|
|
|
value.Add("G54", axesNamesDict);
|
|
|
|
for (int i = (int)G55Index; i < G55Index + numberOfAxes; i++)
|
|
{
|
|
var id = i - G55Index + 1;
|
|
ReadMacroValue(1, i, false, ref d);
|
|
|
|
value["G54"][id.ToString()] = d;
|
|
}
|
|
|
|
for (int i = (int)G55Index; i < G55Index + numberOfAxes; i++)
|
|
ReadMacroValue(1, i, false, ref d);
|
|
|
|
for (int i = G56Index; i < G56Index + numberOfAxes; i++)
|
|
ReadMacroValue(1, i, false, ref d);
|
|
|
|
for (int i = G57Index; i < G57Index + numberOfAxes; i++)
|
|
ReadMacroValue(1, i, false, ref d);
|
|
|
|
for (int i = G58Index; i < G58Index + numberOfAxes; i++)
|
|
ReadMacroValue(1, i, false, ref d);
|
|
|
|
for (int i = G59Index; i < G59Index + numberOfAxes; i++)
|
|
ReadMacroValue(1, i, false, ref d);
|
|
|
|
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;
|
|
}
|
|
|
|
public override CmsError MEM_RWDouble(bool bWrite, int process, MEMORY_TYPE memType, int memIndex, ref double value)
|
|
{
|
|
//List<ushort> ListValue = new List<ushort>() { value };
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWDouble(bool bWrite, int process, MEMORY_TYPE memType, int memTable, int memIndex, ref double value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_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);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
string absolutePath = FormatPathForNc(path, baseDir.drive1);
|
|
|
|
ODBPDFNFIL dataNum = new ODBPDFNFIL
|
|
{
|
|
file_num = 0,
|
|
dir_num = 0
|
|
};
|
|
// Get the number of the directories and of files
|
|
nReturn = Focas1.cnc_rdpdf_subdirn(nLibHandle[0], absolutePath, dataNum);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
short maxFiles = 1;
|
|
// Check if there are directories
|
|
if (dataNum.dir_num > 0)
|
|
{
|
|
IDBPDFSDIR funcInput = new IDBPDFSDIR();
|
|
ODBPDFSDIR dirData = new ODBPDFSDIR();
|
|
|
|
for (short i = 0; i < dataNum.dir_num; i++)
|
|
{
|
|
dirData.dummy = 0;
|
|
funcInput.path = absolutePath;
|
|
funcInput.req_num = i;
|
|
|
|
// Read directory data
|
|
nReturn = Focas1.cnc_rdpdf_subdir(nLibHandle[0], ref maxFiles, funcInput, dirData);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Add directory to list
|
|
files.Add(new PreviewFileModel()
|
|
{
|
|
AbsolutePath = FormatAbsolutePathForHighLevel(absolutePath + dirData.d_f, true),
|
|
IsDirectory = true,
|
|
Name = dirData.d_f,
|
|
Path = FormatPathFroHighLevel(path, dirData.d_f)
|
|
});
|
|
}
|
|
}
|
|
|
|
// Check if there are files
|
|
if (dataNum.file_num > 0)
|
|
{
|
|
IDBPDFADIR funcInput = new IDBPDFADIR();
|
|
ODBPDFADIR fileData = new ODBPDFADIR();
|
|
|
|
// Setup input data
|
|
funcInput.path = absolutePath;
|
|
funcInput.type = 1;
|
|
funcInput.size_kind = 1;
|
|
|
|
for (short i = 0; i < dataNum.file_num; i++)
|
|
{
|
|
funcInput.req_num = (short)(dataNum.dir_num + i); // Update file index
|
|
// Read file data
|
|
nReturn = Focas1.cnc_rdpdf_alldir(nLibHandle[0], ref maxFiles, funcInput, fileData);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Add file to list
|
|
files.Add(new PreviewFileModel()
|
|
{
|
|
AbsolutePath = FormatAbsolutePathForHighLevel(absolutePath + fileData.d_f, false),
|
|
IsDirectory = false,
|
|
Name = fileData.d_f,
|
|
Path = FormatPathFroHighLevel(path, fileData.d_f)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
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);
|
|
|
|
cmsError = FILES_RActiveProgramData(processId, ref data);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
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, ex);
|
|
}
|
|
|
|
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, ex);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public override CmsError FILES_WCleanUploadFolder()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WUploadCustomMainProgramAndActivate(int processId, string customPartProgramContent, ref ActiveProgramDataModel activeData)
|
|
{
|
|
// Check if the NC is connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
try
|
|
{
|
|
string tmpM198FilePath = string.Format(NC_SUPPORT_FILE_PATH + CUSTOM_MAIN_PROGRAM, processId);
|
|
|
|
string fileName = string.Format(M198_FILE_NAME, processId);
|
|
|
|
string updatedProgramContent = customPartProgramContent;
|
|
Regex regex = new Regex(@"\<(.*?)\>");
|
|
Match m = regex.Match(customPartProgramContent);
|
|
if (m.Success)
|
|
{
|
|
updatedProgramContent = regex.Replace(customPartProgramContent, "<" + fileName + ">");
|
|
}
|
|
|
|
// Create new file
|
|
cmsError = WritePPInCmsFolder(NC_SUPPORT_FILE_PATH, updatedProgramContent);
|
|
if (cmsError.IsError())
|
|
return WRONG_CMS_PP_ERROR;
|
|
|
|
// 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;
|
|
}
|
|
|
|
private string FormatPathForNc(string path, string drive)
|
|
{
|
|
if (path == "\\\\")
|
|
return NC_PROGRAM_PATH;
|
|
|
|
if (path.Contains("\\"))
|
|
return NC_PROGRAM_PATH + path.TrimStart('\\') + "/";
|
|
|
|
return path;
|
|
}
|
|
|
|
private string FormatAbsolutePathForHighLevel(string path, bool isFolder)
|
|
{
|
|
string tmp = path.Replace('\\', '/');
|
|
|
|
if (isFolder)
|
|
tmp = tmp + "/";
|
|
|
|
return tmp;
|
|
}
|
|
|
|
private string FormatPathFroHighLevel(string path, string fileName)
|
|
{
|
|
if (path == "\\\\")
|
|
return path + fileName;
|
|
|
|
return path + "/" + fileName;
|
|
}
|
|
|
|
#endregion File Management
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region Siemens Tools Management
|
|
|
|
public override CmsError TOOLS_RConfiguration(ref ToolTableConfiguration config)
|
|
{
|
|
// Check if the NC is connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// 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_FANUC_OSAI;
|
|
|
|
// Set options
|
|
config.RadiusMetricType = false;
|
|
|
|
// Set fields configurations
|
|
config.ToolsConfiguration = NcToolFieldsConfig;
|
|
config.FamiliesConfiguration = NcFamilyFieldsConfig;
|
|
config.ShanksConfiguration = NcShankFieldsConfig;
|
|
config.MagazinePosConfiguration = NcMagazinePosFieldsConfig;
|
|
config.EdgesConfiguration = NcOffsetFieldsConfiguration;
|
|
config.MagPositionOptionActive = true;
|
|
|
|
// Read max offset number
|
|
ODBTLINF2 off = new ODBTLINF2();
|
|
short nReturn = Focas1.cnc_rdtofsinfo2(nLibHandle[0], off);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
// Set max offsets number
|
|
config.MaxOffsets = off.use_no;
|
|
|
|
// Setup magazine list
|
|
List<NcMagazineConfigModel> conf = new List<NcMagazineConfigModel>();
|
|
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 = x.Type != NC_MAGAZINE_TYPE.MAGAZINE_TOOL_BUFFER,
|
|
MaxPositions = x.MaxPositions,
|
|
AssistedToolingIsActive = false
|
|
}).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,
|
|
DestinationMagazine = wordList[2],
|
|
DestinationPosition = wordList[3],
|
|
OriginMagazine = wordList[4],
|
|
OriginPosition = wordList[5],
|
|
};
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStartTDILoading(ushort magazineId, ushort positionId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStartTDIUnloading(ushort magazineId, ushort positionId, ushort toolId)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WEmptyBallufTablet(SiemensToolModel tool)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WEmptyBallufTabletAdditionalData(SiemensToolModel tool)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAbortBallufTablet()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WClearBallufTablet(ushort magazineId, ushort positionId, ushort toolId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_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)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (offsetId > MAX_OFFSET_NUM)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
cmsError = GetOffsetMisureAndDivider(out string unitOfmeasure, out double divider);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
offset = new OffsetModel()
|
|
{
|
|
Id = offsetId,
|
|
UnitOfMeasure = unitOfmeasure
|
|
};
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
offset.RealLength = Math.Round(offset.Length + offset.WearLength, 5);
|
|
offset.RealRadius = Math.Round(offset.Radius + offset.WearRadius, 5);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WOffset(short offsetId, ref OffsetModel offset)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (offsetId > MAX_OFFSET_NUM)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Read unit of measure
|
|
cmsError = GetOffsetMisureAndDivider(out string unitOfmeasure, out double divider);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
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;
|
|
}
|
|
|
|
// If unit of measure is different
|
|
if (unitOfmeasure != offset.UnitOfMeasure)
|
|
{
|
|
if (offset.UnitOfMeasure == INCHES)
|
|
val = val * INCHES_CONST; // Convert INCHES to MM
|
|
else
|
|
val = val / INCHES_CONST; // Convert MM to INCHES
|
|
}
|
|
|
|
// 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);
|
|
|
|
offset.RealLength = Math.Round(offset.Length + offset.WearLength, 5);
|
|
offset.RealRadius = Math.Round(offset.Radius + offset.WearRadius, 5);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError GetOffsetMisureAndDivider(out string unitOfMeasure, out double divider)
|
|
{
|
|
divider = 1;
|
|
unitOfMeasure = MILLIMETERS;
|
|
// Read unit o measure
|
|
CmsError cmsError = NC_RUnitOfMeasure(ref unitOfMeasure);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (unitOfMeasure == INCHES)
|
|
divider = 25.4;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError GetOffsetDivider(string unitOfMeasure, out double divider)
|
|
{
|
|
divider = 1;
|
|
if (unitOfMeasure == INCHES)
|
|
divider = 25.4;
|
|
|
|
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);
|
|
cmsError = MEM_RWIntegerList(W, 0, FAMILY_TABLE_INDEX.MemType, FAMILY_TABLE_INDEX.Address, newMemoryValues.Count(), ref newMemoryValues);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
// Create the added new values
|
|
List<int> newMemoryValuesExtra = Extract_Additional_Parameter(familyList, "_PresettingDelta");
|
|
cmsError = MEM_RWIntegerList(W, 0, FAMILY_TABLE_INDEX_EXTRA_01.MemType, FAMILY_TABLE_INDEX_EXTRA_01.Address, newMemoryValuesExtra.Count(), ref newMemoryValuesExtra);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
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, ref Dictionary<int, ushort> updatedPresetting, ref Dictionary<int, ushort> updatedDressing)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError cmsError = CheckConnection();
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
updatedStatus = new Dictionary<int, byte>();
|
|
updatedLives = new Dictionary<int, uint>();
|
|
updatedPresetting = new Dictionary<int, ushort>();
|
|
updatedDressing = new Dictionary<int, ushort>();
|
|
|
|
// 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_ACK.Address;
|
|
}
|
|
|
|
// Manage ack and strobe
|
|
bitIndex = bitIndex % 16;
|
|
cmsError = PLC_ManageActiveAck(strobeByteIndex, bitIndex, ackByteIndex, bitIndex, MEMORY_TYPE.Fanuc_R);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RStoredData(ref List<NcToolModel> tools, ref List<NcFamilyModel> families, ref List<NcShankModel> shanks)
|
|
{
|
|
List<int> readInt = new List<int>();
|
|
CmsError cmsError = MEM_RWIntegerList(R, 0, FAMILY_TABLE_INDEX.MemType, FAMILY_TABLE_INDEX.Address, FAMILY_TABLE_INDEX.Size / 4, ref readInt);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Test
|
|
FromMemoryToModels(readInt, out families);
|
|
|
|
readInt = new List<int>();
|
|
cmsError = MEM_RWIntegerList(R, 0, FAMILY_TABLE_INDEX_EXTRA_01.MemType, FAMILY_TABLE_INDEX_EXTRA_01.Address, FAMILY_TABLE_INDEX_EXTRA_01.Size / 4, ref readInt);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
//Carico dati aggiuntivi
|
|
Load_Additional_Parameter(readInt, ref families);
|
|
|
|
readInt = new List<int>();
|
|
cmsError = MEM_RWIntegerList(R, 0, TOOL_TABLE_INDEX.MemType, TOOL_TABLE_INDEX.Address, TOOL_TABLE_INDEX.Size / 4, ref readInt);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Test
|
|
FromMemoryToModels(readInt, out tools);
|
|
|
|
readInt = new List<int>();
|
|
cmsError = MEM_RWIntegerList(R, 0, SHANK_TABLE_INDEX.MemType, SHANK_TABLE_INDEX.Address, SHANK_TABLE_INDEX.Size / 4, ref readInt);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Test
|
|
FromMemoryToModels(readInt, out shanks);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private void FromMemoryToModels<T>(List<int> ints, out List<T> models)
|
|
{
|
|
models = new List<T>();
|
|
|
|
PropertyInfo[] properties = typeof(T).GetProperties();
|
|
List<byte> byteValues = IntsToBytes(ints);
|
|
|
|
// Index of the
|
|
int objIndex = 0;
|
|
int propertyStartIndex = 0;
|
|
int propertyIndex = 0;
|
|
// Start from the begin of the table
|
|
for (int memoryIndex = 0; memoryIndex < byteValues.Count();)
|
|
{
|
|
// Get the size of the property
|
|
int size = Marshal.SizeOf(properties[propertyIndex].PropertyType);
|
|
|
|
string propertyName = properties[propertyIndex].Name;
|
|
if ((propertyName + "").StartsWith("_"))
|
|
{
|
|
if (propertyName == "_PresettingDelta")
|
|
{
|
|
//properties[propertyIndex].SetValue(models[objIndex],byteValues[memoryIndex]);
|
|
//memoryIndex += 2;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Choose action based on the size
|
|
switch (size)
|
|
{
|
|
case 1:
|
|
{
|
|
properties[propertyIndex].SetValue(models[objIndex], byteValues[memoryIndex]);
|
|
memoryIndex += 1;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
{
|
|
short u = BitConverter.ToInt16(new byte[2] { byteValues[memoryIndex], byteValues[memoryIndex + 1] }, 0);
|
|
|
|
bool skipAssignment = false;
|
|
// If indexes are pointing to the ID range
|
|
if (propertyIndex == 0)
|
|
{
|
|
// Check if id = 0, if not create new object
|
|
if (byteValues[memoryIndex] != 0)
|
|
{
|
|
// Create TMP item with generic type declaration
|
|
models.Add((T)Activator.CreateInstance(typeof(T)));
|
|
// Update object index
|
|
objIndex = models.Count() - 1;
|
|
}
|
|
else
|
|
{
|
|
// If i've found the first id = 0, stop creating items and skip to the next property
|
|
// I've read all the ids, skip to the next property
|
|
memoryIndex = propertyStartIndex = TOOL_OFFSET * size;
|
|
propertyIndex = 1;
|
|
|
|
// Restart object
|
|
objIndex = -1;
|
|
// Skip assignment
|
|
skipAssignment = true;
|
|
}
|
|
}
|
|
|
|
if (!skipAssignment)
|
|
{
|
|
// Check if property is unsigned or not
|
|
if (properties[propertyIndex].PropertyType == typeof(ushort))
|
|
properties[propertyIndex].SetValue(models[objIndex], (ushort)u);
|
|
else
|
|
properties[propertyIndex].SetValue(models[objIndex], u);
|
|
|
|
memoryIndex += 2;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
{
|
|
int i = BitConverter.ToInt32(new byte[4] { byteValues[memoryIndex], byteValues[memoryIndex + 1], byteValues[memoryIndex + 2], byteValues[memoryIndex + 3], }, 0);
|
|
|
|
// Check if property is unsigned or not
|
|
if (properties[propertyIndex].PropertyType == typeof(uint))
|
|
properties[propertyIndex].SetValue(models[objIndex], (uint)i);
|
|
else
|
|
properties[propertyIndex].SetValue(models[objIndex], i);
|
|
|
|
memoryIndex += 4;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (models.Count() == 0)
|
|
{
|
|
// If memory is empty, force exit
|
|
memoryIndex = byteValues.Count();
|
|
}
|
|
// Check if there is another object
|
|
else if (objIndex + 1 >= models.Count())
|
|
{
|
|
objIndex = 0;
|
|
// check if there is another property
|
|
if (propertyIndex + 1 >= properties.Count())
|
|
// if not, i wrote all the object's properties so exit from loop
|
|
memoryIndex = byteValues.Count();
|
|
else
|
|
{
|
|
// Wait until memoryIndex is in ID range
|
|
if (propertyIndex != 0)
|
|
{
|
|
propertyStartIndex += size * TOOL_OFFSET;
|
|
memoryIndex = propertyStartIndex;
|
|
propertyIndex += 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
objIndex++;
|
|
}
|
|
}
|
|
|
|
private void Load_Additional_Parameter(List<int> ints, ref List<NcFamilyModel> families)
|
|
{
|
|
List<byte> byteValues = IntsToBytes(ints);
|
|
int i = 0;
|
|
for (int memoryIndex = 0; memoryIndex < byteValues.Count(); memoryIndex += 2, i++)
|
|
{
|
|
ushort u = (ushort)BitConverter.ToInt16(new byte[2] { byteValues[memoryIndex], byteValues[memoryIndex + 1] }, 0);
|
|
families[i]._PresettingDelta = Convert.ToUInt16(u);
|
|
}
|
|
}
|
|
|
|
private List<int> Extract_Additional_Parameter(List<NcFamilyModel> families, string propertyName)
|
|
{
|
|
byte[] values = new byte[FAMILY_TABLE_INDEX_EXTRA_01.Size];
|
|
int i = 0;
|
|
foreach (NcFamilyModel familyParameter in families)
|
|
{
|
|
ushort u = Convert.ToUInt16(familyParameter._PresettingDelta);
|
|
// Split ushort into 2 bytes
|
|
byte[] bytesVal = NumberToByte(u);
|
|
values[i] = bytesVal[0];
|
|
values[i + 1] = bytesVal[1];
|
|
i += 2;
|
|
}
|
|
return ListOfByteToListOf<int>(values, BitConverter.ToInt32);
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineBlock(ref List<int> ids)
|
|
{
|
|
ids = new List<int>();
|
|
int val = 0;
|
|
CmsError cmsError = MEM_RWInteger(R, 0, MAGAZINES_TOOLING_CMD.MemType, MAGAZINES_TOOLING_CMD.Address, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool[] values = IntToBits(val);
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
if (values[i])
|
|
ids.Add(i);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WFreeMagazines()
|
|
{
|
|
int val = 0;
|
|
CmsError cmsError = MEM_RWInteger(W, 0, MAGAZINES_TOOLING_CMD.MemType, MAGAZINES_TOOLING_CMD.Address, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
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;
|
|
string propertyName = property.Name;
|
|
if ((propertyName + "").StartsWith("_") || propertyName == "ResidualPresetting")
|
|
{
|
|
if (propertyName == "_PresettingDelta" || propertyName == "ResidualPresetting")
|
|
{
|
|
//properties[propertyIndex].SetValue(models[objIndex],byteValues[memoryIndex]);
|
|
//memoryIndex += 2;
|
|
//continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 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;
|
|
}
|
|
|
|
public override CmsError TOOLS_RAdatpivePathStep(ref Byte step)
|
|
{
|
|
// Check ACK
|
|
CmsError cmsError = MEM_RWByte(R, 0, SELF_ADAPTIVE_PATH.MemType, SELF_ADAPTIVE_PATH.Address, 0, ref step);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAdatpivePathStep(Byte step)
|
|
{
|
|
// Check ACK
|
|
CmsError cmsError = MEM_RWByte(W, 0, SELF_ADAPTIVE_PATH.MemType, SELF_ADAPTIVE_PATH.Address, 0, ref step);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#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;
|
|
}
|
|
|
|
private CmsError PLC_ManageActiveAck(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 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_Graph: return Focas1.page_code.GRAPH;
|
|
case SCREEN_PAGE.Fanuc_MGI: return Focas1.page_code.C_EXECUTOR_C;
|
|
case SCREEN_PAGE.Fanuc_Custom2: return Focas1.page_code.TMAC2;
|
|
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, out bool isSpecial)
|
|
{
|
|
isSpecial = false;
|
|
switch (language.TwoLetterISOLanguageName)
|
|
{
|
|
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:
|
|
{
|
|
isSpecial = true;
|
|
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 nReturn = 0;
|
|
string serialNumber = "";
|
|
|
|
//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;
|
|
|
|
Focas1.ODBSYS node = new Focas1.ODBSYS();
|
|
// Execute the method
|
|
nReturn = Focas1.cnc_sysinfo(nLibHandle[0], node);
|
|
if (nReturn != 0)
|
|
return GetNcError(nReturn);
|
|
|
|
// Read serial number
|
|
cmsError = ReadSerialNumber(ref serialNumber);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Setup the name
|
|
Cnc_name = GetName(node.cnc_type, node.addinfo);
|
|
|
|
// Setup the Software version
|
|
Cnc_SftVersion = new string(node.version);
|
|
|
|
//Setup the Number Series
|
|
Cnc_SeriesNum = serialNumber;
|
|
|
|
Last_Static_Read = DateTime.Now;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private CmsError ReadSerialNumber(ref string serialNum)
|
|
{
|
|
string partProgramPath = "";
|
|
string partProgramContent = "";
|
|
bool fileEnded = false;
|
|
int lenght = 256;
|
|
|
|
// Start read process
|
|
short nReturn = Focas1.cnc_upstart4(nLibHandle[0], 8, partProgramPath); // 2 parameter = 8, means read maintenance FILE
|
|
// 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]);
|
|
|
|
var lines = partProgramContent
|
|
.Split('\n');
|
|
|
|
var line = lines
|
|
.Where(x => x.IndexOf("serial", StringComparison.OrdinalIgnoreCase) >= 0)
|
|
.FirstOrDefault();
|
|
|
|
if (line == null)
|
|
return NO_ERROR;
|
|
|
|
serialNum = line.Split(':')[1];
|
|
|
|
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, int model)
|
|
{
|
|
string name = "Fanuc ";
|
|
switch (string.Join("", Cnc_Type))
|
|
{
|
|
case "15": name += "15"; break;
|
|
case "16": name += "16"; break;
|
|
case "18": name += "18"; break;
|
|
case "21": name += "21"; break;
|
|
case "30": name += "30i"; break;
|
|
case "31": name += "31i"; break;
|
|
case "32": name += "21i"; break;
|
|
case "35": name += "35i"; break;
|
|
case "0": name += "0i"; break;
|
|
}
|
|
|
|
switch (NumberToByte(model)[1])
|
|
{
|
|
case 1: name += " Series A"; break;
|
|
case 2: name += " Series B"; break;
|
|
case 4: name += " Series C"; break;
|
|
case 8: name += " Series D"; break;
|
|
case 16: name += " Series F"; break;
|
|
}
|
|
|
|
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, ex);
|
|
}
|
|
|
|
// 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);
|
|
|
|
// Special language parameter
|
|
internal static MEMORY_CELL SPECIAL_LANGUAGE_BIT = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 2, 1, 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);
|
|
|
|
internal static MEMORY_CELL ACTIVE_CLIENT = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4, 1);
|
|
|
|
// 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_DATA = 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 M155_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3005, 1);
|
|
internal static MEMORY_CELL M155_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3006, 1);
|
|
|
|
internal static MEMORY_CELL M154_SWITCH_ONOFF = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS, 1, 2);
|
|
internal static MEMORY_CELL M154_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3031, 1);
|
|
internal static MEMORY_CELL M154_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 3032, 1);
|
|
|
|
internal static MEMORY_CELL M156_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 23053, 1);
|
|
internal static MEMORY_CELL M156_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 23054, 1);
|
|
internal static MEMORY_CELL M156_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 23055, 1);
|
|
internal static MEMORY_CELL M156_INPUT_ID_LIST = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 23056, 8);
|
|
|
|
internal static int M155_RESPONSE_MEMORY = 955;
|
|
internal static int M156_RESPONSE_MEMORY = 954;
|
|
|
|
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);
|
|
|
|
internal static MEMORY_CELL ASSISTED_TOOLING_DATA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4222, 7);
|
|
internal static MEMORY_CELL HMI_ASSISTED_TOOLING_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4233, 0, 1);
|
|
internal static MEMORY_CELL HMI_ASSISTED_TOOLING_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4233, 1, 1);
|
|
|
|
internal static MEMORY_CELL PLC_ASSISTED_TOOLING_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4234, 1, 1);
|
|
internal static MEMORY_CELL PLC_ASSISTED_TOOLING_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4234, 1, 1);
|
|
|
|
|
|
internal static MEMORY_CELL TOOL_MOVEMENT_AREA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4019, 1, 12);
|
|
internal static MEMORY_CELL TOOL_MOVEMENT_STROBE_END = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4020, 1, 0);
|
|
internal static MEMORY_CELL TOOL_MOVEMENT_HMI_RESPONSE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, STARTING_ADDRESS + 4030, 1, 12);
|
|
|
|
// 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 FAMILY_TABLE_INDEX_EXTRA_01 = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 29200, 600);
|
|
|
|
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, 1800);
|
|
|
|
//old CMS-Control variables
|
|
internal static MEMORY_CELL HEADS_WORKED_TIMES = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 3060, 4);
|
|
|
|
internal static MEMORY_CELL HEAD_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 7217, 4);
|
|
internal static MEMORY_CELL MACHINE_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 7213, 4);
|
|
internal static MEMORY_CELL MACHINE_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 7212, 4);
|
|
internal static MEMORY_CELL CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 7255, 1);
|
|
internal static MEMORY_CELL EXP_CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 7217, 1);
|
|
internal static MEMORY_CELL SELF_ADAPTIVE_PATH = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 8816, 4);
|
|
|
|
// Machine number
|
|
internal static MEMORY_CELL MATR_MACCH_FANUC = new MEMORY_CELL(MEMORY_TYPE.Fanuc_D, 4018, 0, 1);
|
|
internal static MEMORY_CELL NEW_MATR_MACCH = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 23049, 0, 1);
|
|
}
|
|
} |