Files
CMS-MTConn/MTC_Adapter/MTC_Adapter/AdapterFanuc.cs
T
2017-03-28 11:36:50 +02:00

1843 lines
76 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CMSCncLib.CNC;
using System.IO;
using MTC;
namespace MTC_Adapter
{
public class AdapterFanuc : AdapterGeneric
{
// vettore valori in file interscambio
public Dictionary<string, string> generalStatus;
/// <summary>
/// Contenuto valori maintenance data da PLC
/// </summary>
public otherData[] maintData;
/// <summary>
/// Contenuto valori status data da PLC
/// </summary>
public otherData[] statusData;
/// <summary>
/// Oggetto MAIN x connessione FANUC
/// </summary>
protected FANUC FANUC_ref;
/// <summary>
/// wrapper chiamata lettura/scrittura fanuc...
/// </summary>
/// <param name="bWrite"></param>
/// <param name="MemType"></param>
/// <param name="memIndex"></param>
/// <param name="Value"></param>
/// <returns></returns>
public bool FanucMemRW(bool bWrite, FANUC.MemType MemType, Int32 memIndex, ref byte Value)
{
bool answ = false;
if (FANUC_ref.Connected)
{
try
{
answ = FANUC_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
}
catch
{ }
}
return answ;
}
/// <summary>
/// wrapper chiamata lettura/scrittura fanuc...
/// </summary>
/// <param name="bWrite"></param>
/// <param name="MemType"></param>
/// <param name="memIndex"></param>
/// <param name="MATRICE Value"></param>
/// <returns></returns>
public bool FanucMemRW(bool bWrite, FANUC.MemType MemType, Int32 memIndex, ref byte[] Value)
{
bool answ = false;
if (FANUC_ref.Connected)
{
try
{
answ = FANUC_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
}
catch
{ }
}
return answ;
}
/// <summary>
/// struttura dati fanuc x ALL DYN DATA
/// C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rddynamic2.htm
/// </summary>
protected CMSCncLib.Focas1.ODBDY2_1 allDynData;
/// <summary>
/// Vettore degli allarmi CNC attivi
/// </summary>
public CMSCncLib.Focas1.ODBALMMSG2 allarmiCNC;
/// <summary>
/// estende l'init della classe base...
/// </summary>
/// <param name="caller"></param>
/// <param name="adpConf"></param>
public AdapterFanuc(MainForm caller, AdapterConf adpConf) : base(caller, adpConf)
{
lg.Info("Start init Adapter FANUC all'IP {0}", utils.CRS("ipPLC"));
Runtime.CreateNC(CNC.NcType.FANUC, utils.CRS("ipPLC"));
// inizializzo posizioni assi...
prevPosAxis = new double[adpConf.nAxis];
prevDirAxis = new int[adpConf.nAxis];
FANUC_ref = (FANUC)Runtime.NC;
if (utils.CRB("verbose")) lg.Info("FANUC_ref da CMSCncLib");
// disconnetto e connetto...
if (utils.CRB("verbose")) lg.Info("FANUC: tryDisconnect");
tryDisconnect();
lg.Info("FANUC: tryConnect");
tryConnect();
lg.Info("End init Adapter FANUC");
}
public override void tryDisconnect()
{
if (connectionOk)
{
string szStatusConnection = "";
try
{
FANUC_ref.Disconnect(ref szStatusConnection);
connectionOk = false;
lg.Info(szStatusConnection);
lg.Info("Effettuata disconnessione adapter FANUC!");
}
catch (Exception exc)
{
lg.Fatal(exc, "Errore nella disconnessione dall'adapter FANUC");
}
}
else
{
lg.Error("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile...");
}
}
public override void tryConnect()
{
if (!connectionOk)
{
string szStatusConnection = "";
try
{
FANUC_ref.Connect(ref szStatusConnection);
lg.Info(szStatusConnection);
connectionOk = true;
// refresh stato allarmi!!!
if (connectionOk)
{
// carico status allarmi (completo)
lg.Info("Inizio refresh completo stato allarmi...");
forceAlarmCheck();
lg.Info("Completato refresh completo stato allarmi!");
}
else
{
lg.Error("Impossibile procedere, connessione mancante...");
}
}
catch (Exception exc)
{
lg.Fatal(exc, "Errore nella connessione all'adapter FANUC", szStatusConnection);
connectionOk = false;
lg.Info(string.Format("Segnalo Adapter NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec")));
}
}
}
/// <summary>
/// Verifico connessione fanuc...
/// </summary>
/// <returns></returns>
public override bool connectionOk
{
get
{
return FANUC_ref.Connected;
}
}
/// <summary>
/// Effettuo lettura dei 16 byte di strobe/status
/// </summary>
public override void getStrobeAndAckStatus()
{
base.getStrobeAndAckStatus();
if (connectionOk)
{
// leggo TUTTO ack e strobe,
byte[] MemBlock = new byte[Strobes.Length + Acknowl.Length];
int memIndex = 10500;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref MemBlock);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-STROBES", MemBlock.Length), DateTime.Now.Subtract(inizio).Ticks);
// suddivido!
Buffer.BlockCopy(MemBlock, 0, Acknowl, 0, Acknowl.Length);
Buffer.BlockCopy(MemBlock, Acknowl.Length, Strobes, 0, Strobes.Length);
}
else
{
lg.Error("Errore connessione mancante in getStrobeAndAckStatus");
}
}
/// <summary>
/// processing strobe!
/// </summary>
public override void processStrobe()
{
base.processStrobe();
// !!!FARE!!! multipath...
// verifico i vari strobe x recuperare i dati... PER ORA SOLO DW1 per path1 (indice 0)...
int idxPath = 0;
int memIndex = 0;
int bitNum = 0;
inizio = DateTime.Now;
// byte di acknowledge...
byte[] retACK_DW1 = new byte[4];
// inizializzo userAction
string UserAction = "";
string TestingData = "";
string UnkStrobe = "";
try
{
// controllo TUTTI i flag: se ce ne sono di alzati DEVO processare...
if (STRB_DW1 != StFlag32.NONE)
{
// blocco memoria x lettura TUTTI i dati di buffer M/S/T: 46 byte: 2byte (16bit) x (11+6+6) aree
byte[] MemBlock = new byte[46];
// leggo tutto!!!
memIndex = 10660;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref MemBlock);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-STRB_DW1", MemBlock.Length), DateTime.Now.Subtract(inizio).Ticks);
// check COD_M
bitNum = 0;
gestStrobeCodMST(bitNum, ref retACK_DW1, 0, MemBlock, "M");
// check COD_S
bitNum = 1;
gestStrobeCodMST(bitNum, ref retACK_DW1, 11, MemBlock, "S");
// check COD_T
bitNum = 2;
gestStrobeCodMST(bitNum, ref retACK_DW1, 17, MemBlock, "T");
// check FILE DATI MODIFICATO: ricaricare...
bitNum = 3;
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
{
lg.Info("Notifica file modificato");
try
{
// reload dati da file...
reloadDataFromFile();
// memorizzo allarme nel vettore ack....
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
}
catch
{
lg.Info("Errore lettura dati da file");
}
}
// AREA strobe USER ACTION
// chiamato Start...
bitNum = 4;
gestStrobeUserAction(bitNum, ref retACK_DW1, ref UserAction, " (START) ");
// chiamato Stop...
bitNum = 5;
gestStrobeUserAction(bitNum, ref retACK_DW1, ref UserAction, " (STOP) ");
// chiamato Reset...
bitNum = 6;
gestStrobeUserAction(bitNum, ref retACK_DW1, ref UserAction, " (RESET) ");
// processo tutti gli strobe x i BIT 7-29 NON gestiti in modo da dare comunque ACK e event...
for (int i = 7; i < 30; i++)
{
gestStrobeUserAction(i, ref retACK_DW1, ref UnkStrobe, string.Format(" [STROBE_{0:00}] ", i));
}
// AREA strobe x TEST
// INIZIO TEST...
bitNum = 30;
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
{
// formatto stringa risultato
TestingData = string.Format("START TEST{0}", getTestData(utils.CRS("testCharSep")));
// memorizzo allarme nel vettore ack....
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
}
// FINE TEST...
bitNum = 31;
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
{
// formatto stringa risultato
TestingData = string.Format("STOP TEST{0}", getTestData(utils.CRS("testCharSep")));
// memorizzo allarme nel vettore ack....
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
}
}
else
{
// se mi sono rimasti degli strobe di lettura allarmi alzati li abbasso
if (ACK_DW1 != StFlag32.NONE)
{
// inizializzo 4 byte a zero!!!
retACK_DW1 = new byte[4];
}
}
}
catch
{
lg.Info("Errore in strobe");
}
// 2017.01.16 INVIO vettore azioni (1 o +)... SE CE NE SONO!
if (UserAction.Trim() != "")
{
mUserAction.ForceChanged();
mUserAction.Value = UserAction.Trim();
}
// Invio comunque strobe non riconosciuti
if (mUnkStrobe.Value.ToString() != UnkStrobe.Trim())
{
mUnkStrobe.Value = UnkStrobe.Trim();
}
// INVIO COMUNQUE stato test...
mTestingData.Value = TestingData.Trim();
memIndex = 10504;
// scrivo update ad ack SE VARIATO!!!
if (ACK_DW1 != (StFlag32)BitConverter.ToUInt32(retACK_DW1, 0))
{
inizio = DateTime.Now;
FanucMemRW(W, FANUC.MemType.R, memIndex, ref retACK_DW1);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("W{0}-DW1", retACK_DW1.Length), DateTime.Now.Subtract(inizio).Ticks);
}
sendWatchDog();
}
/// <summary>
/// Invia (se necessario) il watchdog di stato in vita... blink 0/1 ogni secondo
/// </summary>
private void sendWatchDog()
{
int memIndex = 0;
byte[] retACK_DW = new byte[4];
// 2016.10.18 aggiungo scrittura del bit di "watchdog" al primo bit della DW2... come resto tra secondi / 2
if (utils.CRB("sendWatchDog"))
{
int resto = 0;
Math.DivRem(DateTime.Now.Second, 2, out resto);
bool setFlag = resto == 0;
retACK_DW = utils.setBitOnStFlag(retACK_DW, setFlag, 0); // imposto primo bit!!!
// scrivo su area PLC
memIndex = 10508;
inizio = DateTime.Now;
FanucMemRW(W, FANUC.MemType.R, memIndex, ref retACK_DW);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("W{0}-DW2", retACK_DW.Length), DateTime.Now.Subtract(inizio).Ticks);
}
}
/// <summary>
/// Recupero info su test: numero + elenco parametri IN/OUT
/// </summary>
/// <param name="charSep"></param>
/// <returns></returns>
private string getTestData(string charSep)
{
string answ = "";
// Area di memoria x test... 64 byte
byte[] MemBlockTestData = new byte[64];
// variabili numero test e num parametri impiegati
int testNum = 0;
int numPar = 0;
// variabile dove parcheggiare conversione codici dei parametri del test (IN o OUT)
UInt32 testParam = 0;
// leggo tutto!!!
int memIndex = 11000;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref MemBlockTestData);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TEST_DATA_DW1", MemBlockTestData.Length), DateTime.Now.Subtract(inizio).Ticks);
// recupero cod univoco test e numero parametri impiegati
testNum = BitConverter.ToUInt16(MemBlockTestData, 0);
numPar = BitConverter.ToUInt16(MemBlockTestData, 2);
// riporto separatore + numero test + num parametri
answ = string.Format("{0}TN:{1}{0}NP:{2}", charSep, testNum, numPar);
// se ci sono parametri da accodare li recupero!
if (numPar > 0)
{
for (int i = 0; i < numPar; i++)
{
testParam = BitConverter.ToUInt32(MemBlockTestData, 4 * (1 + i));
answ += string.Format("{0}{1}", charSep, testParam);
}
}
return answ;
}
/// <summary>
/// Gestione STROBE --> ACK per codici M/S/T
/// </summary>
/// <param name="bitNum">0/1/2</param>
/// <param name="retACK_DW1">vettore da restituire di ACK</param>
/// <param name="memShift">shift memoria x buffer dati da leggere</param>
/// <param name="MemBlock">Vettore completo dei valori + buffer code M/S/T</param>
/// <param name="Coda">Quale coda: M/S/T</param>
private void gestStrobeCodMST(int bitNum, ref byte[] retACK_DW1, int memShift, byte[] MemBlock, string Coda)
{
int numEv = 0;
int codEv = 0;
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
{
// verifico sia > 0 il numero di valori da leggere indice 0 sull'area...
numEv = BitConverter.ToUInt16(MemBlock, 2 * memShift);
if (numEv > 0)
{
// il num ev rappresenta quanti slot 16bit (da 2 byte) sono stati valorizzati, VA FATTO CICLO E LETTI TUTTI
for (int i = 0; i < numEv; i++)
{
// leggo valore Codice
codEv = BitConverter.ToUInt16(MemBlock, 2 * (i + 1 + memShift));
// accodo evento Codice
appendCodeMST(Coda, codEv.ToString());
}
}
// memorizzo allarme nel vettore ack....
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
}
}
/// <summary>
/// Ricarica dati da file di scambio con CMSConnect
/// </summary>
private void reloadDataFromFile()
{
if (utils.CRB("verbose")) lg.Info("Inizio lettura dati da file");
int totRighe = 0;
// da rivedere: se sono N+1 file (N=path + generale) deve essere ad esempio nomeComune_*.mtc --> ciclo per leggerne N
string fileName = string.Format(@"{0}\{1}", utils.dataDir, utils.CRS("GeneralStatusFilePath"));
string linea;
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
generalStatus = new Dictionary<string, string>();
try
{
totRighe = File.ReadLines(fileName).Count();
// carica da file...
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
if (file != null)
{
// leggo 1 linea alla volta...
string[] valori;
while ((linea = file.ReadLine()) != null)
{
// SE non è un commento...
if (linea.Substring(0, 1) != "#")
{
valori = linea.Split(utils.CRC("testCharSep"));
generalStatus.Add(valori[0], valori[1]);
}
}
// chiudo file
file.Close();
if (utils.CRB("verbose")) lg.Info("Fine lettura dati da file");
}
}
catch
{
lg.Info("Errore in lettura dati da file");
}
// ora salvo valori letti...
foreach (KeyValuePair<string, string> item in generalStatus)
{
// verifico la chiave e nel caso aggiorno...
switch (item.Key)
{
case "OperatorId":
mOperator.Value = item.Value;
break;
case "Path_01_CurrProg":
istPathProgrName[0] = item.Value;
break;
case "Path_02_CurrProg":
istPathProgrName[1] = item.Value;
break;
case "Path_03_CurrProg":
istPathProgrName[2] = item.Value;
break;
case "Path_04_CurrProg":
istPathProgrName[3] = item.Value;
break;
case "Path_05_CurrProg":
istPathProgrName[4] = item.Value;
break;
case "Path_06_CurrProg":
istPathProgrName[5] = item.Value;
break;
case "Path_01_PartId":
istPathPartId[0] = item.Value;
break;
case "Path_02_PartId":
istPathPartId[1] = item.Value;
break;
case "Path_03_PartId":
istPathPartId[2] = item.Value;
break;
case "Path_04_PartId":
istPathPartId[3] = item.Value;
break;
case "Path_05_PartId":
istPathPartId[4] = item.Value;
break;
case "Path_06_PartId":
istPathPartId[5] = item.Value;
break;
default:
break;
}
}
}
/// <summary>
/// Gestione strobe UserAction: salva dati e gestione ACK
/// </summary>
/// <param name="bitNum"></param>
/// <param name="retACK_DW1"></param>
/// <param name="UserAction"></param>
/// <param name="azione"></param>
private void gestStrobeUnknown(int bitNum, ref byte[] retACK_DW1, ref string UserAction, string azione)
{
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
{
// salvo evento UserAction in variabile...
UserAction += azione;
// memorizzo allarme nel vettore ack....
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
}
}
/// <summary>
/// Gestione strobe UserAction: salva dati e gestione ACK
/// </summary>
/// <param name="bitNum"></param>
/// <param name="retACK_DW1"></param>
/// <param name="UserAction"></param>
/// <param name="azione"></param>
private void gestStrobeUserAction(int bitNum, ref byte[] retACK_DW1, ref string UserAction, string azione)
{
if (STRB_DW1.HasFlag((StFlag32)Math.Pow(2, bitNum)))
{
// salvo evento UserAction in variabile...
UserAction += azione;
// memorizzo allarme nel vettore ack....
retACK_DW1 = utils.setBitOnStFlag(retACK_DW1, true, bitNum);
}
}
/// <summary>
/// recupera allarmi ed aggiorna strobe (privato) degli allarmi
/// </summary>
/// <param name="Alarm2Refresh">32bit mask degli allarmi da aggiornare</param>
/// <param name="giveAck">boolean: se si debba tornare ACK</param>
public override void refreshAlarmState(StFlag32 Alarm2Refresh, bool giveAck)
{
// log bitmap se verboso attivo + ho allarmi da refreshare
if ((Alarm2Refresh != StFlag32.NONE) && utils.CRB("verbose"))
{
lg.Info("Richiesto refresh allarmi x bitmask: {0}", utils.binaryForm((int)Alarm2Refresh));
}
bool ackReturned = false;
// byte di acknowledge...
byte[] retACK_DW0 = new byte[4];
// inizio impostando una bitmap x ACK che abbia i bit abbassati se lo strobe è disattivo: AND logico tra STR e ACK
retACK_DW0 = BitConverter.GetBytes(Convert.ToUInt32(STRB_DW0 & ACK_DW0));
inizio = DateTime.Now;
byte[] MemBlock;
// primo blocco memoria allarmi
int memIndex = 10532;
// controllo, SE devo leggere tutto uso un unico accesso ai 128byte, altrimenti leggo a blocchi di 32bit...
if (Alarm2Refresh == (StFlag32)unchecked((int)UInt32.MaxValue))
{
// blocco memoria x lettura dati COMPLETO (4Byte*32 = 128Byte)
MemBlock = new byte[128];
// recupero tutti i 32 bit del blocco
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref MemBlock);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-STRB_DW0", MemBlock.Length), DateTime.Now.Subtract(inizio).Ticks);
if (AlarmFlags != null)
{
try
{
// aggiorno vettore allarmi x intero!
Buffer.BlockCopy(MemBlock, 0, AlarmFlags, 0, MemBlock.Length);
}
catch (Exception exc)
{
lg.Error(string.Format("Errore in BLOCKCOPY{0}{1}", Environment.NewLine, exc));
}
}
}
else
{
if (Alarm2Refresh != StFlag32.NONE)
{
// blocco memoria x lettura dati
MemBlock = new byte[4];
// verifico gli allarmi di tutti i bit alzati...
for (int i = 0; i < 32; i++)
{
if (Alarm2Refresh.HasFlag((StFlag32)Math.Pow(2, i)))
{
// recupero tutti i 32 bit del blocco
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex + i * 4, ref MemBlock);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-STRB_DW0", MemBlock.Length), DateTime.Now.Subtract(inizio).Ticks);
// da testare metodo copia alternativo !!!FARE!!!
if (true)
{
// aggiorno nel vettore allarmi i byte interessati
for (int j = 0; j < 4; j++)
{
// copy array o byte?!? !!!FARE!!! verifica
AlarmFlags[i * 4 + j] = MemBlock[j];
}
}
else
{
Buffer.BlockCopy(MemBlock, i, AlarmFlags, i, MemBlock.Length);
}
// segnalo allarme letto! memorizzo allarme nel vettore ack....
retACK_DW0 = utils.setBitOnStFlag(retACK_DW0, true, i);
}
}
// scrivo ack se richiesto!!!
if (giveAck)
{
// mi preparo a scrivere ACK
memIndex = 10500;
// scrivo update ad ack!!!
inizio = DateTime.Now;
FanucMemRW(W, FANUC.MemType.R, memIndex, ref retACK_DW0);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("W{0}-ACK_DW0", retACK_DW0.Length), DateTime.Now.Subtract(inizio).Ticks);
ackReturned = true;
}
}
}
// SE non ho già tornato un ACK...
if (!ackReturned)
{
// se è diverso il vettori degli ACK in memoria da quello PLC...
if (ACK_DW0 != (StFlag32)BitConverter.ToUInt32(retACK_DW0, 0))
{
memIndex = 10500;
// invio INTERO set ACK_DW0 con bit abbassati...
retACK_DW0 = BitConverter.GetBytes(Convert.ToUInt32(STRB_DW0 & ACK_DW0));
inizio = DateTime.Now;
FanucMemRW(W, FANUC.MemType.R, memIndex, ref retACK_DW0);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("W{0}-ACK_DW0", retACK_DW0.Length), DateTime.Now.Subtract(inizio).Ticks);
}
}
}
/// <summary>
/// processing!
/// </summary>
public override void processStatus()
{
// update status da DW2/ DW3
// EMstop: verifico BIT e di conseguenza imposto
if (STRB_DW2.HasFlag(StFlag32.B00))
{
mEStop.Value = "TRIGGERED";
}
else
{
mEStop.Value = "ARMED";
}
// verifico POWER ON...
if (STRB_DW2.HasFlag(StFlag32.B01))
{
mPower.Value = "ON";
}
else
{
mPower.Value = "OFF";
}
// Processo selezionato 0=P1, 1=P2
string procSel = "";
if (STRB_DW2.HasFlag(StFlag32.B02))
{
procSel = "P2";
}
else
{
procSel = "P1";
}
if (mProcSel.Value.ToString() != procSel)
{
mProcSel.Value = procSel;
}
// HARD CODE: forzo path 1 (indice 0...)
int idxPath = 0;
// verifico tipo processo path...
if (STRB_DW2.HasFlag(StFlag32.B03))
{
vettPath[idxPath].mPathType.Value = "LAVORO";
}
else
{
vettPath[idxPath].mPathType.Value = "ASSERV";
}
// switch su RUN mode...
string runMode = "";
if (STRB_DW2.HasFlag(StFlag32.B04))
{
runMode = "AUTOMATIC";
}
else if (STRB_DW2.HasFlag(StFlag32.B05))
{
runMode = "EDIT";
}
else if (STRB_DW2.HasFlag(StFlag32.B06))
{
runMode = "MANUAL_DATA_INPUT";
}
else if (STRB_DW2.HasFlag(StFlag32.B07))
{
runMode = "MANUAL";
}
else if (STRB_DW2.HasFlag(StFlag32.B08))
{
runMode = "SEMI_AUTO";
}
// salvo valore selezionato
if (vettPath[idxPath].mPathRunMode.Value.ToString() != runMode)
{
vettPath[idxPath].mPathRunMode.Value = runMode;
}
// switch su EXE mode...
string exeMode = "";
if (STRB_DW2.HasFlag(StFlag32.B09))
{
exeMode = "ACTIVE";
}
else if (STRB_DW2.HasFlag(StFlag32.B10))
{
exeMode = "READY";
}
else if (STRB_DW2.HasFlag(StFlag32.B11))
{
exeMode = "STOPPED";
}
else if (STRB_DW2.HasFlag(StFlag32.B12))
{
exeMode = "FEED_HOLD";
}
else if (STRB_DW2.HasFlag(StFlag32.B13))
{
exeMode = "OPTIONAL_STOP";
}
else if (STRB_DW2.HasFlag(StFlag32.B14))
{
exeMode = "PROGRAM_STOPPED";
}
else if (STRB_DW2.HasFlag(StFlag32.B15))
{
exeMode = "PROGRAM_COMPLETED";
}
// salvo valore selezionato
if (vettPath[idxPath].mPathExeMode.Value.ToString() != exeMode)
{
vettPath[idxPath].mPathExeMode.Value = exeMode;
}
// processo eventuali altri bit status non noti...
string UnkStatus = "";
// cerco i bit alzati --> aggiungo in stringa!
for (int i = 14; i < 32; i++)
{
// converto! e aggiungo allarmi sollevati al corretto controller allarmi...
if (STRB_DW2.HasFlag((StFlag32)Math.Pow(2, i)))
{
UnkStatus += string.Format(" [STATUS_{0:00}] ", i);
}
}
// invio comunque...
mUnkStatus.Value = UnkStatus.Trim();
// inizializzo SEMPRE a vuoto...
string SubMode = "";
// verifico sulla STRB_DW3 i submode che POTREBBERO tutti sovrapposti...
if (STRB_DW3 != StFlag32.NONE)
{
// cerco i bit alzati --> aggiungo relativo submode!
for (int i = 0; i < 32; i++)
{
// converto! e aggiungo allarmi sollevati al corretto controller allarmi...
if (STRB_DW3.HasFlag((StFlag32)Math.Pow(2, i)))
{
SubMode += string.Format(" [{0}]", elencoSubMode[i.ToString()]);
}
}
}
// 2017.01.16 INVIO SOLO SE CAMBIA:..
if (vettPath[idxPath].mPathSubMode.Value.ToString() != SubMode.Trim())
{
// INVIO SEMPRE (x prendere il reset/fronte discesa)...
vettPath[idxPath].mPathSubMode.Value = SubMode.Trim();
}
}
public override void getConfigParam()
{
base.getConfigParam();
}
public override void getSlowChangingData()
{
base.getSlowChangingData();
// reload dati da file...
reloadDataFromFile();
// area gestione dati utensili... in base al num max di UnOp recupero i dati utensile... PROCEDURA AD HOC!!!
getDatiUt_Fanuc(currAdpConf.nUnOp);
}
/// <summary>
/// Gestione lettura dati manutenzione
/// </summary>
private void getMtzDataFromPlc()
{
bool needSave = false;
// recupero i dati di manutenzione dall'area di memoria IN BLOCCO
int memIndex = 14000;
byte[] tabDatiMtz = new byte[4 * maintData.Length];
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref tabDatiMtz);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-DatiMtz", tabDatiMtz.Length), DateTime.Now.Subtract(inizio).Ticks);
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
int shift = 4; // 32bit
int numero = 0;
uint valRead = 0;
for (int i = 0; i < maintData.Length; i++)
{
numero = 0;
valRead = 0;
// 2016.07.06 uso indice i * 4 x selezionare area memoria...
//shift = Convert.ToInt32(maintData[i].codNum) - 1;
if (maintData[i].varName == "ACC_TIME")
{
istOreMaccOn = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
else if (maintData[i].varName == "ACC_TIME_WORK")
{
istOreMaccLav = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
else if (maintData[i].varName.StartsWith("Path_"))
{
if (maintData[i].varName.EndsWith("_PZ_TOT"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Path_", "").Replace("_PZ_TOT", ""));
}
catch
{
}
if (numero > 0)
{
vettPath[numero - 1].mPathPartCount.Value = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
}
else if (maintData[i].varName.StartsWith("Axis_"))
{
if (maintData[i].varName.EndsWith("_DistDone"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_DistDone", ""));
}
catch
{ }
if (numero > 0)
{
istDistMovAssi[numero - 1] = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
else if (maintData[i].varName.EndsWith("_Invers"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_Invers", ""));
}
catch
{ }
if (numero > 0)
{
// 2016.07.06 debug di valori che potrebbero essere nulli...
try
{
valRead = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
catch (Exception exc)
{
valRead = 0;
lg.Error(string.Format("Errore in recupero num inversioni:{0}parametro: {1}{0}shift: {2}{0}i: {3}{0}Exc: {4}", Environment.NewLine, maintData[i].varName, shift, i, exc));
}
istNumInvAssi[numero - 1] = valRead;
}
}
else if (maintData[i].varName.EndsWith("_AccTime"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Axis_", "").Replace("_AccTime", ""));
}
catch
{ }
if (numero > 0)
{
// 2016.07.06 debug di valori che potrebbero essere nulli...
try
{
valRead = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
catch (Exception exc)
{
valRead = 0;
lg.Error(string.Format("Errore in recupero num inversioni:{0}parametro: {1}{0}shift: {2}{0}i: {3}{0}Exc: {4}", Environment.NewLine, maintData[i].varName, shift, i, exc));
}
istAccTimeAssi[numero - 1] = valRead;
}
}
}
else if (maintData[i].varName.StartsWith("UnOp_"))
{
if (maintData[i].varName.EndsWith("_AccTime"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("UnOp_", "").Replace("_AccTime", ""));
}
catch
{ }
if (numero > 0)
{
istGiriElettrom[numero - 1] = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
else if (maintData[i].varName.EndsWith("_NumCambiUT"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("UnOp_", "").Replace("_NumCambiUT", ""));
}
catch
{ }
if (numero > 0)
{
istNumCambiUt[numero - 1] = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
}
else if (maintData[i].varName.StartsWith("VacPump_"))
{
if (maintData[i].varName.EndsWith("_WrkTime"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("VacPump_", "").Replace("_WrkTime", ""));
}
catch
{ }
if (numero > 0)
{
istVacPumpWrkTime[numero - 1] = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
}
else if (maintData[i].varName.StartsWith("VacAct_"))
{
if (maintData[i].varName.EndsWith("_Count"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("VacAct_", "").Replace("_Count", ""));
}
catch
{ }
if (numero > 0)
{
istVacActCount[numero - 1] = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
}
else if (maintData[i].varName.StartsWith("Lubro_"))
{
if (maintData[i].varName.EndsWith("_Num"))
{
try
{
numero = Convert.ToInt32(maintData[i].varName.Replace("Lubro_", "").Replace("_Num", ""));
}
catch
{ }
if (numero > 0)
{
istLubroCount[numero - 1] = BitConverter.ToUInt32(tabDatiMtz, shift * i);
}
}
}
}
// verifica se si debba aggiornare XML (e salva in adapter dati vari)
needSave = procOreMaccOn(needSave);
needSave = procOreMaccLav(needSave);
needSave = procProgrName(needSave);
needSave = procPartId(needSave);
needSave = procPzProd(needSave);
needSave = procGiriTotUnOp(needSave);
needSave = procNumCU(needSave);
needSave = procMovTotAssi(needSave);
needSave = procAccTimeAssi(needSave);
needSave = procNumInvAssi(needSave);
needSave = procVacPump(needSave);
needSave = procVacAct(needSave);
needSave = procLubro(needSave);
// salvo se necessario!
if (needSave) parentForm.persistData();
// -------------------------------------------
}
/// <summary>
/// Gestione lettura dati status da PLC
/// </summary>
private void getStatusDataFromPlc()
{
// recupero i dati di manutenzione dall'area di memoria IN BLOCCO
int memIndex = 14512;
int bitNum = 0;
int byteNum = 0;
byte byteVal;
int numByte = 1 + (statusData.Length / 8);
byte[] tabDatiStatus = new byte[numByte];
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref tabDatiStatus);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-DatiStatus", tabDatiStatus.Length), DateTime.Now.Subtract(inizio).Ticks);
// uno ad uno vado a inserirli nella mappa dei dati dell'adapter...
int numero = 0;
string status = "";
for (int i = 0; i < statusData.Length; i++)
{
numero = 0;
status = "";
// calcolo quale byte e quale bit devo leggere..
byteNum = i / 8;
bitNum = i - (8 * byteNum); // indice zero dei bit nel byte ( da cui -1 )
// faccio vera lettura
byteVal = tabDatiStatus[byteNum];
// leggo bit come ACTIVE/INACTIVE
if (((StFlag8)byteVal).HasFlag((StFlag8)Math.Pow(2, bitNum)))
{
status = "ACTIVE";
}
else
{
status = "INACTIVE";
}
if (statusData[i].varName == "PROTECTION_STATUS")
{
mProtectionStatus.Value = status;
}
else if (statusData[i].varName.StartsWith("VacPump_"))
{
if (statusData[i].varName.EndsWith("_Status"))
{
try
{
numero = Convert.ToInt32(statusData[i].varName.Replace("VacPump_", "").Replace("_Status", ""));
}
catch
{
}
if (numero > 0)
{
vettVacPump[numero - 1].mVacPumpStatus.Value = status;
}
}
}
else if (statusData[i].varName.StartsWith("Cooler_"))
{
if (statusData[i].varName.EndsWith("_Status"))
{
try
{
numero = Convert.ToInt32(statusData[i].varName.Replace("Cooler_", "").Replace("_Status", ""));
}
catch
{ }
if (numero > 0)
{
vettCooler[numero - 1].mCoolStatus.Value = status;
}
}
}
else if (statusData[i].varName.StartsWith("UnOp_"))
{
if (statusData[i].varName.EndsWith("_Status"))
{
try
{
numero = Convert.ToInt32(statusData[i].varName.Replace("UnOp_", "").Replace("_Status", ""));
}
catch
{ }
if (numero > 0)
{
vettUnOp[numero - 1].mUnOpStatus.Value = status;
}
}
}
}
}
/// <summary>
/// Leggo dati globali comuni (x path, assi...)
/// </summary>
public override void getGlobalData()
{
base.getGlobalData();
// accodo dati path in DataMonitor......
StringBuilder sb = new StringBuilder();
// leggo dati globali...
inizio = DateTime.Now;
allDynData = FANUC_ref.getAllDynData();
if (utils.CRB("recTime")) TimingData.addResult("R-ALL-DYN-DATA", DateTime.Now.Subtract(inizio).Ticks);
FeedRate = allDynData.actf;
int memIndex = 12000;
byte[] PathData = new byte[4];
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.R, memIndex, ref PathData);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-PathData", PathData.Length), DateTime.Now.Subtract(inizio).Ticks);
// 2016.07.19 mod con Fabio
//JogRateOver = PathData[0];
FeedRateOver = PathData[1];
RapidOver = PathData[2];
SpeedRateOver = PathData[3];
sb.AppendLine(string.Format("FeedRate: {0} mm/min", FeedRate));
sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver));
sb.AppendLine(string.Format("RapidOver: {0} %", RapidOver));
sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver));
// se ho allarmi li accodo...
if (allDynData.alarm != 0)
{
sb.AppendLine(string.Format("Allarmi CNC: {0}", allDynData.alarm));
inizio = DateTime.Now;
allarmiCNC = FANUC_ref.getCncAlarm();
if (utils.CRB("recTime")) TimingData.addResult("R-CNC-ALARMS", DateTime.Now.Subtract(inizio).Ticks);
checkCNCAlarms();
}
else
{
allarmiCNC = new CMSCncLib.Focas1.ODBALMMSG2();
}
parentForm.dataMonitor = sb.ToString();
// gestisco lettura dati manutenzione da PLC...
getMtzDataFromPlc();
// gestisco lettura dati status da PLC...
getStatusDataFromPlc();
}
/// <summary>
/// Carico file conf dati CMS
/// </summary>
protected override void loadOtherFile()
{
base.loadOtherFile();
loadMaintData();
loadStatusData();
}
/// <summary>
/// Lettura file gestione dati manutenzione da PLC
/// </summary>
private void loadMaintData()
{
// carico dati x Maintenance
if (utils.CRB("verbose")) lg.Info("Inizio caricamento vettore variabili manutenzione gestite");
int totRighe = 0;
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("CounterListFilePath"));
string linea;
totRighe = File.ReadLines(fileName).Count();
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
maintData = new otherData[File.ReadLines(fileName).Count()];
// carica da file...
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
// leggo 1 linea alla volta...
int numRiga = 0;
while ((linea = file.ReadLine()) != null)
{
// SE non è un commento...
if (linea.Substring(0, 1) != "#")
{
//elencoAllarmi[rumRiga] = decodeAlarmLine(linea, ':');
maintData[numRiga] = decodeOtherData(linea, utils.CRC("testCharSep"), "R", 14000, 4);
numRiga++;
}
}
// chiudo file
file.Close();
// ora trimmo vettore al solo numero VERO dei valori caricati...
Array.Resize<otherData>(ref maintData, numRiga);
if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili manutenzione gestite", numRiga));
}
/// <summary>
/// Lettura file gestione dati status da PLC
/// </summary>
private void loadStatusData()
{
// carico dati x Maintenance
if (utils.CRB("verbose")) lg.Info("Inizio caricamento vettore variabili status gestite");
int totRighe = 0;
string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("StatusListFilePath"));
string linea;
totRighe = File.ReadLines(fileName).Count();
// creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco...
statusData = new otherData[File.ReadLines(fileName).Count()];
// carica da file...
System.IO.StreamReader file = new System.IO.StreamReader(fileName);
// leggo 1 linea alla volta...
int numRiga = 0;
while ((linea = file.ReadLine()) != null)
{
// SE non è un commento...
if (linea.Substring(0, 1) != "#")
{
//elencoAllarmi[rumRiga] = decodeAlarmLine(linea, ':');
statusData[numRiga] = decodeBitData(linea, utils.CRC("testCharSep"), "R", 14512, 1, numRiga);
numRiga++;
}
}
// chiudo file
file.Close();
// ora trimmo vettore al solo numero VERO dei valori caricati...
Array.Resize<otherData>(ref statusData, numRiga);
if (utils.CRB("verbose")) lg.Info(string.Format("Fine caricamento vettore di {0} variabili status gestite", numRiga));
}
public override void processAlarm()
{
base.processAlarm();
// ggiungo gestione allarmi CNC
checkCNCAlarms();
}
/// <summary>
/// Verifica i 10 allarmi CNC SE presenti
/// </summary>
private void checkCNCAlarms()
{
// faccio parse allarmi: se ci sono invio e presento
sendAlarmIfPresent(allarmiCNC.msg1);
sendAlarmIfPresent(allarmiCNC.msg2);
sendAlarmIfPresent(allarmiCNC.msg3);
sendAlarmIfPresent(allarmiCNC.msg4);
sendAlarmIfPresent(allarmiCNC.msg5);
sendAlarmIfPresent(allarmiCNC.msg6);
sendAlarmIfPresent(allarmiCNC.msg7);
sendAlarmIfPresent(allarmiCNC.msg8);
sendAlarmIfPresent(allarmiCNC.msg9);
sendAlarmIfPresent(allarmiCNC.msg10);
}
/// <summary>
/// Invia singolo allarme CNC se presente
/// </summary>
/// <param name="allarme"></param>
protected void sendAlarmIfPresent(CMSCncLib.Focas1.ODBALMMSG2_data allarme)
{
// controllo valore...
if (allarme.alm_no > 0)
{
//if (utils.CRB("verbose")) sb.AppendLine(string.Format("Allarmi CNC: NUM {0} | MESS: {1} | ASSE: {2} | TYPE: {3}", allarme.alm_no, allarme.alm_msg, allarme.axis, allarme.type));
// se ho asse accodo ad asse altrimenti no...
string codAllarme = string.Format("T{0}-N{1}", allarme.type, allarme.alm_no);
if (allarme.axis == 0)
{
mAlarmCNC.Add(MTConnect.Condition.Level.FAULT, allarme.alm_msg, codAllarme, "", "");
}
else
{
mAlarmCNC.Add(MTConnect.Condition.Level.FAULT, allarme.alm_msg, codAllarme, "", "");
vettAxis[allarme.axis - 1].mAxAlarmCNC.Add(MTConnect.Condition.Level.FAULT, allarme.alm_msg, codAllarme, "", "");
}
}
}
public override void getUnOp()
{
base.getUnOp();
// leggo in blocco tutte le speed da memoria...
int memIndex = 3140;
// buffer memoria 60 byte... speed (16bit 2 * 20) + load (8bit 1 * 20) visto che sono 20 teste max
byte[] unOpSpeedMem = new byte[60];
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref unOpSpeedMem);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-SPEED_UNOP", unOpSpeedMem.Length), DateTime.Now.Subtract(inizio).Ticks);
// NON VA: RICHIEDE OPZIONE... The extended driver/library function is necessary.
#if false
// recupero vettore load spindle...
inizio = DateTime.Now;
CMSCncLib.Focas1.ODBSPN spindleVect = FANUC_ref.getSpindleLoad();
if (utils.CRB("recTime")) TimingData.addResult("R-SpindleLoad", DateTime.Now.Subtract(inizio).Ticks);
#endif
StringBuilder sb = new StringBuilder();
int numUnOp = currAdpConf.nUnOp;
// cicl su path x leggere le velocità dell'UnOp
for (int i = 0; i < numUnOp; i++)
{
// leggo valore Codice
SpeedRate = BitConverter.ToUInt16(unOpSpeedMem, 2 * i);
// leggo 41° byte = indice 40 + 2*i x le var del carico UnOp
UnOpLoad = unOpSpeedMem[40 + i];
//vettUnOp[i].mUnOpNumCU.Value = uoData.UnOpNumCU;
//vettUnOp[i].mUnOpStatus.Value = uoData.UnOpStatus;
//vettUnOp[i].mUnOpAccTime.Value = uoData.UnOpAccTime;
sb.AppendLine(string.Format("SpeedRate UnOp_{0}: {1} rpm", i + 1, SpeedRate));
sb.AppendLine(string.Format("Load UnOp_{0}: {1}", i + 1, UnOpLoad));
}
parentForm.dataMonitor += sb.ToString();
}
/// <summary>
/// procedura di lettura (Multipla) dati da memoria x caricare dati utensile
/// </summary>
/// <param name="maxNumOp">num max di teste da recuperare</param>
private void getDatiUt_Fanuc(int maxNumOp)
{
// variabili "Indice" utensile e famiglia da decodificare + utils
int maxMemAddr = 200;
int[] idUtMontato = new int[maxNumOp];
int[] idFamUt = new int[maxNumOp];
int[] idTipoVitaUt = new int[maxNumOp];
int[] valVitaUtRes = new int[maxNumOp];
int[] tabUt = new int[maxMemAddr];
int[] tabFamUt = new int[maxMemAddr];
int memIndex = 0;
byte[] int32Mem = new byte[4];
byte[] int16Mem = new byte[2];
byte int8Mem = new byte();
// step 1: lettura ID dell'utensile x ogni testa...
byte[] elencoUtMem = new byte[2 * maxNumOp];
// leggo area memoria degli UT montati
memIndex = 2960;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref elencoUtMem);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-NUMUT", elencoUtMem.Length), DateTime.Now.Subtract(inizio).Ticks);
// decodifica da byte a int16 dell'ID Utensile
for (int i = 0; i < maxNumOp; i++)
{
idUtMontato[i] = BitConverter.ToUInt16(elencoUtMem, 2 * i);
}
// step 2a: leggo vettore memoria dei maxMemAddr(200) UT in Tabella Utensili
memIndex = 11300;
byte[] tabUt_UT = new byte[2 * maxMemAddr];
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref tabUt_UT);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-UT", tabUt_UT.Length), DateTime.Now.Subtract(inizio).Ticks);
// decodifico TUTTI i maxMemAddr utensili
for (int i = 0; i < maxMemAddr; i++)
{
tabUt[i] = BitConverter.ToUInt16(tabUt_UT, 2 * i);
}
// step 2a: devo cercare l'UT di ogni UnOp nella Tabella Utensili
for (int i = 0; i < maxNumOp; i++)
{
// spazzo la tab Utensili x cercare quelli delle UnOp...
for (int j = 0; j < maxMemAddr; j++)
{
// controllo, se l'id utensile è quello dell'attuale UnOp...
if (tabUt[j] == idUtMontato[i])
{
// leggo FamUt puntuale..
memIndex = 11700 + 2 * j;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref int16Mem);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-FamUT", int16Mem.Length), DateTime.Now.Subtract(inizio).Ticks);
// step 2b: leggo puntualmente la FamUt dal suo indice...
idFamUt[i] = BitConverter.ToUInt16(int16Mem, 0);
}
}
}
// step 3: leggo vettore memoria dei maxMemAddr(200) FamUT in Tabella Famiglie Utensili (x ricavare unità misura vita)
memIndex = 8900;
byte[] tabFam_FamUt = new byte[2 * maxMemAddr];
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref tabFam_FamUt);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabFamUT-FamUT", tabFam_FamUt.Length), DateTime.Now.Subtract(inizio).Ticks);
// decodifico TUTTI i maxMemAddr utensili
for (int i = 0; i < maxMemAddr; i++)
{
tabFamUt[i] = BitConverter.ToUInt16(tabFam_FamUt, 2 * i);
}
// step 3a: devo cercare la famiglia dell'UT di ogni UnOp nella Tabella Famiglie
for (int i = 0; i < maxNumOp; i++)
{
// poiché potrei trovarlo replicato dopo la prima volta che lo trovo evito di ricontrollare...
bool found = false;
// spazzo la tab Utensili x cercare quelli delle UnOp...
for (int j = 0; j < maxMemAddr; j++)
{
// controllo, se l'id utensile è quello dell'attuale UnOp...
if (tabFamUt[j] == idFamUt[i] && !found)
{
// leggo FamUt puntuale..
memIndex = 10700 + 1 * j;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref int8Mem);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-FamUT", 8), DateTime.Now.Subtract(inizio).Ticks);
// step 3b: leggo puntualmente il TIPO DI vita UT dal suo indice...
idTipoVitaUt[i] = int8Mem;
found = true;
}
}
}
// step 4: recupero la vita residua dell'utente
for (int i = 0; i < maxNumOp; i++)
{
// spazzo la tab Utensili x cercare quelli delle UnOp...
for (int j = 0; j < maxMemAddr; j++)
{
// controllo, se l'id utensile è quello dell'attuale UnOp...
if (tabUt[j] == idUtMontato[i])
{
// leggo FamUt puntuale..
memIndex = 13100 + 4 * j;
inizio = DateTime.Now;
FanucMemRW(R, FANUC.MemType.D, memIndex, ref int32Mem);
if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-TabUT-VitaRes", int32Mem.Length), DateTime.Now.Subtract(inizio).Ticks);
// leggo puntualmente valore della vita ut residua da indice utensile...
valVitaUtRes[i] = BitConverter.ToInt32(int32Mem, 0);
}
}
}
// salvo in adapter vita UT residua...
for (int i = 0; i < maxNumOp; i++)
{
vettUnOp[i].mUnOpToolId.Value = idUtMontato[i];
vettUnOp[i].mUnOpVitaRes.Value = valVitaUtRes[i];
// decodifico valore tipo VitaRes...
string tipoVitaRes = "ND";
switch (idTipoVitaUt[i])
{
case 1:
tipoVitaRes = "Time";
break;
case 2:
tipoVitaRes = "Stroke";
break;
case 3:
tipoVitaRes = "Distance";
break;
default: break;
}
vettUnOp[i].mUnOpVitaResType.Value = tipoVitaRes;
}
}
public override void getPath()
{
base.getPath();
// recupero vettore generale G MODE
inizio = DateTime.Now;
CMSCncLib.Focas1.ODBGCD vettGCodes = FANUC_ref.getPathGCodeMod();
if (utils.CRB("recTime")) TimingData.addResult("R-GCodModal", DateTime.Now.Subtract(inizio).Ticks);
string GCodAttivi = "";
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd0.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd1.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd2.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd3.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd4.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd5.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd6.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd7.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd8.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd9.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd10.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd11.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd12.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd13.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd14.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd15.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd16.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd17.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd18.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd19.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd20.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd21.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd22.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd23.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd24.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd25.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd26.code);
GCodAttivi += string.Format("[{0}]", vettGCodes.gcd27.code);
inizio = DateTime.Now;
vettGCodes = FANUC_ref.getPathGCode1Shot();
if (utils.CRB("recTime")) TimingData.addResult("R-GCodOneShot", DateTime.Now.Subtract(inizio).Ticks);
if (vettGCodes.gcd0.flag > 0) GCodAttivi += string.Format("[{0}]", vettGCodes.gcd0.code);
if (vettGCodes.gcd1.flag > 0) GCodAttivi += string.Format("[{0}]", vettGCodes.gcd1.code);
if (vettGCodes.gcd2.flag > 0) GCodAttivi += string.Format("[{0}]", vettGCodes.gcd2.code);
if (vettGCodes.gcd3.flag > 0) GCodAttivi += string.Format("[{0}]", vettGCodes.gcd3.code);
inizio = DateTime.Now;
CMSCncLib.Focas1.ODB5AXMAN vettTTCoord = FANUC_ref.getPathTTCoord();
if (utils.CRB("recTime")) TimingData.addResult("R-TTCoord", DateTime.Now.Subtract(inizio).Ticks);
// cicl su path
for (int i = 0; i < currAdpConf.nPath; i++)
{
// accodo dati path in DataMonitor......
StringBuilder sb = new StringBuilder();
vettPath[i].mPathCodG_Act.Value = GCodAttivi;
vettPath[i].mPathPosActX.Value = ((decimal)vettTTCoord.data1) / utils.CRI("fattdecimale");
vettPath[i].mPathPosActY.Value = ((decimal)vettTTCoord.data2) / utils.CRI("fattdecimale");
vettPath[i].mPathPosActZ.Value = ((decimal)vettTTCoord.data3) / utils.CRI("fattdecimale");
vettPath[i].mPathPosActI.Value = ((decimal)vettTTCoord.c1) / utils.CRI("fattdecimale");
vettPath[i].mPathPosActJ.Value = ((decimal)vettTTCoord.c2) / utils.CRI("fattdecimale");
vettPath[i].mPathPosActK.Value = "0"; // è 5 assi...nullo...
// 2017.01.16 da rivedere
vettPath[i].mPathCurrProgRowNum.Value = "";
vettPath[i].mPathActiveAxes.Value = "";
sb.AppendLine(string.Format("Path {0}, PROG: {1}", i + 1, vettPath[i].mPathCurrProg.Value));
sb.AppendLine(string.Format("Path {0}, Asse 1: {1:N3}", i + 1, ((decimal)vettTTCoord.data1) / utils.CRI("fattdecimale")));
sb.AppendLine(string.Format("Path {0}, Asse 2: {1:N3}", i + 1, ((decimal)vettTTCoord.data2) / utils.CRI("fattdecimale")));
sb.AppendLine(string.Format("Path {0}, Asse 3: {1:N3}", i + 1, ((decimal)vettTTCoord.data3) / utils.CRI("fattdecimale")));
sb.AppendLine(string.Format("Path {0}, Cent 1: {1:N3}", i + 1, ((decimal)vettTTCoord.c1) / utils.CRI("fattdecimale")));
sb.AppendLine(string.Format("Path {0}, Cent 2: {1:N3}", i + 1, ((decimal)vettTTCoord.c2) / utils.CRI("fattdecimale")));
parentForm.dataMonitor += sb.ToString();
}
}
public override void getAxis()
{
// mostro assi in DataMonitor......
StringBuilder sb = new StringBuilder();
inizio = DateTime.Now;
CMSCncLib.Focas1.ODBPOS posAssi = FANUC_ref.getAllAxisPos();
if (utils.CRB("recTime")) TimingData.addResult("R-AXIS_POS", DateTime.Now.Subtract(inizio).Ticks);
inizio = DateTime.Now;
CMSCncLib.Focas1.ODBSVLOAD loadAssi = FANUC_ref.getAllAxisLoad();
if (utils.CRB("recTime")) TimingData.addResult("R-AXIS_LOAD", DateTime.Now.Subtract(inizio).Ticks);
CMSCncLib.Focas1.LOADELM valLoad = new CMSCncLib.Focas1.LOADELM();
CMSCncLib.Focas1.POSELMALL valPos = new CMSCncLib.Focas1.POSELMALL();
// nuova posizione (per calcoli)
double newPos = 0;
double distPerc = 0;
int newDir = 0;
string tipoAsse = "";
string direzione = "";
for (int i = 0; i < currAdpConf.nAxis; i++)
{
// per sicurezza try-catch
try
{
// in base a indice scelgo valore posizione e load
switch (i)
{
case 0:
valPos = posAssi.p1;
valLoad = loadAssi.svload1;
break;
case 1:
valPos = posAssi.p2;
valLoad = loadAssi.svload2;
break;
case 2:
valPos = posAssi.p3;
valLoad = loadAssi.svload3;
break;
case 3:
valPos = posAssi.p4;
valLoad = loadAssi.svload4;
break;
case 4:
valPos = posAssi.p5;
valLoad = loadAssi.svload5;
break;
case 5:
valPos = posAssi.p6;
valLoad = loadAssi.svload6;
break;
case 6:
valPos = posAssi.p7;
valLoad = loadAssi.svload7;
break;
case 7:
valPos = posAssi.p8;
valLoad = loadAssi.svload8;
break;
case 8:
valPos = posAssi.p9;
valLoad = loadAssi.svload9;
break;
case 9:
valPos = posAssi.p10;
valLoad = loadAssi.svload10;
break;
case 10:
valPos = posAssi.p11;
valLoad = loadAssi.svload11;
break;
case 11:
valPos = posAssi.p12;
valLoad = loadAssi.svload12;
break;
case 12:
valPos = posAssi.p13;
valLoad = loadAssi.svload13;
break;
case 13:
valPos = posAssi.p14;
valLoad = loadAssi.svload14;
break;
case 14:
valPos = posAssi.p15;
valLoad = loadAssi.svload15;
break;
case 15:
valPos = posAssi.p16;
valLoad = loadAssi.svload16;
break;
case 16:
valPos = posAssi.p17;
valLoad = loadAssi.svload17;
break;
case 17:
valPos = posAssi.p18;
valLoad = loadAssi.svload18;
break;
case 18:
valPos = posAssi.p19;
valLoad = loadAssi.svload19;
break;
case 19:
valPos = posAssi.p20;
valLoad = loadAssi.svload20;
break;
case 20:
valPos = posAssi.p21;
valLoad = loadAssi.svload21;
break;
case 21:
valPos = posAssi.p22;
valLoad = loadAssi.svload22;
break;
case 22:
valPos = posAssi.p23;
valLoad = loadAssi.svload23;
break;
case 23:
valPos = posAssi.p24;
valLoad = loadAssi.svload24;
break;
case 24:
valPos = posAssi.p25;
valLoad = loadAssi.svload25;
break;
case 25:
valPos = posAssi.p26;
valLoad = loadAssi.svload26;
break;
case 26:
valPos = posAssi.p27;
valLoad = loadAssi.svload27;
break;
case 27:
valPos = posAssi.p28;
valLoad = loadAssi.svload28;
break;
case 28:
valPos = posAssi.p29;
valLoad = loadAssi.svload29;
break;
case 29:
valPos = posAssi.p30;
valLoad = loadAssi.svload30;
break;
case 30:
valPos = posAssi.p31;
valLoad = loadAssi.svload31;
break;
case 31:
valPos = posAssi.p32;
valLoad = loadAssi.svload32;
break;
default:
// 2017.03.01 suggerimento Fabio: in CMS_FANUC in advanced compiler options mettere FS30D=1,SIEMENS=1 x leggere + assi?!?
valPos = posAssi.p1;
valLoad = loadAssi.svload1;
break;
}
// popolo valori...
vettAxis[i].mAxLoad.Value = (double)(valLoad.data) / Math.Pow(10, valLoad.dec);
newPos = (double)(valPos.abs.data) / Math.Pow(10, valPos.abs.dec);
vettAxis[i].mAxPosAct.Value = newPos;
vettAxis[i].mAxPosTgt.Value = newPos + (double)(valPos.dist.data) / Math.Pow(10, valPos.dist.dec);
vettAxis[i].mAxFeedAct.Value = FeedRate;
// calcolo distanza e salvo valore...
distPerc = newPos - prevPosAxis[i];
// sistemo direzione +/- (POS/NEG se lineari, CCW/CW se rotativi)
if (distPerc != 0)
{
newDir = Convert.ToInt32(distPerc / Math.Abs(distPerc));
}
else
{
newDir = prevDirAxis[i];
}
// verifico tipo direzione da tipo asse...
tipoAsse = vettAxis[i].mAxType.Value.ToString();
if (tipoAsse == "LINEAR")
{
// ?: conditional operator.
direzione = (newDir > 0) ? "POSITIVE" : "NEGATIVE";
}
else if (tipoAsse == "ROTARY")
{
direzione = (newDir > 0) ? "CLOCKWISE" : "COUNTER_CLOCKWISE";
}
vettAxis[i].mAxDir.Value = direzione;
if (utils.CRB("verbose"))
{
sb.AppendLine(string.Format("Asse {0}: PosAct:{1:N3}, ToGo:{2:N3}{3} | {4}", valPos.abs.name, (double)(valPos.abs.data) / Math.Pow(10, valPos.abs.dec), valPos.dist.name, (double)(valPos.dist.data) / Math.Pow(10, valPos.dist.dec), direzione));
}
// salvo valori vettore prec...
prevPosAxis[i] = newPos;
prevDirAxis[i] = newDir;
//vettAxis[i].mAxMainProc.Value = AxData.AxisMainProc;
//vettAxis[i].mAxIsMaster.Value = AxData.AxisIsMaster;
//vettAxis[i].mAxMastId.Value = AxData.AxisMastId;
vettAxis[i].mAxFeedOver.Value = FeedRateOver;
//vettAxis[i].mAxAccelAct.Value = AxData.AxisAccel;
//vettAxis[i].mAxBattery.Value = AxData.AxisBattery;
}
catch
{
lg.Error(string.Format("Errore in lettura asse {0}", i));
}
}
parentForm.dataMonitor += sb.ToString();
}
}
}