Files
cms-core-active/CMS_CORE_Library/Fanuc/Nc_Fanuc.cs
T
Lucio Maranta 439a61cd59 Fix siemens
FIx Fanuc
2019-01-28 08:15:55 +00:00

4218 lines
169 KiB
C#

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