diff --git a/Jenkinsfile b/Jenkinsfile index 5e8f59d..56f37ef 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -15,7 +15,7 @@ pipeline { /* calcolo numero versione... diverso x branch MASTER/DEVELOP */ script { - withEnv(['NEXT_BUILD_NUMBER=460']) { + withEnv(['NEXT_BUILD_NUMBER=461']) { // env.versionNumber = VersionNumber(versionNumberString : '2.2.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true) env.versionNumber = VersionNumber(versionNumberString : '2.2.${BUILD_DATE_FORMATTED, "yyMM"}.${BUILDS_ALL_TIME}', projectStartDate : '2006-01-01', skipFailedBuilds: true, overrideBuildsAllTime: '${NEXT_BUILD_NUMBER}') env.APP_NAME = 'SCMA' diff --git a/MTC_Adapter/SCMA/AdapterPLC/SCM/ESA.cs b/MTC_Adapter/SCMA/AdapterPLC/CMS/EsaKvara.cs similarity index 99% rename from MTC_Adapter/SCMA/AdapterPLC/SCM/ESA.cs rename to MTC_Adapter/SCMA/AdapterPLC/CMS/EsaKvara.cs index b0eb3ac..08e6373 100644 --- a/MTC_Adapter/SCMA/AdapterPLC/SCM/ESA.cs +++ b/MTC_Adapter/SCMA/AdapterPLC/CMS/EsaKvara.cs @@ -7,9 +7,9 @@ using System.Linq; using System.Text; using System.Threading; -namespace SCMA.AdapterPLC.SCM +namespace SCMA.AdapterPLC.CMS { - public class ESA : AdapterGeneric + public class Esa : Generic { /// /// Configurazione valori da leggere IOT_Byte @@ -245,7 +245,7 @@ namespace SCMA.AdapterPLC.SCM /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) - public ESA(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) + public Esa(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) { string iniPath = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("defaultEsaFile")); diff --git a/MTC_Adapter/SCMA/AdapterFanuc.cs b/MTC_Adapter/SCMA/AdapterPLC/CMS/Fanuc.cs similarity index 99% rename from MTC_Adapter/SCMA/AdapterFanuc.cs rename to MTC_Adapter/SCMA/AdapterPLC/CMS/Fanuc.cs index 59d56cb..431c350 100644 --- a/MTC_Adapter/SCMA/AdapterFanuc.cs +++ b/MTC_Adapter/SCMA/AdapterPLC/CMS/Fanuc.cs @@ -4,9 +4,9 @@ using SCMA.AdapterCom; using System; using System.Text; -namespace SCMA +namespace SCMA.AdapterPLC.CMS { - public class AdapterFanuc : AdapterGeneric + public class Fanuc : Generic { /// /// Oggetto MAIN x connessione FANUC @@ -103,7 +103,7 @@ namespace SCMA /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) - public AdapterFanuc(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) + public Fanuc(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) { // !!!HARD CODED!!! aggiunto banco STATUS del 2 processo IN CODA... (4+1)DW=20byte x strobes...!!! Strobes = new byte[20]; diff --git a/MTC_Adapter/SCMA/AdapterOsai.cs b/MTC_Adapter/SCMA/AdapterPLC/CMS/Osai.cs similarity index 99% rename from MTC_Adapter/SCMA/AdapterOsai.cs rename to MTC_Adapter/SCMA/AdapterPLC/CMS/Osai.cs index cc10cf0..33c58a1 100644 --- a/MTC_Adapter/SCMA/AdapterOsai.cs +++ b/MTC_Adapter/SCMA/AdapterPLC/CMS/Osai.cs @@ -5,9 +5,9 @@ using System; using System.Collections.Generic; using System.Text; -namespace SCMA +namespace SCMA.AdapterPLC.CMS { - public class AdapterOsai : AdapterGeneric + public class Osai : Generic { /// /// Oggetto MAIN x connessione OSAI @@ -196,7 +196,7 @@ namespace SCMA /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) - public AdapterOsai(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) + public Osai(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) { // !!!HARD CODED!!! aggiunto banco STATUS del 2 processo IN CODA... (4+1)DW=20byte x strobes...!!! Strobes = new byte[20]; diff --git a/MTC_Adapter/SCMA/AdapterSiemens.cs b/MTC_Adapter/SCMA/AdapterPLC/CMS/Siemens.cs similarity index 99% rename from MTC_Adapter/SCMA/AdapterSiemens.cs rename to MTC_Adapter/SCMA/AdapterPLC/CMS/Siemens.cs index 077c32e..64a4cc9 100644 --- a/MTC_Adapter/SCMA/AdapterSiemens.cs +++ b/MTC_Adapter/SCMA/AdapterPLC/CMS/Siemens.cs @@ -6,9 +6,9 @@ using System; using System.Collections.Generic; using System.Text; -namespace SCMA +namespace SCMA.AdapterPLC.CMS { - public class AdapterSiemens : AdapterGeneric + public class Siemens : Generic { /// /// Oggetto MAIN x connessione SIEMENS @@ -189,7 +189,7 @@ namespace SCMA /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) - public AdapterSiemens(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) + public Siemens(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) { // !!!HARD CODED!!! aggiunto banco STATUS del 2 processo IN CODA... (4+1)DW=20byte x strobes...!!! Strobes = new byte[20]; diff --git a/MTC_Adapter/SCMA/AdapterDemo.cs b/MTC_Adapter/SCMA/AdapterPLC/Demo.cs similarity index 96% rename from MTC_Adapter/SCMA/AdapterDemo.cs rename to MTC_Adapter/SCMA/AdapterPLC/Demo.cs index df595e9..3627529 100644 --- a/MTC_Adapter/SCMA/AdapterDemo.cs +++ b/MTC_Adapter/SCMA/AdapterPLC/Demo.cs @@ -3,9 +3,9 @@ using MTConnect; using SCMA.AdapterCom; using System; -namespace SCMA +namespace SCMA.AdapterPLC { - public class AdapterDemo : AdapterGeneric + public class Demo : Generic { DateTime nextChange; /// @@ -14,7 +14,7 @@ namespace SCMA /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) - public AdapterDemo(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) + public Demo(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) { // !!!HARD CODED!!! aggiunto banco STATUS del 2 processo IN CODA... (4+1)DW=20byte x strobes...!!! Strobes = new byte[20]; diff --git a/MTC_Adapter/SCMA/AdapterGeneric.cs b/MTC_Adapter/SCMA/AdapterPLC/Generic.cs similarity index 99% rename from MTC_Adapter/SCMA/AdapterGeneric.cs rename to MTC_Adapter/SCMA/AdapterPLC/Generic.cs index dc86d86..503c9ce 100644 --- a/MTC_Adapter/SCMA/AdapterGeneric.cs +++ b/MTC_Adapter/SCMA/AdapterPLC/Generic.cs @@ -5,7 +5,7 @@ using System.IO; using System.Linq; using System.Text; -namespace SCMA +namespace SCMA.AdapterPLC { using AdapterCom; using MTC; @@ -520,7 +520,7 @@ namespace SCMA #endregion macro oggetti da istanziare a blocchi da configurazione XML - public class AdapterGeneric + public class Generic { /// /// inizializzo l'oggetto sulla form SULLA BASE DEL FILE DI CONFIGURAZIONE letto @@ -528,7 +528,7 @@ namespace SCMA /// FORM chaimante /// CONFIGURAZIONE adapter /// OGGETTO gestione comunicazione OUT (tipologia e metodi) - public AdapterGeneric(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) + public Generic(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) { lg = LogManager.GetCurrentClassLogger(); lg.Info("Avvio preliminare AdapterGeneric"); diff --git a/MTC_Adapter/SCMA/AdapterPLC/SCM/EsaKvara.cs b/MTC_Adapter/SCMA/AdapterPLC/SCM/EsaKvara.cs new file mode 100644 index 0000000..0e3116b --- /dev/null +++ b/MTC_Adapter/SCMA/AdapterPLC/SCM/EsaKvara.cs @@ -0,0 +1,1158 @@ +using MTC; +using SCMA.AdapterCom; +using SCMCncLib; +using System; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; + +namespace SCMA.AdapterPLC.SCM +{ + public class EsaKvara : Generic + { + /// + /// Configurazione valori da leggere IOT_Byte + /// + public otherData[] mapIOT_Byte; + /// + /// Configurazione valori da leggere IOT_Word + /// + public otherData[] mapIOT_Word; + /// + /// Configurazione valori da leggere IOT_DWord + /// + public otherData[] mapIOT_DWord; + /// + /// Configurazione valori da leggere IOT_String + /// + public otherData[] mapIOT_String; + + /// + /// Oggetto elenco allarmi SOLO CNC (OCCHIO codice numerico = INDICE!!!) + /// + public allarme[] elencoAllarmiCNC; + + /// + /// dimensione buffer BYTE (da file map) + /// + public int numByte = 0; + /// + /// dimensione buffer WORD (da file map) + /// + public int numWord = 0; + /// + /// dimensione buffer DWORD (da file map) + /// + public int numDWord = 0; + /// + /// Dimensione buffer string (FISSO!!!) + /// + public int numString = 255; + + /// + /// Carico file conf dati IOT + /// + protected override void loadOtherFile() + { + base.loadOtherFile(); + loadByteListMap(); + loadWordListMap(); + loadDWordListMap(); + loadStringListMap(); + loadAllarmiCNC(); + } + /// + /// Carico conf vettore dati STRING + /// + private void loadStringListMap() + { + loadConfFile(ref mapIOT_String, filePath("IOTStringFilePath"), 1, ref numString); + // riporto numString a 255! + numString = 255; + } + /// + /// Carico conf vettore dati DWORD + /// + private void loadDWordListMap() + { + loadConfFile(ref mapIOT_DWord, filePath("IOTDWordFilePath"), 1, ref numDWord); + } + /// + /// Carico conf vettore dati WORD + /// + private void loadWordListMap() + { + loadConfFile(ref mapIOT_Word, filePath("IOTWordFilePath"), 1, ref numWord); + } + /// + /// Carico conf vettore dati BYTE + /// + private void loadByteListMap() + { + loadConfFile(ref mapIOT_Byte, filePath("IOTByteFilePath"), 1, ref numByte); + } + /// + /// caricamento allarmi da file (CON RIEMPIMENTO MANCANTI!!!!) + /// + protected void loadAllarmiCNC() + { + if (utils.CRB("verbose")) + { + lg.Info("Inizio caricamento vettore allarmi"); + } + + int totRighe = 0; + string fileName = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("AlarmListCNC")); + string linea; + try + { + string lastLine = File.ReadLines(fileName).Last(); + totRighe = startNumb(lastLine, utils.CRC("testCharSep")); + } + catch + { + totRighe = File.ReadLines(fileName).Count(); + } + // creo un vettore della dimensione corretta... PRENDO IL MASSIMO dei valori... + elencoAllarmiCNC = new allarme[totRighe]; + // ora creo un vettore di allarmi VUOTI... + for (int i = 1; i <= totRighe; i++) + { + elencoAllarmiCNC[i - 1] = new allarme(i.ToString(), "CNC", "WARNING", string.Format("[{0}] MISSING", i), string.Format("[{0}] MISSING", i), string.Format("[{0}] MISSING", i)); + } + // 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) != "#") + { + // recupero numRiga da prima parte linea... + numRiga = startNumb(linea, utils.CRC("testCharSep")); + elencoAllarmiCNC[numRiga - 1] = decodeAlarmLine(linea, utils.CRC("testCharSep")); + } + } + // chiudo file + file.Close(); + if (utils.CRB("verbose")) + { + lg.Info(string.Format("Fine caricamento vettore allarmi CNC: {0} allarmi caricati!", numRiga)); + } + } + /// + /// Restituisce path completo file da chaive configurazione + /// + /// chaive conf x file richiesto + /// + protected string filePath(string keyFile) + { + return string.Format(@"{0}\{1}", utils.confDir, utils.CRS(keyFile)); + } + /// + /// Legge il file di conf di una MAP di informazioni da gestire con lettura set memoria + /// + /// nome vettore memoria + /// file origine + /// dimensione (in byte) della memoria + /// dimensione (in byte) della memoria + protected void loadConfFile(ref otherData[] vettoreConf, string nomeFile, int memSize, ref int numVett) + { + otherData lastData = new otherData(); + int totRighe = 0; + string linea; + totRighe = File.ReadLines(nomeFile).Count(); + // creo un vettore della dimensione corretta... conta anche commenti tanto poi riduco... + vettoreConf = new otherData[File.ReadLines(nomeFile).Count()]; + // carica da file... + StreamReader file = new StreamReader(nomeFile); + // leggo 1 linea alla volta... + int numRiga = 0; + int bitNum = 0; + int byteNum = 0; + while ((linea = file.ReadLine()) != null) + { + // SE non è un commento... + if (linea.Substring(0, 1) != "#") + { + // se finisce per BIT allora processo bit-a-bit... + if (linea.EndsWith("BOOL")) + { + try + { + string[] memIdx = linea.Split(utils.CRC("testCharSep"))[0].Split('.'); + // calcolo bit e byte number... + int.TryParse(memIdx[0], out byteNum); + if (memIdx.Length > 1) + { + int.TryParse(memIdx[1], out bitNum); + } + else + { + bitNum = 0; + } + } + catch + { + byteNum = 0; + bitNum = 0; + } + lastData = decodeBitData(linea, utils.CRC("testCharSep"), byteNum, 1, bitNum); + vettoreConf[numRiga] = lastData; + } + else + { + lastData = decodeOtherData(linea, utils.CRC("testCharSep"), "", 1, memSize); + vettoreConf[numRiga] = lastData; + } + numRiga++; + } + } + // salvo lunghezza file... + try + { + numVett = Convert.ToInt32(lastData.memAddr) + 1; + } + catch + { + numVett = numRiga + 1; + } + // chiudo file + file.Close(); + // ora trimmo vettore al solo numero VERO dei valori caricati... + Array.Resize(ref vettoreConf, numRiga); + + if (utils.CRB("verbose")) + { + lg.Info(string.Format("Fine caricamento vettore di {0} variabili per file {1}", numRiga, nomeFile)); + } + } + + /// + /// oggetto onnessione ESA + /// + protected thdNcEsaGvKvara ncDevice; + /// + /// thread del processo comunicazione esa + /// + protected Thread thdDevice; + + /// + /// estende l'init della classe base... + /// + /// FORM chaimante + /// CONFIGURAZIONE adapter + /// OGGETTO gestione comunicazione OUT (tipologia e metodi) + public EsaKvara(MainForm caller, AdapterConf adpConf, Gateway gatewayObj) : base(caller, adpConf, gatewayObj) + { + string iniPath = string.Format(@"{0}\{1}", utils.confDir, utils.CRS("defaultEsaFile")); + + lg.Info("Start init Adapter ESA dal file {0}", iniPath); + + IniFiles.IniFile EsaIni = new IniFiles.IniFile(iniPath); + + if (utils.CRB("verbose")) + { + lg.Info("step 01: impostato INI File {0}", iniPath); + } + + loadOtherFile(); + + parentForm.commPlcActive = true; + //ncDevice = new thdNcEsaGvKvara(EsaIni, mapIOT_Byte.Length, mapIOT_Word.Length, mapIOT_DWord.Length, 255); // impostato a 255 byte (char) FISSO x la parte stringa... mapIOT_String.Length); + ncDevice = new thdNcEsaGvKvara(EsaIni, numByte, numWord, numDWord, numString); // impostato a 255 byte (char) FISSO x la parte stringa... mapIOT_String.Length); + parentForm.commPlcActive = false; + + if (utils.CRB("verbose")) + { + lg.Info("step 02: avviato thdNcEsaGvKvara da INI File {0}", iniPath); + } + + // inizializzo posizioni assi... + prevPosAxis = new double[adpConf.nAxis]; + prevDirAxis = new int[adpConf.nAxis]; + + // verifica avvio... + lg.Info("ESA: tryConnect"); + tryConnect(); + lg.Info("End init Adapter ESA"); + } + + public override void tryDisconnect() + { + base.tryDisconnect(); + // disconnetto + ncDevice.Disconnect(); + connectionOk = false; + } + + public override void tryConnect() + { + base.tryConnect(); + + // se non già connesso provo a connettermi... + if (!ncDevice.Connected) + { + // provo a collegarmi + if (!ncDevice.Connect()) + { + //altrimenti disconnette... + ncDevice.Disconnect(); + connectionOk = false; + } + else + { + connectionOk = true; + } + } + } + + /// + /// Verifico connessione ESA... + /// + /// + public override bool connectionOk + { + get + { + return ncDevice.Connected; + } + } + + /// + /// Carica ed acquisisce dati del buffer Byte (8 bit) di memoria + /// + protected void getIotMem_Byte() + { + // HARD CODE: forzo path 1 (indice 0...) + int idxPath = 0; + // accodo dati path in DataMonitor...... + StringBuilder sb = new StringBuilder(); + + if (connectionOk) + { + // leggo TUTTO il blocco di memoria + parentForm.commPlcActive = true; + inizio = DateTime.Now; + ncDevice.ReadBufferByte(); + if (utils.CRB("recTime")) + { + TimingData.addResult(string.Format("R{0}-PLC_IOT-Byte", ncDevice.PLC_MemoryAreaIOT_Byte.Length), DateTime.Now.Subtract(inizio).Ticks); + } + + parentForm.commPlcActive = false; + } + else + { + lg.Error("Errore connessione mancante in getIotMem_Byte"); + } + // Processing area BYTE + int numero = 0; + string status = ""; + string pathExeMode = ""; + string pathRunMode = ""; + string ProgAreaRun = ""; + int ProgAreaRunCode = 0; + bool isFeedHold = false; + bool isActive = false; + bool isReady = false; + int bitNum = 0; + int byteNum = 0; + byte currByte; + for (int i = 0; i < mapIOT_Byte.Length; i++) + { + // vado a gestire le variabili BYTE + if (mapIOT_Byte[i].dataType == "BYTE") + { + int.TryParse(mapIOT_Byte[i].memAddr, out byteNum); + if (mapIOT_Byte[i].varName == "IOT_OVRF") + { + FeedRateOver = ncDevice.PLC_MemoryAreaIOT_Byte[byteNum]; + } + else if (mapIOT_Byte[i].varName == "IOT_OVRS") + { + SpeedRateOver = ncDevice.PLC_MemoryAreaIOT_Byte[byteNum]; + } + else if (mapIOT_Byte[i].varName == "IOT_MODECN") + { + // Modo CN:0=Nessuno,1=Manuale,2=Automatico, 3=Pom,4=Mdi,5=SemiAutomatico,6=Rap,7=Test + int modoCn = ncDevice.PLC_MemoryAreaIOT_Byte[byteNum]; + switch (modoCn) + { + case 1: + pathRunMode = "MANUAL"; + break; + case 2: + pathRunMode = "AUTOMATIC"; + break; + case 3: + pathRunMode = "POM"; + break; + case 4: + pathRunMode = "MANUAL_DATA_INPUT"; + break; + case 5: + pathRunMode = "SEMI_AUTOMATIC"; //"SEMIAUTO"; + break; + case 6: + pathRunMode = "RAP"; //"MANUAL"; + break; + case 7: + pathRunMode = "TES"; //"MANUAL"; + break; + case 0: + default: + pathRunMode = "NA"; + break; + } + // salvo run mode + currGateway.updateItemNodeValue(vettPath[idxPath].runModeKey, pathRunMode); + } + else if (mapIOT_Byte[i].varName.StartsWith("IOT_LUB_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_LUB_", "").Replace("_STA", "").Replace("_CNT", "")); + // salvo in vettore SE possibile... + if (numero <= vettLubro.Length) + { + if (mapIOT_Byte[i].varName.EndsWith("_STA")) + { + if (ncDevice.PLC_MemoryAreaIOT_Byte[byteNum] != 0) + { + status = "EMPTY"; + } + else + { + status = "OK"; + } + currGateway.updateItemNodeValue(vettLubro[numero - 1].statusKey, status); + } + else if (mapIOT_Byte[i].varName.EndsWith("_CNT")) + { + currGateway.updateItemNodeValue(vettLubro[numero - 1].countKey, ncDevice.PLC_MemoryAreaIOT_Byte[byteNum]); + } + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Byte[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Byte[i].varName); + } + } + else if (mapIOT_Byte[i].varName.StartsWith("IOT_I_MD_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_I_MD_", "")); + // salvo in vettore SE possibile... + if (numero <= vettUnOp.Length) + { + currGateway.updateItemNodeValue(vettUnOp[numero - 1].loadKey, ncDevice.PLC_MemoryAreaIOT_Byte[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Byte[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Byte[i].varName); + } + } + } + // gestisco le variabili BIT/BOOL + else if (mapIOT_Byte[i].dataType == "BOOL") + { + string[] memIdx = mapIOT_Byte[i].memAddr.Split('.'); + // calcolo bit e byte number... + int.TryParse(memIdx[0], out byteNum); + if (memIdx.Length > 1) + { + int.TryParse(memIdx[1], out bitNum); + } + // leggo byte... + currByte = ncDevice.PLC_MemoryAreaIOT_Byte[byteNum]; + if (mapIOT_Byte[i].varName == "IOT_MACHON") + { + if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) + { + currGateway.updateItemNodeValue("POWER", onOffStatus.ON.ToString()); + } + else + { + currGateway.updateItemNodeValue("POWER", onOffStatus.OFF.ToString()); + } + } + else if (mapIOT_Byte[i].varName == "IOT_READY") + { + isReady = ((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum)); + } + else if (mapIOT_Byte[i].varName == "IOT_EXEC") + { + isActive = ((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum)); + } + else if (mapIOT_Byte[i].varName == "IOT_HOLD") + { + isFeedHold = ((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum)); + } + else if (mapIOT_Byte[i].varName == "IOT_EMG") + { + if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) + { + currGateway.updateItemNodeValue("E_STOP", emStatus.TRIGGERED.ToString()); + } + else + { + currGateway.updateItemNodeValue("E_STOP", emStatus.ARMED.ToString()); + } + } + else if (mapIOT_Byte[i].varName == "IOT_ALRM") + { + if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) + { + // inutile, leggo sempre TUTTI gli allarmi... + } + } + else if (mapIOT_Byte[i].varName.StartsWith("IOT_EXEC_A_")) + { + ProgAreaRun = "OFF"; + ProgAreaRunCode = 0; + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_EXEC_A_", "")); + // salvo SOLO SE ha bit = 1.. + if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) + { + ProgAreaRun = "ON"; + ProgAreaRunCode = 1; + } + currGateway.updateItemNodeCodeValue(vettMemArea[numero - 1].prgRunningKey, ProgAreaRunCode.ToString(), ProgAreaRun); + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Byte[i].varName); + } + } + else if (mapIOT_Byte[i].varName.StartsWith("IOT_VAC_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_Byte[i].varName.Replace("IOT_VAC_", "")); + // controllo SE ha bit = 1 è ON.. + string VacStat = ""; + if (((StFlag8)currByte).HasFlag((StFlag8)Math.Pow(2, bitNum))) + { + VacStat = "ON"; + } + else + { + VacStat = "OFF"; + } + // salvo in vettore SE possibile... + if (numero <= vettVacPump.Length) + { + currGateway.updateItemNodeValue(vettVacPump[numero - 1].statusKey, VacStat); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Byte[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Byte[i].varName); + } + } + } + } + + // imposto exe mode alla fine secondo gerarchia stati... + if (isFeedHold) + { + pathExeMode = "FEED_HOLD"; //"FEEDHOLD"; + } + else if (isActive) + { + pathExeMode = "ACTIVE"; + } + else if (isReady) + { + pathExeMode = "READY"; + } + currGateway.updateItemNodeValue(vettPath[idxPath].exeModeKey, pathExeMode); + // sistemo le stringhe x display + sb.AppendLine(string.Format("RunMode: {0}", pathRunMode)); + sb.AppendLine(string.Format("ExeMode: {0}", pathExeMode)); + sb.AppendLine(string.Format("FeedRateOver: {0} %", FeedRateOver)); + sb.AppendLine(string.Format("SpeedRateOver: {0} %", SpeedRateOver)); + + // update form! + parentForm.dataMonitor_1 += sb.ToString(); + } + /// + /// Carica ed acquisisce dati del buffer WORD (16 bit) di memoria + /// + protected void getIotMem_Word() + { + if (connectionOk) + { + // leggo TUTTO il blocco di memoria + parentForm.commPlcActive = true; + inizio = DateTime.Now; + ncDevice.ReadBufferWord(); + if (utils.CRB("recTime")) + { + TimingData.addResult(string.Format("R{0}-PLC_IOT-Word", ncDevice.PLC_MemoryAreaIOT_Word.Length), DateTime.Now.Subtract(inizio).Ticks); + } + + parentForm.commPlcActive = false; + } + else + { + lg.Error("Errore connessione mancante in getIotMem_Word"); + } + + StringBuilder sb = new StringBuilder(); + int numAlarmCNC = 0; + int numero = 0; + int byteNum = 0; + // Processing area WORD + for (int i = 0; i < mapIOT_Word.Length; i++) + { + int.TryParse(mapIOT_Word[i].memAddr, out byteNum); + + if (mapIOT_Word[i].varName == "IOT_CN_MSG") + { + // leggo codice allarme... + numAlarmCNC = ncDevice.PLC_MemoryAreaIOT_Word[byteNum]; + // controllo, SE è 0 --> normal/niente, altrimenti è l'allarme indicato!!! + if (numAlarmCNC == 0) + { + // init TUTTI i nodi... + currGateway.initAlarms(); + } + else + { + allarme currAllarm = elencoAllarmiCNC[numAlarmCNC - 1]; + // forzo a CNC x siocurezza... + currAllarm.gruppo = currGateway.nCncConditions; + currGateway.addAlarm(currAllarm); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_S_MD_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_S_MD_", "")); + // salvo in vettore SE possibile... + if (numero <= vettUnOp.Length) + { + currGateway.updateItemNodeValue(vettUnOp[numero - 1].speedKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_T_MD_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_T_MD_", "")); + // salvo in vettore SE possibile... + if (numero <= vettUnOp.Length) + { + currGateway.updateItemNodeValue(vettUnOp[numero - 1].toolIdKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_C_TC_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_TC_", "")); + // salvo in vettore SE possibile... + if (numero <= vettUnOp.Length) + { + currGateway.updateItemNodeValue(vettUnOp[numero - 1].numCUKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_C_H_MD_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_H_MD_", "")); + // salvo in vettore SE possibile... + if (numero <= vettUnOp.Length) + { + currGateway.updateItemNodeValue(vettUnOp[numero - 1].accTimeKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_C_H_VAC_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_H_VAC_", "")); + // salvo in vettore SE possibile... + if (numero <= vettVacPump.Length) + { + currGateway.updateItemNodeValue(vettVacPump[numero - 1].workTimeKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_PGMR_A_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_PGMR_A_", "")); + // salvo in vettore SE possibile... + if (numero <= vettMemArea.Length) + { + currGateway.updateItemNodeValue(vettMemArea[numero - 1].numRepKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + else if (mapIOT_Word[i].varName.StartsWith("IOT_C_EXEC_A_")) + { + try + { + numero = Convert.ToInt32(mapIOT_Word[i].varName.Replace("IOT_C_EXEC_A_", "")); + // salvo in vettore SE possibile... + if (numero <= vettMemArea.Length) + { + currGateway.updateItemNodeValue(vettMemArea[numero - 1].numExeKey, ncDevice.PLC_MemoryAreaIOT_Word[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_Word[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_Word[i].varName); + } + } + } + // verifico se nei mandini ho un tool e quanti cambi... + for (int i = 0; i < vettUnOp.Length; i++) + { + if (currGateway.getItemNode(vettUnOp[i].toolIdKey).ToString() != "") + { + sb.AppendLine(string.Format("UnOp_{0}: ToolId: {1} | NumCU: {2}", i + 1, currGateway.getItemNode(vettUnOp[i].toolIdKey), currGateway.getItemNode(vettUnOp[i].numCUKey))); + } + } + // update form! + parentForm.dataMonitor_2 += sb.ToString(); + } + /// + /// Carica ed acquisisce dati del buffer DWORD (32 bit) di memoria + /// + protected void getIotMem_DWord() + { + // accodo dati path in DataMonitor...... + StringBuilder sb = new StringBuilder(); + if (connectionOk) + { + // leggo TUTTO il blocco di memoria + parentForm.commPlcActive = true; + inizio = DateTime.Now; + ncDevice.ReadBufferDWord(); + if (utils.CRB("recTime")) + { + TimingData.addResult(string.Format("R{0}-PLC_IOT-DWord", ncDevice.PLC_MemoryAreaIOT_DWord.Length), DateTime.Now.Subtract(inizio).Ticks); + } + + parentForm.commPlcActive = false; + } + else + { + lg.Error("Errore connessione mancante in getIotMem_DWord"); + } + + int numero = 0; + int byteNum = 0; + double valDouble = 0; + // Processing area WORD + for (int i = 0; i < mapIOT_DWord.Length; i++) + { + int.TryParse(mapIOT_DWord[i].memAddr, out byteNum); + if (mapIOT_DWord[i].varName == "IOT_FEED") + { + FeedRate = BitConverter.ToInt32(BitConverter.GetBytes(ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]), 0); + } + else if (mapIOT_DWord[i].varName.StartsWith("IOT_FEED_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_FEED_", "")); + // salvo in vettore SE possibile... + if (numero <= FeedRateGrp.Length) + { + FeedRateGrp[numero - 1] = BitConverter.ToInt32(BitConverter.GetBytes(ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]), 0); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_DWord[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_DWord[i].varName); + } + } + else if (mapIOT_DWord[i].varName.StartsWith("IOT_C_KU_AX_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_KU_AX_", "")); + // salvo in vettore SE possibile... + if (numero <= vettAxis.Length) + { + currGateway.updateItemNodeValue(vettAxis[numero - 1].distDoneKey, ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_DWord[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_DWord[i].varName); + } + } + else if (mapIOT_DWord[i].varName.StartsWith("IOT_C_KINV_AX_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_KINV_AX_", "")); + // salvo in vettore SE possibile... + if (numero <= vettAxis.Length) + { + currGateway.updateItemNodeValue(vettAxis[numero - 1].invDDoneKey, ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_DWord[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_DWord[i].varName); + } + } + else if (mapIOT_DWord[i].varName.StartsWith("IOT_POS_AX_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_POS_AX_", "")); + // recupero valore pos assi (in micron) + valDouble = BitConverter.ToInt32(BitConverter.GetBytes(ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]), 0); + // salvo in vettore SE possibile... + if (numero <= vettAxis.Length) + { + // riporto il dato in mm (divido x 1000) + currGateway.updateItemNodeValue(vettAxis[numero - 1].posActKey, valDouble / utils.CRI("fattdecimale")); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_DWord[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_DWord[i].varName); + } + } + else if (mapIOT_DWord[i].varName.StartsWith("IOT_C_KREV_MD_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_C_KREV_MD_", "")); + // salvo in vettore SE possibile... + if (numero <= vettUnOp.Length) + { + currGateway.updateItemNodeValue(vettUnOp[numero - 1].kRevKey, ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]); + } + else + { + lg.Error("Errore in inserimento vettore " + mapIOT_DWord[i].varName); + } + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_DWord[i].varName); + } + } + else if (mapIOT_DWord[i].varName.StartsWith("IOT_PLC_MSG_")) + { + // recupero NUMERO + try + { + numero = Convert.ToInt32(mapIOT_DWord[i].varName.Replace("IOT_PLC_MSG_", "")); + // copio allarmi in vettore generale AlarmFlags (dove lo gestisce) 4 byte alla volta + Buffer.BlockCopy(BitConverter.GetBytes(ncDevice.PLC_MemoryAreaIOT_DWord[byteNum]), 0, currGateway.AlarmFlags, numero * 4, 4); + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_DWord[i].varName); + } + } + } + // aggiungo feedrate + sb.AppendLine(string.Format("FeedRate: {0} mm/min", FeedRate)); + // verifico se nei gruppi di feed ho qualcosa di diverso da zero... + for (int i = 0; i < 20; i++) + { + if (FeedRateGrp[i] != 0) + { + sb.AppendLine(string.Format("FeedRate_{1}: {0:00} mm/min", FeedRateGrp[i], i)); + } + } + // update form! + parentForm.dataMonitor_1 += sb.ToString(); + } + /// + /// Carica ed acquisisce dati del buffer STRING di memoria + /// + protected void getIotMem_String() + { + // accodo dati path in DataMonitor...... + StringBuilder sb = new StringBuilder(); + if (connectionOk) + { + // leggo TUTTO il blocco di memoria + parentForm.commPlcActive = true; + inizio = DateTime.Now; + ncDevice.ReadBufferString(); + if (utils.CRB("recTime")) + { + TimingData.addResult(string.Format("R{0}-PLC_IOT-DWord", ncDevice.PLC_MemoryAreaIOT_DWord.Length), DateTime.Now.Subtract(inizio).Ticks); + } + + parentForm.commPlcActive = false; + } + else + { + lg.Error("Errore connessione mancante in getIotMem_DWord"); + } + + // Processing area STRING: OGNI area di memoria... + for (int j = 0; j < mapIOT_String.Length; j++) + { + string valString = ""; + + for (int i = 0; i < numString; i++) + { + try + { + valString += Convert.ToChar(ncDevice.PLC_MemoryAreaIOT_String[j, i]).ToString().Replace("\0", " "); + } + catch (Exception exc) + { + lg.Error(exc, "Errore in decodifica " + mapIOT_String[i].varName); + } + } + // trimmo! + valString = valString.Trim(); + // salvo + currGateway.updateItemNodeCodeValue(vettMemArea[j].prgNameKey, j.ToString(), valString); + // aggiungo nomi programmi... + sb.AppendLine(string.Format("{0}: {1}", mapIOT_String[j].varName, valString)); + } + // update form! + parentForm.dataMonitor_2 += sb.ToString(); + } + public override void getGlobalData() + { + base.getGlobalData(); + } + + /// + /// Processing di TUTTA l'area di memoria configurata e delle variabili derivate... + /// + public override void processAllMemory() + { + // inizializzo data monitor su FORM + parentForm.dataMonitor_1 = ""; + parentForm.dataMonitor_2 = ""; + parentForm.dataMonitor_3 = ""; + + // recupero le varie memorie (prima string che mi serve x area selezionata --> programma selezionato) + getIotMem_String(); + getIotMem_Byte(); + getIotMem_Word(); + getIotMem_DWord(); + + // processo componenti specifici x info... + getUnOp(); + getPath(); + getAxis(); + } + + /// + /// Recupera la speed override x i mandrini (UnOp) + /// + public override void getUnOp() + { + // cicl su UnOp + for (int i = 0; i < currAdpConf.nUnOp; i++) + { + currGateway.updateItemNodeValue(vettUnOp[i].speedOverKey, SpeedRateOver); + } + } + + /// + /// Carica info accessorie assi (direzione, feed, ...) + /// + public override void getAxis() + { + // mostro assi in DataMonitor...... + StringBuilder sb = new StringBuilder(); + + // nuova posizione (per calcoli) + double newPos = 0; + double distPerc = 0; + int newDir = 0; + string tipoAsse = ""; + string direzione = ""; + int numInvAx = 0; + + // leggo in modo "cablato" i dati dei vari assi... + for (int i = 0; i < currAdpConf.nAxis; i++) + { + // verifico: se l'asse appartiene ad un gruppo uso la sua feedrate... + int axGroup = 0; + try + { + axGroup = Convert.ToInt32(currGateway.getItemNode(vettAxis[i].groupKey)); + } + catch + { } + if (axGroup > 0) + { + currGateway.updateItemNodeValue(vettAxis[i].feedrateKey, FeedRateGrp[axGroup - 1]); + } + else + { + currGateway.updateItemNodeValue(vettAxis[i].feedrateKey, FeedRate); + } + + currGateway.updateItemNodeValue(vettAxis[i].feedOverKey, FeedRateOver); + + // calcolo distanza e salvo valore... + newPos = Convert.ToDouble(currGateway.getItemNode(vettAxis[i].posActKey)); + 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 = currGateway.getItemNode(vettAxis[i].typeKey).ToString(); + if (tipoAsse == "LINEAR") + { + // ?: conditional operator. + direzione = (newDir > 0) ? "POSITIVE" : "NEGATIVE"; + } + else if (tipoAsse == "ROTARY") + { + direzione = (newDir > 0) ? "CLOCKWISE" : "COUNTER_CLOCKWISE"; + } + + currGateway.updateItemNodeValue(vettAxis[i].directionKey, direzione); + + // se la direzione è variata salvo il cambio direzione... + if (newDir != prevDirAxis[i]) + { + // recupero num prec... + numInvAx = Convert.ToInt32(istNumInvAssi[i].vcMedian); + numInvAx++; + // salvo "+1" come cambi direzione.... ATTENZIONE servirà che la finestra sia "corta" (tipo 1 sec...) mentre io ne inserisco 3 distanziati di 1/5 sec + istNumInvAssi[i].addValue(DateTime.Now.AddMilliseconds(-400), numInvAx); + istNumInvAssi[i].addValue(DateTime.Now.AddMilliseconds(-200), numInvAx); + istNumInvAssi[i].addValue(DateTime.Now, numInvAx); + } + + if (utils.CRB("verbose")) + { + sb.AppendLine(string.Format("Asse {0}: PosAct:{1:N3} | {2}", i, newPos, direzione)); + } + + // salvo valori vettore prec... + prevPosAxis[i] = newPos; + prevDirAxis[i] = newDir; + } + + parentForm.dataMonitor_3 += sb.ToString(); + } + } +} diff --git a/MTC_Adapter/SCMA/MainForm.cs b/MTC_Adapter/SCMA/MainForm.cs index 35f2022..ccde092 100644 --- a/MTC_Adapter/SCMA/MainForm.cs +++ b/MTC_Adapter/SCMA/MainForm.cs @@ -63,7 +63,7 @@ namespace SCMA /// /// Oggetto x gestione dell'adapter GENERICO (x poter usare metodi di ognuno...) /// - AdapterGeneric agObj; + AdapterPLC.Generic agObj; /// /// configurazione caricata /// @@ -380,38 +380,38 @@ namespace SCMA switch (tipoScelto) { case tipoAdapter.DEMO: - agObj = new AdapterDemo(this, adpConf, currGateway); + agObj = new AdapterPLC.Demo(this, adpConf, currGateway); EnableTab(tabCtrlMain.TabPages[1], true); EnableTab(tabCtrlMain.TabPages[2], true); start.Enabled = true; break; case tipoAdapter.ESAGV: - agObj = new AdapterPLC.SCM.ESA(this, adpConf, currGateway); + agObj = new AdapterPLC.SCM.EsaKvara(this, adpConf, currGateway); EnableTab(tabCtrlMain.TabPages[1], true); EnableTab(tabCtrlMain.TabPages[2], false); start.Enabled = true; break; case tipoAdapter.FANUC: - agObj = new AdapterFanuc(this, adpConf, currGateway); + agObj = new AdapterPLC.CMS.Fanuc(this, adpConf, currGateway); EnableTab(tabCtrlMain.TabPages[1], true); EnableTab(tabCtrlMain.TabPages[2], false); start.Enabled = true; break; case tipoAdapter.OSAI: - agObj = new AdapterOsai(this, adpConf, currGateway); + agObj = new AdapterPLC.CMS.Osai(this, adpConf, currGateway); EnableTab(tabCtrlMain.TabPages[1], true); EnableTab(tabCtrlMain.TabPages[2], false); start.Enabled = true; break; case tipoAdapter.SIEMENS: - agObj = new AdapterSiemens(this, adpConf, currGateway); + agObj = new AdapterPLC.CMS.Siemens(this, adpConf, currGateway); EnableTab(tabCtrlMain.TabPages[1], true); EnableTab(tabCtrlMain.TabPages[2], false); start.Enabled = true; break; case tipoAdapter.ND: default: - agObj = new AdapterDemo(this, adpConf, currGateway); + agObj = new AdapterPLC.Demo(this, adpConf, currGateway); EnableTab(tabCtrlMain.TabPages[1], false); EnableTab(tabCtrlMain.TabPages[2], false); start.Enabled = false; diff --git a/MTC_Adapter/SCMA/SCMA.csproj b/MTC_Adapter/SCMA/SCMA.csproj index d16a2c6..b60b9e9 100644 --- a/MTC_Adapter/SCMA/SCMA.csproj +++ b/MTC_Adapter/SCMA/SCMA.csproj @@ -141,12 +141,13 @@ - - - - - - + + + + + + + @@ -397,9 +398,7 @@ false - - - +