Files
2021-02-04 09:03:00 +01:00

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);
}
}