diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs
index 8e65d7e8..faa39363 100644
--- a/IOB-UT-NEXT/Enums.cs
+++ b/IOB-UT-NEXT/Enums.cs
@@ -362,6 +362,11 @@ namespace IOB_UT_NEXT
///
ND,
+ ///
+ /// Adapter MITSUBISHI con EZCnc lib
+ ///
+ MITSUBISHI,
+
///
/// Adapter ModBus TCP generico
///
diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs
index 8af62843..09ce9789 100644
--- a/IOB-WIN-NEXT/AdapterForm.cs
+++ b/IOB-WIN-NEXT/AdapterForm.cs
@@ -1,4 +1,5 @@
using IOB_UT_NEXT;
+using IOB_WIN_NEXT.Iob;
using IOB_WIN_NEXT.IobSoap;
using MapoSDK;
using Newtonsoft.Json;
@@ -1690,6 +1691,11 @@ namespace IOB_WIN_NEXT
start.Enabled = true;
break;
+ case tipoAdapter.MITSUBISHI:
+ iobObj = new Mitsubishi(this, IOBConf);
+ start.Enabled = true;
+ break;
+
case tipoAdapter.MODBUS_TCP:
iobObj = new IobModbusTCP.ModbusTCP(this, IOBConf);
start.Enabled = true;
diff --git a/IOB-WIN-NEXT/DATA/CONF/VL28.ini b/IOB-WIN-NEXT/DATA/CONF/VL28.ini
index e62241bf..7a68a81d 100644
--- a/IOB-WIN-NEXT/DATA/CONF/VL28.ini
+++ b/IOB-WIN-NEXT/DATA/CONF/VL28.ini
@@ -52,6 +52,7 @@ BLINK_FILT=0
[OPTPAR]
EZNC_SYS=EZNC_SYS_MELDAS700L
+ENABLE_PZCOUNT=TRUE
;PZCOUNT_MODE=STD|BIT
;PZCOUNT_MODE=STD.PAR.6711
;PZGTOT_MODE=STD.PAR.6712
@@ -67,8 +68,8 @@ ENABLE_SEND_PZC_BLOCK=TRUE
MIN_SEND_PZC_BLOCK=0
MAX_SEND_PZC_BLOCK=100
; conf cablata set Art/Commessa
-SET_NUM_ART=STD.VAR.501
SET_NUM_COM=STD.VAR.500
+SET_NUM_ART=STD.VAR.501
SET_NUM_PZ=STD.VAR.502
MAX_CHAR_DESC=7
;indica se il numero articolo sia semplicemente il trim dei caratteri alfabetici (chiama comunque server...)
diff --git a/IOB-WIN-NEXT/Iob/Fanuc.cs b/IOB-WIN-NEXT/Iob/Fanuc.cs
index 90d1553f..34223681 100644
--- a/IOB-WIN-NEXT/Iob/Fanuc.cs
+++ b/IOB-WIN-NEXT/Iob/Fanuc.cs
@@ -24,6 +24,7 @@ namespace IOB_WIN_NEXT.Iob
///
public Fanuc(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
+ lgInfo("Start init Fanuc");
// i dati RAW principali sono 6 byte...
RawInput = new byte[6];
diff --git a/IOB-WIN-NEXT/Iob/Mitsubishi.cs b/IOB-WIN-NEXT/Iob/Mitsubishi.cs
new file mode 100644
index 00000000..2d8121d8
--- /dev/null
+++ b/IOB-WIN-NEXT/Iob/Mitsubishi.cs
@@ -0,0 +1,2578 @@
+using EgwProxy.MultiCncLib.CNC;
+using IOB_UT_NEXT;
+using KRcc;
+using MapoSDK;
+using Newtonsoft.Json;
+using Opc.Ua;
+using Org.BouncyCastle.Utilities.Collections;
+using System;
+using System.Collections.Generic;
+using System.Data.SqlTypes;
+using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+
+namespace IOB_WIN_NEXT.Iob
+{
+ public class Mitsubishi : Iob.Generic
+ {
+ #region Public Constructors
+
+ ///
+ /// Controllo specifico da gestire
+ ///
+ public enum SYSTEMTYPE
+ {
+ ///
+ /// M700L
+ ///
+ EZNC_SYS_MELDAS700L = 5,
+ ///
+ /// M700M
+ ///
+ EZNC_SYS_MELDAS700M = 6,
+ ///
+ /// C70
+ ///
+ EZNC_SYS_MELDASC70 = 7,
+ ///
+ /// M800L
+ ///
+ EZNC_SYS_MELDAS800L = 8,
+ ///
+ /// M800M
+ ///
+ EZNC_SYS_MELDAS800M = 9,
+ ///
+ /// C80
+ ///
+ EZNC_SYS_CNCC80 = 10,
+ }
+
+ ///
+ /// Tipo di controllo gestito
+ ///
+ private SYSTEMTYPE sysType = SYSTEMTYPE.EZNC_SYS_MELDAS700L;
+
+ ///
+ /// Indirizzo partenza lettura Var(100/500)
+ ///
+ private int MemVarStart = 500;
+ ///
+ /// Num celle Var da leggere
+ ///
+ private int MemVarNum = 1;
+
+ ///
+ /// Array contenuto memorie Var
+ ///
+ private Dictionary VarDict { get; set; } = new Dictionary();
+
+
+ ///
+ /// Indirizzo partenza lettura Param
+ ///
+ private int ParamStart = 8000;
+ ///
+ /// Num celle Param da leggere
+ ///
+ private int ParamNum = 1;
+ ///
+ /// Array contenuto memorie Param
+ ///
+ private Dictionary ParamDict { get; set; } = new Dictionary();
+
+ ///
+ /// Max num caratteri string ammessi VAR label
+ ///
+ private int maxVarStrLen = 7;
+
+ ///
+ /// Nome amcchina x connessione
+ ///
+ protected string hostName = "EZNC_LOCALHOST";
+
+ ///
+ /// Nome/IP del CN
+ ///
+ protected string ipAddr="";
+ ///
+ /// Porta di comunicazione INT
+ ///
+ protected int ezPort = 683;
+
+
+ ///
+ /// Obj di comunicazione Mitsubishi
+ ///
+ protected EZNCAUTLib.DispEZNcCommunication oEZNcAutCom = null;
+
+ ///
+ /// Estende l'init della classe base...
+ ///
+ ///
+ ///
+ public Mitsubishi(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
+ {
+ lgInfo("Start init Mitsubishi");
+ // gestione invio ritardato contapezzi
+ pzCountDelay = utils.CRI("pzCountDelay");
+ lastPzCountSend = DateTime.Now;
+ lastWarnODL = DateTime.Now;
+
+ // inizializzo correttamente aree memoria secondo CONF - iniFileName
+ IniFile fIni = new IniFile(IOBConf.iniFileName);
+
+ // inizializzo aree di memoria correnti...
+ MemVarStart = fIni.ReadInteger("MEMORY", "AREAV_START", 500);
+ MemVarNum = fIni.ReadInteger("MEMORY", "AREAV_SIZE", 1);
+ ParamStart = fIni.ReadInteger("MEMORY", "PAR_START", 8001);
+ ParamNum = fIni.ReadInteger("MEMORY", "PAR_SIZE", 1);
+
+ // loggo aree di memoria avviate...
+ lgInfo($"Avviata area di memoria Var: {MemVarNum} vars");
+ lgInfo($"Avviata area di memoria Param: {ParamNum} params");
+
+ // fix enable prgName
+ enablePrgName = fIni.ReadBoolean("CNC", "GETPRGNAME", true);
+
+
+
+ // effettuo lettura della conf sigLUT... cercando 1:1 i bit...
+ string currBit = "";
+ string memArea = "";
+ for (int i = 0; i < 8; i++)
+ {
+ currBit = $"BIT{i}";
+ memArea = fIni.ReadString("MEMORY", currBit, "");
+ // se trovo un valore...
+ if (!string.IsNullOrEmpty(memArea))
+ {
+ signLUT.Add(currBit, memArea);
+ }
+ }
+
+ // recupero sysType del controllo, sennò default M700L...
+ string sEZNC_SYS = getOptPar("EZNC_SYS");
+ if (!string.IsNullOrEmpty(sEZNC_SYS))
+ {
+ sysType = (SYSTEMTYPE)Enum.Parse(typeof(SYSTEMTYPE), sEZNC_SYS);
+ }
+ lgInfo($"Start init Mitsubishi | SysType: {sysType}");
+
+
+ // gestione override contapezzi
+ enablePzCountByApp = utils.CRB("enableContapezzi");
+ enablePzCountByIob = (getOptPar("ENABLE_PZCOUNT") == "TRUE");
+ disablePzCountByIob = (getOptPar("DISABLE_PZCOUNT") == "FALSE");
+
+ // gestione override idx articoli...
+ if (!string.IsNullOrEmpty(getOptPar("NUM_ART_CHR_TRIM")))
+ {
+ string NUM_ART_CHR_TRIM = getOptPar("NUM_ART_CHR_TRIM");
+ bool.TryParse(NUM_ART_CHR_TRIM, out numArtCharTrim);
+ }
+ if (!string.IsNullOrEmpty(getOptPar("MAX_CHAR_DESC")))
+ {
+ string MAX_CHAR_DESC = getOptPar("MAX_CHAR_DESC");
+ int.TryParse(MAX_CHAR_DESC, out maxVarStrLen);
+ }
+
+ // leggo conf x ricerca valori memoria da tracciare in log di continuo...
+ mem2trace = fIni.ReadString("OPTPAR", "MEM_2_TRACE", "");
+
+ // è little endian (NON serve conversione)
+ hasBigEndian = false;
+ lgInfoStartup($"Start init Adapter MITSUBISHI | IP {IOBConf.cncIpAddr}:{IOBConf.cncPort} per IOB {IOBConf.codIOB}");
+
+ // Creo oggetto connessione NC
+ parentForm.commPlcActive = true;
+
+ // init oggetto
+ oEZNcAutCom = new EZNCAUTLib.DispEZNcCommunication();
+ int.TryParse(IOBConf.cncPort, out ezPort);
+ ipAddr = IOBConf.cncIpAddr;
+
+#if false
+ // Open communication
+ int iRet = 0;
+ iRet = oEZNcAutCom.SetTCPIPProtocol(ipAddr, ezPort);
+ iRet = oEZNcAutCom.Open3((int)sysType, 1, 10, hostName);
+#endif
+ parentForm.commPlcActive = false;
+
+ // effettuo disconnect + connect...
+ lgInfo("MITSUBISHI startup: tryDisconnect");
+ tryDisconnect();
+ lgInfo("MITSUBISHI startup: tryConnect");
+ tryConnect();
+ if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob))
+ {
+ lgInfo("MITSUBISHI: inizio gestione contapezzi");
+ try
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con
+ // indicazione area)
+ if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE")))
+ {
+ if (getOptPar("PZCOUNT_MODE").StartsWith("STD"))
+ {
+ lgInfo("Init contapezzi MITSUBISHI: pzCntReload(true)");
+ pzCntReload(true);
+ // refresh associazione Macchina - IOB
+ SendM2IOB();
+ // invio altri dati accessori...
+ SendMachineConf();
+ // per adesso imposto lettura MITSUBISHI == contapezzi (poi farà vera lettura...)
+ contapezziPLC = contapezziIOB;
+ }
+ else
+ {
+ contapezziIOB = 0;
+ lgInfo("Contapezzi STD disabilitato: modalità {0}", getOptPar("PZCOUNT_MODE"));
+ }
+ }
+ else
+ {
+ contapezziIOB = 0;
+ lgInfo("Parametro mancante PZCOUNT_MODE");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in contapezzi MITSUBISHI 01");
+ }
+ }
+ // finisco INIT ADAPTER
+ lgInfo("End init Adapter MITSUBISHI");
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Processo i task richiesti e li elimino dalla coda 1:1
+ ///
+ ///
+ public override Dictionary executeTasks(Dictionary task2exe)
+ {
+ // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti...
+ Dictionary taskDone = new Dictionary();
+ if (task2exe != null)
+ {
+ bool taskOk = false;
+ string taskVal = "";
+ string newVal = "";
+ string memAddr = "";
+ int newValInt = 0;
+ // cerco task specifici: se ho startSetup --> imposto bit DBB701.DBB0.4
+ foreach (var item in task2exe)
+ {
+ taskOk = false;
+ taskVal = "";
+ // converto richiesta in enum...
+ taskType tName = taskType.nihil;
+ Enum.TryParse(item.Key, out tName);
+ switch (tName)
+ {
+ case taskType.setArt:
+ case taskType.setComm:
+ lgInfo($"Richiesta scrittura {tName}");
+ // salvo in memoria il valore richiesto...
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ dataConf currMem = memMap.mMapWrite[item.Key];
+ memAddr = currMem.memAddr;
+ taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte";
+ // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
+ memMap.mMapWrite[item.Key].value = newVal;
+ }
+ else
+ {
+ taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})";
+ }
+ }
+ else
+ {
+ taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})";
+ }
+ // salvo in currProd..
+ saveProdData(new KeyValuePair(item.Key, item.Value));
+ upsertKey(item.Key, item.Value);
+ break;
+
+ case taskType.nihil:
+ case taskType.fixStopSetup:
+ case taskType.forceResetPzCount:
+ case taskType.setProg:
+ case taskType.forceSetPzCount:
+ case taskType.sendWatchDogMes2Plc:
+ taskVal = $"taskReq: {tName} | key: {item.Key} | val: {item.Value} | SKIPPED | NO EXEC";
+ lgInfo($"Chiamata senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.setArtNum:
+ lgInfo($"Richiesta scrittura CodART numerico");
+ // in primis faccio una chiamata per tutta la tab SE fosse vuoto il dict
+ // di traduzione
+ if (DictNumArt == null || DictNumArt.Count == 0)
+ {
+ getNumArt("");
+ lgInfo($"Recuperato DictNumArt, trovati {DictNumArt.Count} rec");
+ }
+ // chiamo server x avere decodifica valore INT
+ newVal = getNumArt(item.Value);
+ // se c'è gestione semplificata num articolo --> usa trim dei soli
+ // caratteri alfabetici lasciando numeri..
+ if (numArtCharTrim)
+ {
+ newVal = baseUtils.GetNumbers(item.Value);
+ }
+ // converto int...
+ int.TryParse(newVal, out newValInt);
+ // procedo come il resto cercando mappatura in memMap: recupero dati da memMap...
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ dataConf currMem = memMap.mMapWrite[item.Key];
+ memAddr = currMem.memAddr;
+ taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte";
+ // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
+ memMap.mMapWrite[item.Key].value = newVal;
+ }
+ else
+ {
+ taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})";
+ }
+ }
+ else
+ {
+ taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})";
+ }
+
+ // invio a controller...
+ taskOk = setNumArt(newValInt);
+ //se ho successo rileggo ed eventualmente sistemo valore
+ if (taskOk)
+ {
+ //var rVal = getValByParam("SET_NUM_ART");
+ var rVal = getValByMemAddr(memAddr);
+ if (rVal == newVal)
+ {
+ lgInfo("All OK");
+ // invio aggiornamento x reset richiesta... test!
+ sendOptVal(item.Key, newVal);
+ }
+ else
+ {
+ lgError($"Error | memName: {memAddr} | rVal: {rVal} | newVal: {newVal}");
+ }
+ }
+ else
+ {
+ lgError("Errore in scrittura SetNumArt");
+ }
+ // salvo in currProd..
+ saveProdData(new KeyValuePair(item.Key, newVal));
+ upsertKey(item.Key, item.Value);
+ break;
+
+ case taskType.setCommNum:
+ lgInfo($"Richiesta scrittura cod COMMESSA numerica");
+ // chiamo server x avere decodifica valore INT
+ newVal = getNumComm(item.Value);
+ // converto int...
+ int.TryParse(newVal, out newValInt);
+ //riscrivo senza eventuali zeri...
+ newVal = newValInt > 0 ? $"{newValInt}" : newVal;
+ lgTrace($"Conv.Int numComm | newVal: {newVal} | newValInt: {newValInt}");
+ // procedo come il resto cercando mappatura in memMap: recupero dati da memMap...
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ if (memMap.mMapWrite.ContainsKey(item.Key))
+ {
+ dataConf currMem = memMap.mMapWrite[item.Key];
+ memAddr = currMem.memAddr;
+ taskVal = $"SET task: {item.Key} --> {newVal} | mem: {currMem.memAddr} - {currMem.size} byte";
+ // salvo il nuovo valore nella memoria... così prox invio lo trasmetterà
+ memMap.mMapWrite[item.Key].value = newVal;
+ }
+ else
+ {
+ taskVal = $"NO DATA MEM, SET task: {item.Key} --> {newVal} ({item.Value})";
+ }
+ }
+ else
+ {
+ taskVal = $"NO MemMap found, SET task: {item.Key} --> {newVal} ({item.Value})";
+ }
+
+ // invio a controller...
+ taskOk = setNumCom(newValInt);
+ //se ho successo rileggo ed eventualmente sistemo valore
+ if (taskOk)
+ {
+ //var rVal = getValByParam("SET_NUM_COM");
+ var rVal = getValByMemAddr(memAddr);
+ if (rVal == newVal)
+ {
+ lgInfo("All OK");
+ // invio aggiornamento x reset richiesta... test!
+ sendOptVal(item.Key, newVal);
+ }
+ else
+ {
+ lgError($"Error | memName: {memAddr} | rVal: {rVal} | newVal: {newVal}");
+ }
+ }
+ else
+ {
+ lgError("Errore in scrittura SetNumCom");
+ }
+ // salvo in currProd..
+ saveProdData(new KeyValuePair(item.Key, newVal));
+ upsertKey(item.Key, item.Value);
+ break;
+
+ case taskType.setPzComm:
+ int pzReq = 0;
+ int.TryParse(item.Value, out pzReq);
+ // set pezzi richiesti inizio setup
+ taskOk = setPzComm(pzReq);
+ taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+
+ // salvo in currProd..
+ saveProdData(new KeyValuePair(item.Key, newVal));
+ upsertKey(item.Key, item.Value);
+ break;
+
+ case taskType.startSetup:
+ // reset contapezzi inizio setup
+ taskOk = resetContapezziPLC();
+ taskVal = taskOk ? "RESET: SETUP START" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata startSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.stopSetup:
+ // reset contapezzi fine setup SE ESPLICITAMENTE IMPOSTATO
+ if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET_stopSetup") == "TRUE")
+ {
+ taskOk = resetContapezziPLC();
+ }
+ taskVal = taskOk ? "RESET: SETUP END" : "PZ RESET DISABLED | NO EXEC";
+ lgInfo($"Chiamata stopSetup: taskOk: {taskOk} | taskVal: {taskVal}");
+ break;
+
+ case taskType.setParameter:
+ lgInfo($"Chiamata setParameter | NO processing: taskOk: {taskOk} | taskVal: {taskVal}");
+ taskVal = "setParameter | SKIPPED | NO EXEC";
+ break;
+
+ default:
+ lgInfo($"Chiamata default senza processing: taskOk: {taskOk} | taskVal: {taskVal}");
+ taskVal = "SKIPPED | NO EXEC";
+ break;
+ }
+ // aggiungo task!
+ taskDone.Add(item.Key, taskVal);
+ }
+ }
+ return taskDone;
+ }
+
+ ///
+ /// Wrapper chiamata lettura/scrittura INTERO in area macro...
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool MITSUBISHIMemMacroRW(bool bWrite, Int32 memIndex, ref short Value)
+ {
+ bool answ = false;
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ try
+ {
+ parentForm.commPlcActive = true;
+ // provo ad usare SEMPRE double...
+ short zeroVal = 0;
+ // in primis scrivo reset a zero...
+ answ = MITSUBISHI_ref.F_RW_Macro_Short(bWrite, memIndex, ref zeroVal);
+ // ora scrivo vero valore...
+ answ = MITSUBISHI_ref.F_RW_Macro_Short(bWrite, memIndex, ref Value);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in MITSUBISHIMemMacroRW | Short{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ parentForm.commPlcActive = false;
+ return answ;
+ }
+
+ ///
+ /// Wrapper chiamata lettura/scrittura DOUBLE in area macro...
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool MITSUBISHIMemMacroRW(bool bWrite, Int32 memIndex, ref double Value)
+ {
+ bool answ = false;
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ try
+ {
+ parentForm.commPlcActive = true;
+ short zeroVal = 0;
+ // in primis scrivo reset a zero...
+ answ = MITSUBISHI_ref.F_RW_Macro_Short(bWrite, memIndex, ref zeroVal);
+ // ora scrivo vero valore...
+ answ = MITSUBISHI_ref.F_RW_Macro_Double(bWrite, memIndex, ref Value);
+ }
+ catch (Exception exc)
+ {
+ lgError($"Eccezione in MITSUBISHIMemMacroRW | Double{Environment.NewLine}{exc}");
+ }
+ }
+ }
+ parentForm.commPlcActive = false;
+ return answ;
+ }
+
+ ///
+ /// wrapper chiamata lettura/scrittura SINGOLO BYTE...
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool MITSUBISHIMemRW(bool bWrite, MITSUBISHI.MemType MemType, Int32 memIndex, ref byte Value)
+ {
+ bool answ = false;
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ try
+ {
+ parentForm.commPlcActive = true;
+ answ = MITSUBISHI_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
+ }
+ catch
+ { }
+ }
+ }
+ parentForm.commPlcActive = false;
+ return answ;
+ }
+
+ ///
+ /// wrapper chiamata lettura/scrittura MULTI BYTE...
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool MITSUBISHIMemRW(bool bWrite, MITSUBISHI.MemType MemType, Int32 memIndex, ref byte[] Value)
+ {
+ bool answ = false;
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ try
+ {
+ parentForm.commPlcActive = true;
+ answ = MITSUBISHI_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
+ }
+ catch
+ { }
+ }
+ }
+ parentForm.commPlcActive = false;
+ return answ;
+ }
+
+ ///
+ /// Recupero dati dinamici...
+ ///
+ public override Dictionary getDynData()
+ {
+ Dictionary outVal = new Dictionary();
+ // processo SOLO SE connected...
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ stopwatch.Restart();
+ EgwProxy.MultiCncLib.Focas1.ODBDY2_1 answ = MITSUBISHI_ref.getAllDynData();
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("PROC-DYN-DATA"), stopwatch.ElapsedTicks);
+ }
+
+ try
+ {
+ string actf = answ.actf.ToString();
+ string acts = answ.acts.ToString();
+ //string numAlarm = memName.alarm.ToString();
+ // preparo i singoli valori dell'array...
+ //outVal.Add("DYNDATA", string.Format("{0}#{1}#{2}", actf, acts, numAlarm));
+ outVal.Add("DYNDATA", string.Format("FEED {0}#SPEED_RPM {1}", actf, acts));
+ if (utils.CRB("SendFeedSpeed"))
+ {
+ outVal.Add("FEED", actf);
+ outVal.Add("SPEED_RPM", acts);
+ //outVal.Add("NUM_ALARM", numAlarm);
+ }
+ if (utils.CRB("SendAxPos"))
+ {
+ // salvo le posizioni...
+ EgwProxy.MultiCncLib.Focas1.FAXIS posAx = answ.pos;
+ int[] currPosAbs = posAx.absolute;
+ int i = 0;
+ foreach (var item in currPosAbs)
+ {
+ i++;
+ outVal.Add(string.Format("POS_{0:00}", i), item.ToString());
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in getDynData");
+ }
+ stopwatch.Stop();
+ }
+ }
+ return outVal;
+ }
+
+ ///
+ /// Recupero dati override (da area G che è già stata letta...)
+ ///
+ ///
+ public override Dictionary getOverrides()
+ {
+ Dictionary outVal = new Dictionary();
+ // processo SOLO SE connected...
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ if (utils.CRB("enableMode") && MemBlockG != null && MemBlockG.Length > 0)
+ {
+ outVal.Add("FEED_OVER", MemBlockG[30].ToString());
+ outVal.Add("RAPID_OVER", MemBlockG[12].ToString());
+ }
+ }
+ }
+ return outVal;
+ }
+
+ ///
+ /// Recupero programma in lavorazione
+ ///
+ ///
+ public override string getPrgName()
+ {
+ string prgName = "";
+ // recupero NUOVO prgName...
+ try
+ {
+ // recupero nome programma MAIN
+ prgName = utils.purgedChar2String(MITSUBISHI_ref.getPrgNameMain());
+ // trimmo path del programma, ovvero "CNCMEMUSERPATH1"
+ prgName = prgName.Replace(utils.CRS("basePrgMemPath"), "");
+ lgInfo("Current PROG: {0}", prgName);
+ }
+ catch (Exception exc)
+ {
+ lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc));
+ connectionOk = false;
+ }
+ return prgName;
+ }
+
+ ///
+ /// Recupero programma in lavorazione come Dictionary MITSUBISHI...
+ /// - SYSINFO: (prima KEY globale) TUTTI i valori separati da # (x fare check modifica)
+ /// - altre stringhe: ogni singolo parametro / valore
+ ///
+ ///
+ public override Dictionary getSysInfo()
+ {
+ Dictionary outVal = new Dictionary();
+ stopwatch.Restart();
+ EgwProxy.MultiCncLib.Focas1.ODBSYS answ = MITSUBISHI_ref.getSysInfo();
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("SYS-INFO"), stopwatch.ElapsedTicks);
+ }
+
+ try
+ {
+ string cnc_type = new string(answ.cnc_type);
+ string mt_type = new string(answ.mt_type);
+ string series = new string(answ.series);
+ string version = new string(answ.version);
+ string axes = new string(answ.axes);
+ //short addInfo = memName.addinfo;
+ short max_axis = answ.max_axis;
+ // preparo i singoli valori dell'array...
+ outVal.Add("SYSINFO", string.Format("{0}#{1}#{2}#{3}#{4}#{5}", cnc_type, mt_type, series, version, axes, max_axis));
+ outVal.Add("CNC", cnc_type);
+ outVal.Add("MTT", mt_type);
+ outVal.Add("SER", series);
+ outVal.Add("VER", version);
+ outVal.Add("AXS", string.Format("{0}|{1}", axes, max_axis));
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in getSysInfo");
+ connectionOk = false;
+ }
+ return outVal;
+ }
+
+ ///
+ /// Effettua vero processing contapezzi:
+ /// 6711: pezzi lavorati
+ /// 6712: pezzi lavorati totali
+ /// 6713: pezzi richiesti
+ ///
+ public override void processContapezzi()
+ {
+ if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob))
+ {
+ // procedo SOLO SE ho connessione...
+ if (connectionOk)
+ {
+ try
+ {
+ // controllo di AVERE parametri opzionali x conteggi vari
+ if (cIobConf.optPar.Count > 0)
+ {
+ // contapezzi ATTUALE
+ if (!string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE")))
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT
+ // (Custom, con indicazione area)
+ string memAddr = getOptPar("PZCOUNT_MODE");
+ if (memAddr.StartsWith("STD"))
+ {
+ // inizio verifica area memoria/parametro levando prima parte codice
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ // var di appoggio
+ int cntAddr = 0;
+ object outputVal = new object();
+ // verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
+ if (memAddr.StartsWith("PAR."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 6711;
+ }
+ // processo parametro contapezzi (lavorati)
+ stopwatch.Restart();
+ MITSUBISHI_ref.F_RW_Param_Integer(false, cntAddr, 3, ref outputVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-PAR", 4), stopwatch.ElapsedTicks);
+ }
+ // salvo ultimo conteggio rilevato
+ int newVal = -1;
+ Int32.TryParse(outputVal.ToString(), out newVal);
+ contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
+ }
+ // 2022.05.23 gestione MACRO da testare (Jetco)
+ else if (memAddr.StartsWith("MACRO."))
+ {
+ lgTrace($"Decodifica memoria MACRO | memName: {memAddr}");
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ // processo parametro
+ stopwatch.Restart();
+ double macroVal = 0;
+ MITSUBISHI_ref.F_Read_macro(cntAddr, ref macroVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-MACRO", 5), stopwatch.ElapsedTicks);
+ }
+ // salvo ultimo conteggio rilevato
+ int newVal = -1;
+ Int32.TryParse($"{macroVal}", out newVal);
+ contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
+ }
+ // altrimenti se legge da area memoria specifica leggo da li...
+ // formato tipo STD.D.1604.DW
+ else
+ {
+ memAddressMITSUBISHI areaCounter = new memAddressMITSUBISHI(memAddr);
+ if (isVerboseLog)
+ {
+ lgInfo("processContapezzi [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
+ }
+ // leggo!
+ stopwatch.Restart();
+ // switch x tipo dati --> tipo lettura... e salvo ultimo
+ // conteggio rilevato
+ switch (areaCounter.vType)
+ {
+ case "B":
+ byte valB = 0;
+ MITSUBISHI_ref.F_RW_Byte(false, areaCounter.mType, areaCounter.mPos, ref valB);
+ outputVal = valB;
+ break;
+
+ case "D":
+ ushort valW = 0;
+ MITSUBISHI_ref.F_RW_Word(false, areaCounter.mType, areaCounter.mPos, ref valW);
+ outputVal = valW;
+ break;
+
+ case "DW":
+ uint valDW = 0;
+ MITSUBISHI_ref.F_RW_DWord(false, areaCounter.mType, areaCounter.mPos, ref valDW);
+ if (isVerboseLog)
+ {
+ lgInfo("[1] valDW contapezzi: {0}", valDW);
+ }
+
+ outputVal = valDW;
+ if (isVerboseLog)
+ {
+ lgInfo("[2] outputVal contapezzi: {0}", outputVal);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks);
+ }
+ // salvo...
+ int newVal = -1;
+ Int32.TryParse(outputVal.ToString(), out newVal);
+ contapezziPLC = newVal > -1 ? newVal : contapezziPLC;
+ //if (isVerboseLog)
+ //{
+ lgInfo("[3] contapezziPLC contapezzi: {0}", contapezziPLC);
+ //}
+ }
+ stopwatch.Stop();
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in contapezzi MITSUBISHI 02");
+ connectionOk = false;
+ }
+ }
+ else
+ {
+ lgError("Errore: manca connessione in contapezzi MITSUBISHI");
+ }
+ }
+ }
+
+ ///
+ /// Esegue processing MODE (e nel contempo recupera altri dati dell'area G)
+ ///
+ public override void processMode()
+ {
+ // processo SOLO SE connected...
+ if (connectionOk)
+ {
+ if (MITSUBISHI_ref.Connected)
+ {
+ if (utils.CRB("enableMode") && MemBlockG != null && MemBlockG.Length > 0)
+ {
+ try
+ {
+ // leggo tutto da 0 a 43...
+ int memIndex = 0;
+ // controllo modalità lettura memoria
+ stopwatch.Restart();
+ MITSUBISHIMemRW(R, MITSUBISHI.MemType.G, memIndex, ref MemBlockG);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-G-AREA", MemBlockG.Length), stopwatch.ElapsedTicks);
+ }
+
+ stopwatch.Stop();
+ // verifico modo con valore corrente, se cambia aggiorno...
+ CNC_MODE newMode = decodeG43(MemBlockG[43]);
+ if (newMode != currMode)
+ {
+ // aggiorno!
+ currMode = newMode;
+ // conversione NUM MODE in descrizione da ENUM
+ string descrMode = Enum.GetName(typeof(CNC_MODE), currMode);
+ // accodo x invio
+ string sVal = string.Format("[CNC_MODE]{0}", descrMode);
+ // chiamo accodamento...
+ accodaFLog(sVal, qEncodeFLog("CNC_MODE", descrMode));
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, string.Format("Errore in process Mode G43: {0}{1}", Environment.NewLine, exc));
+ connectionOk = false;
+ stopwatch.Stop();
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Recupero altri counters se ci sono
+ ///
+ public override void processOtherCounters()
+ {
+ try
+ {
+ // controllo di AVERE parametri opzionali x conteggi vari
+ if (cIobConf.optPar.Count > 0)
+ {
+ // gestione con ricerca in memoria Write / optPar...
+ if (string.IsNullOrEmpty(memAddrPzReq))
+ {
+ lgTrace("PzReq disabilitato | NO memConf.Write | NO optPar");
+ }
+ else
+ {
+ sendOptVal(memNamePzReq, getValByMemAddr(memAddrPzReq));
+ }
+ if (string.IsNullOrEmpty(memAddrArt))
+ {
+ lgTrace("Articolo disabilitato | NO memConf.Write | NO optPar");
+ }
+ else
+ {
+ sendOptVal(memNameArt, getValByMemAddr(memAddrArt));
+ }
+ if (string.IsNullOrEmpty(memAddrCom))
+ {
+ lgTrace("Commessa disabilitata | NO memConf.Write | NO optPar");
+ }
+ else
+ {
+ sendOptVal(memNameCom, getValByMemAddr(memAddrCom));
+ }
+ if (string.IsNullOrEmpty(memAddrPzCnt))
+ {
+ lgTrace("PzCount disabilitato | NO memConf.Write | NO optPar");
+ }
+ else
+ {
+ sendOptVal(memNamePzCnt, getValByMemAddr(memAddrPzCnt));
+ }
+ if (string.IsNullOrEmpty(memAddrPzCntTot))
+ {
+ lgTrace("PzCntTOT disabilitato | NO memConf.Write | NO optPar");
+ }
+ else
+ {
+ sendOptVal(memNamePzCntTot, getValByMemAddr(memAddrPzCntTot));
+ }
+ if (string.IsNullOrEmpty(memAddrCaden))
+ {
+ lgTrace("Cadenza disabilitata | NO memConf.Write | NO optPar");
+ }
+ else
+ {
+ sendOptVal(memNameCaden, getValByMemAddr(memAddrCaden));
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Eccezione in processOtherCounters");
+ }
+ }
+
+ ///
+ /// Effettua lettura semafori principale Parametri da
+ /// aggiornare x display in form
+ ///
+ public override void readSemafori(ref newDisplayData currDispData)
+ {
+ DateTime adesso = DateTime.Now;
+ base.readSemafori(ref currDispData);
+ // verifico non sia in veto invio iniziale...
+ if (queueInEnabCurr)
+ {
+ try
+ {
+ if (verboseLog)
+ {
+ lgInfo("inizio read semafori");
+ }
+
+ currDispData.semIn = Semaforo.SV;
+ // ogni lettura inizia da SUA area inizio controllo area R: se ha dati (> 0
+ // byte) --> leggo!
+ if (MemBlockR.Length > 0)
+ {
+ stopwatch.Restart();
+ MITSUBISHIMemRW(R, MITSUBISHI.MemType.R, areaR.startIdx, ref MemBlockR);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-R", MemBlockR.Length), stopwatch.ElapsedTicks);
+ }
+ // log
+ if (verboseLog)
+ {
+ for (int i = 0; i < MemBlockR.Length; i++)
+ {
+ lgInfo(string.Format("MemBlockR{0}: {1}", i, utils.binaryForm(MemBlockR[i])));
+ }
+ }
+ }
+ // controllo area X: se ha dati (> 0 byte) --> leggo!
+ if (MemBlockX.Length > 0)
+ {
+ stopwatch.Restart();
+ MITSUBISHIMemRW(R, MITSUBISHI.MemType.X, areaX.startIdx, ref MemBlockX);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-X", MemBlockX.Length), stopwatch.ElapsedTicks);
+ }
+ // log
+ if (verboseLog)
+ {
+ for (int i = 0; i < MemBlockX.Length; i++)
+ {
+ lgInfo(string.Format("MemBlockX{0}: {1}", i, utils.binaryForm(MemBlockX[i])));
+ }
+ }
+ }
+ // controllo area Y: se ha dati (> 0 byte) --> leggo!
+ if (MemBlockY.Length > 0)
+ {
+ stopwatch.Restart();
+ MITSUBISHIMemRW(R, MITSUBISHI.MemType.Y, areaY.startIdx, ref MemBlockY);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-Y", MemBlockY.Length), stopwatch.ElapsedTicks);
+ }
+ // log
+ if (verboseLog)
+ {
+ for (int i = 0; i < MemBlockY.Length; i++)
+ {
+ lgInfo(string.Format("MemBlockY{0}: {1}", i, utils.binaryForm(MemBlockY[i])));
+ }
+ }
+ }
+ stopwatch.Stop();
+ // salvo il solo BYTE dell'input decifrando il semaforo...
+ decodeToBitmap();
+ reportRawInput(ref currDispData);
+ }
+ catch (Exception exc)
+ {
+ lgError(string.Format("Eccezione in readSemafori:{0}{1}", Environment.NewLine, exc));
+ connectionOk = false;
+ currDispData.semIn = Semaforo.SR;
+ }
+ }
+ else
+ {
+ lgDebug($"[VETO readSemafori] | veto attivo alle {adesso:yyyy.MM.dd HH:mm:ss}");
+ checkVetoQueueIn();
+ }
+ }
+
+ ///
+ /// Effettua reset del contapezzi
+ ///
+ ///
+ public override bool resetContapezziPLC()
+ {
+ bool answ = false;
+ // ...SE abilitato da conf IOB
+ if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_RESET") == "TRUE")
+ {
+ // scrivo valore 0 x il contapezzi
+ try
+ {
+ // contapezzi ATTUALE
+ if (!string.IsNullOrEmpty(getOptPar("PZCOUNT_MODE")))
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con
+ // indicazione area)
+ string memAddr = getOptPar("PZCOUNT_MODE");
+ if (memAddr.StartsWith("STD"))
+ {
+ // inizio verifica area memoria/parametro levando prima parte codice
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ // var di appoggio
+ int cntAddr = 0;
+ // var contapezzi a zero....
+ object newVal = new object();
+ newVal = 0;
+ // verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
+ if (memAddr.StartsWith("PAR."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 6711;
+ }
+
+ // processo RESET contapezzi (lavorati)
+ stopwatch.Restart();
+ MITSUBISHI_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("W{0}-PAR", 4), stopwatch.ElapsedTicks);
+ }
+ }
+ else if (memAddr.StartsWith("MACRO."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 9999;
+ }
+ // processo SET contapezzi (lavorati)
+ stopwatch.Restart();
+ double vTransf = (double)0;
+ answ = MITSUBISHIMemMacroRW(true, cntAddr, ref vTransf);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks);
+ }
+ }
+ // altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
+ else
+ {
+ memAddressMITSUBISHI areaCounter = new memAddressMITSUBISHI(memAddr);
+
+ if (isVerboseLog)
+ {
+ lgInfo("resetContapezziPLC [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
+ }
+ // leggo!
+ stopwatch.Restart();
+ // switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
+ switch (areaCounter.vType)
+ {
+ case "B":
+ byte valB = 0;
+ MITSUBISHI_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB);
+ newVal = valB;
+ break;
+
+ case "D":
+ ushort valW = 0;
+ MITSUBISHI_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW);
+ newVal = valW;
+ break;
+
+ case "DW":
+ uint valDW = 0;
+ MITSUBISHI_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW);
+ break;
+
+ default:
+ break;
+ }
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks);
+ }
+ }
+ stopwatch.Stop();
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in RESET contapezzi MITSUBISHI");
+ connectionOk = false;
+ }
+ answ = true;
+ }
+ return answ;
+ }
+
+ ///
+ /// Override salvataggio valori in memoria...
+ ///
+ /// tipo di DUMP
+ public override void saveMemDump(dumpType tipo)
+ {
+ // se l'area ha una size > 0...
+ if (areaD.arraySize > 0)
+ {
+ dump_MemArea(tipo, MITSUBISHI.MemType.D, areaD.startIdx, areaD.arraySize);
+ }
+ // se l'area ha una size > 0...
+ if (areaR.arraySize > 0)
+ {
+ dump_MemArea(tipo, MITSUBISHI.MemType.R, areaR.startIdx, areaR.arraySize);
+ }
+ // se l'area ha una size > 0...
+ if (areaX.arraySize > 0)
+ {
+ dump_MemArea(tipo, MITSUBISHI.MemType.X, areaX.startIdx, areaX.arraySize);
+ }
+ // se l'area ha una size > 0...
+ if (areaY.arraySize > 0)
+ {
+ dump_MemArea(tipo, MITSUBISHI.MemType.Y, areaY.startIdx, areaY.arraySize);
+ }
+ // se l'area ha una size > 0...
+ if (areaPAR.arraySize > 0)
+ {
+ dump_ParArea(tipo, areaPAR.startIdx, areaPAR.arraySize);
+ }
+ }
+
+ ///
+ /// Effettua impostazione del valore numerico ARTICOLO (specifico MITSUBISHI)
+ ///
+ ///
+ public bool setNumArt(int valReq)
+ {
+ bool answ = false;
+ string memAddr = memAddrArt;
+ lgTrace($"INIT setNumArt | memName: {memAddr}");
+ if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(memAddr))
+ {
+ // scrivo valore richiesto in area configurata
+ try
+ {
+ // var di appoggio
+ int cntAddr = 0;
+ // verifico se si tratta di lettura MACRO... formato tipo MACRO.6711
+ if (memAddr.StartsWith("MACRO."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 9999;
+ }
+ lgTrace($"MACRO | ART Write 01 | memName: {memAddr} | idx: {cntAddr}");
+ // processo SET contapezzi (lavorati)
+ stopwatch.Restart();
+ // comincio scrivendo reset a zero x cominciare...
+
+ double vTransf = (double)valReq;
+ answ = MITSUBISHIMemMacroRW(true, cntAddr, ref vTransf);
+ lgTrace($"MACRO | ART Write 02 | memName: {memAddr} | valReq: {valReq} | vTransf: {vTransf}");
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks);
+ }
+ }
+ stopwatch.Stop();
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in setNumArt MITSUBISHI");
+ connectionOk = false;
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua impostazione del valore numerico COMMESSA (specifico MITSUBISHI)
+ ///
+ ///
+ public bool setNumCom(int valReq)
+ {
+ bool answ = false;
+ // verifico quale modalità sia richiesta
+ string memAddr = memAddrCom;
+ lgTrace($"INIT setNumCom | memName: {memAddr}");
+ if (cIobConf.optPar.Count > 0 && !string.IsNullOrEmpty(memAddr))
+ {
+ lgTrace($"setNumCom | memName: {memAddr} | valReq: {valReq}");
+ // scrivo valore richiesto in area configurata
+ try
+ {
+ // var di appoggio
+ int cntAddr = 0;
+ // verifico se si tratta di lettura MACRO... formato tipo MACRO.6711
+ if (memAddr.StartsWith("MACRO."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 9999;
+ }
+ lgTrace($"MACRO | Com Write 01 | memName: {memAddr} | idx: {cntAddr}");
+ // processo SET contapezzi (lavorati)
+ stopwatch.Restart();
+ double vTransf = (double)valReq;
+ answ = MITSUBISHIMemMacroRW(true, cntAddr, ref vTransf);
+ lgTrace($"MACRO | Com Write 02 | memName: {memAddr} | valReq: {valReq} | vTransf: {vTransf}");
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks);
+ }
+ }
+ stopwatch.Stop();
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in setNumCom MITSUBISHI");
+ connectionOk = false;
+ }
+ answ = true;
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua impostazione del conteggio pezzi richiesti
+ ///
+ ///
+ public override bool setPzComm(int pzReq)
+ {
+ bool answ = false;
+ // ...SE abilitato da conf IOB
+ if (cIobConf.optPar.Count > 0 && getOptPar("ENABLE_PZ_REQ") == "TRUE")
+ {
+ // scrivo valore 0 x il contapezzi
+ try
+ {
+#if false
+ string memAddr = getOptPar("PZREQ_MODE");
+#endif
+ string memAddr = memAddrPzReq;
+ lgTrace($"INIT setPzComm | memName: {memAddr}");
+ // contapezzi ATTUALE
+ if (!string.IsNullOrEmpty(memAddr))
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con
+ // indicazione area)
+ if (memAddr.StartsWith("STD"))
+ {
+ // inizio verifica area memoria/parametro levando prima parte codice
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ // var di appoggio
+ int cntAddr = 0;
+ // var contapezzi a zero....
+ object newVal = new object();
+ newVal = pzReq;
+ // verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
+ if (memAddr.StartsWith("PAR."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 6711;
+ }
+
+ // processo SET contapezzi (lavorati)
+ stopwatch.Restart();
+ MITSUBISHI_ref.F_RW_Param_Integer(true, cntAddr, 3, ref newVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("W{0}-PAR", 4), stopwatch.ElapsedTicks);
+ }
+ }
+ else if (memAddr.StartsWith("MACRO."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ if (cntAddr == 0)
+ {
+ cntAddr = 9999;
+ }
+ lgTrace($"MACRO | Pz Write 01 | memName: {memAddr} | idx: {cntAddr}");
+ // processo SET contapezzi (lavorati)
+ stopwatch.Restart();
+ // se > 2^16 scrivo con INT, sennò con double...
+ short valTrShr = 0;
+ double valTrDbl = 0;
+ if (pzReq < Math.Pow(2, 16))
+ {
+ valTrShr = (short)pzReq;
+ answ = MITSUBISHIMemMacroRW(true, cntAddr, ref valTrShr);
+ //answ = MITSUBISHI_ref.F_RW_Macro_Short(true, cntAddr, ref valTrShr);
+ lgTrace($"MACRO | Com Write 02 SHORT | memName: {memAddr} | pzReq: {pzReq} | valTrShr: {valTrShr}");
+ }
+ // sennò double!
+ else
+ {
+ valTrDbl = (double)pzReq;
+ answ = MITSUBISHIMemMacroRW(true, cntAddr, ref valTrDbl);
+ //answ = MITSUBISHI_ref.F_RW_Macro_Double(true, cntAddr, ref valTrDbl);
+ lgTrace($"MACRO | Com Write 02 DOUBLE | memName: {memAddr} | pzReq: {pzReq} | valTrDbl: {valTrDbl}");
+ }
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, "MACRO-SHORT", stopwatch.ElapsedTicks);
+ }
+ }
+ // altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
+ else
+ {
+ memAddressMITSUBISHI areaCounter = new memAddressMITSUBISHI(memAddr);
+
+ if (isVerboseLog)
+ {
+ lgInfo("setPzComm [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
+ }
+ // leggo!
+ stopwatch.Restart();
+ // switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
+ switch (areaCounter.vType)
+ {
+ case "B":
+ byte valB = (byte)pzReq;
+ MITSUBISHI_ref.F_RW_Byte(true, areaCounter.mType, areaCounter.mPos, ref valB);
+ newVal = valB;
+ break;
+
+ case "D":
+ ushort valW = (ushort)pzReq;
+ MITSUBISHI_ref.F_RW_Word(true, areaCounter.mType, areaCounter.mPos, ref valW);
+ newVal = valW;
+ break;
+
+ case "DW":
+ uint valDW = (uint)pzReq;
+ MITSUBISHI_ref.F_RW_DWord(true, areaCounter.mType, areaCounter.mPos, ref valDW);
+ break;
+
+ default:
+ break;
+ }
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("W-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks);
+ }
+ }
+ stopwatch.Stop();
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError($"Errore in SET PzReq Commessa MITSUBISHI{Environment.NewLine}{exc}");
+ connectionOk = false;
+ }
+ answ = true;
+ }
+ return answ;
+ }
+
+ ///
+ /// Override connessione
+ ///
+ public override void tryConnect()
+ {
+ if (!connectionOk)
+ {
+ // controllo che il ping sia stato tentato almeno pingTestSec fa...
+ if (DateTime.Now.Subtract(lastPING).TotalSeconds > utils.CRI("pingTestSec"))
+ {
+ if (verboseLog || periodicLog)
+ {
+ lgInfo("MITSUBISHI: ConnKO - tryConnect");
+ }
+ // in primis salvo data ping...
+ lastPING = DateTime.Now;
+ // ora PING!!!
+ Ping pingSender = new Ping();
+ IPAddress address = IPAddress.Loopback;
+ IPAddress.TryParse(cIobConf.cncIpAddr, out address);
+ PingReply reply;
+ try
+ {
+ // se != null --> uso address...
+ if (address != null)
+ {
+ reply = pingSender.Send(address, 100);
+ }
+ else
+ {
+ reply = pingSender.Send(cIobConf.cncIpAddr, 100);
+ }
+ }
+ catch
+ {
+ reply = pingSender.Send(IPAddress.Loopback, 100);
+ }
+ // se passa il ping faccio il resto...
+ if (reply.Status == IPStatus.Success)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ // ora provo connessione...
+ parentForm.commPlcActive = true;
+
+ // Open communication
+ int iRet = 0;
+ iRet = oEZNcAutCom.SetTCPIPProtocol(ipAddr, ezPort);
+ iRet = oEZNcAutCom.Open3((int)sysType, 1, 10, hostName);
+ parentForm.commPlcActive = false;
+ lgInfo($"Mitubishi | open Result: {iRet}" );
+ connectionOk = iRet == 0;
+ connectionOk = true;
+ // refresh stato allarmi!!!
+ if (connectionOk)
+ {
+ checkVetoQueueIn();
+ dtAvvioAdp = DateTime.Now;
+ if (adpRunning)
+ {
+ lgInfo("Connessione OK");
+ }
+ }
+ else
+ {
+ lgError("Impossibile procedere, connessione mancante...");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgFatal(string.Format("Errore nella connessione all'adapter MITSUBISHI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc));
+ connectionOk = false;
+ lgInfo(string.Format("Eccezione in TryConnect, Adapter NON running, pausa di {0} msec prima di ulteriori tentativi di riconnessione", utils.CRI("waitRecMSec")));
+ }
+ }
+ else
+ {
+ // loggo no risposta ping ...
+ connectionOk = false;
+ if (verboseLog || periodicLog)
+ {
+ lgInfo(string.Format("Attenzione: controllo PING fallito per IP {0} - {1}", cIobConf.cncPingAddr, reply.Status));
+ }
+ }
+ }
+ }
+ // se non è ancora connesso faccio procesisng memoria caso disconnesso...
+ if (!connectionOk)
+ {
+ // processo semafori ed invio...
+ processMemoryDiscon();
+ }
+ }
+
+ ///
+ /// Override disconnessione
+ ///
+ public override void tryDisconnect()
+ {
+ if (connectionOk)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ // Close.
+ var iRet = oEZNcAutCom.Close();
+ //Release object
+ oEZNcAutCom = null;
+ connectionOk = false;
+ // resetto timing!
+ TimingData.resetData();
+ lgInfo(szStatusConnection);
+ lgInfo("Effettuata disconnessione adapter MITSUBISHI!");
+ }
+ catch (Exception exc)
+ {
+ lgFatal(exc, "Errore nella disconnessione dall'adapter MITSUBISHI");
+ }
+ }
+ else
+ {
+ lgError("IMPOSSIBILE effettuare disconnessione: Connessione non disponibile...");
+ }
+ queueInEnabCurr = false;
+ }
+
+ #endregion Public Methods
+
+ #region Internal Fields
+
+ ///
+ /// LookUpTable di decodifica da CNC a segnali tipo bitmap MAPO
+ ///
+ internal Dictionary signLUT = new Dictionary();
+
+ #endregion Internal Fields
+
+ #region Protected Fields
+
+ ///
+ /// Dati dell'area D
+ ///
+ protected memAreaMITSUBISHI areaD;
+
+ ///
+ /// Dati dell'area PARameters
+ ///
+ protected memAreaMITSUBISHI areaPAR;
+
+ ///
+ /// Dati dell'area R
+ ///
+ protected memAreaMITSUBISHI areaR;
+
+ ///
+ /// Dati dell'area X
+ ///
+ protected memAreaMITSUBISHI areaX;
+
+ ///
+ /// Dati dell'area Y
+ ///
+ protected memAreaMITSUBISHI areaY;
+
+ /////
+ ///// Oggetto MAIN x connessione MITSUBISHI
+ /////
+ //protected MITSUBISHI MITSUBISHI_ref;
+
+ ///
+ /// Area memoria G (copia)
+ ///
+ protected byte[] MemBlockG = new byte[2];
+
+ ///
+ /// Area memoria R (copia)
+ ///
+ protected byte[] MemBlockR = new byte[2];
+
+ ///
+ /// Area memoria X (copia)
+ ///
+ protected byte[] MemBlockX = new byte[2];
+
+ ///
+ /// Area memoria Y (copia)
+ ///
+ protected byte[] MemBlockY = new byte[2];
+
+ #endregion Protected Fields
+
+ #region Protected Methods
+
+ ///
+ /// decodifica il modo dai valori del byte G43
+ ///
+ ///
+ ///
+ protected static CNC_MODE decodeG43(byte currVal)
+ {
+ // hard coded da valori tabellari a MODI definiti in CNC_MODE...
+ CNC_MODE answ = CNC_MODE.ND;
+ switch (currVal)
+ {
+ case 0:
+ answ = CNC_MODE.MDI;
+ break;
+
+ case 1:
+ answ = CNC_MODE.MEN;
+ break;
+
+ case 3:
+ answ = CNC_MODE.EDIT;
+ break;
+
+ case 4:
+ answ = CNC_MODE.HANDLE_INC;
+ break;
+
+ case 5:
+ answ = CNC_MODE.JOG;
+ break;
+
+ case 6:
+ answ = CNC_MODE.TJOG;
+ break;
+
+ case 7:
+ answ = CNC_MODE.THND;
+ break;
+
+ case 33:
+ answ = CNC_MODE.RMT;
+ break;
+
+ case 133:
+ answ = CNC_MODE.REF;
+ break;
+
+ default:
+ answ = CNC_MODE.ND;
+ break;
+ }
+ return answ;
+ }
+
+ ///
+ /// Metodo da overridare x scrivere DAVVERO i parametri sul PLC
+ ///
+ ///
+ protected override void plcWriteParams(ref List updatedPar)
+ {
+ lgTrace($"plcWriteParams: richiesta per {updatedPar.Count} params");
+ foreach (var item in updatedPar)
+ {
+ lgInfo($"ITEM | {item.uid} | {item.value}");
+ // salvo i valori ricevuti
+ upsertKey(item.uid, item.reqValue);
+ // se i valori richiesto e fatto corrispondono... resetto!
+ if (item.reqValue.Trim() == item.value.Trim())
+ {
+ // resetto richiesta!
+ item.reqValue = "";
+ }
+ }
+ }
+
+ #endregion Protected Methods
+
+ #region Private Properties
+
+ private string memAddrArt
+ {
+ get
+ {
+ string memAddr = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("setArtNum"))
+ {
+ memAddr = memMap.mMapWrite["setArtNum"].memAddr;
+ }
+ // se vuoto provo altra alternativa...
+ if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setArt"))
+ {
+ memAddr = memMap.mMapWrite["setArt"].memAddr;
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memAddr))
+ {
+ memAddr = getOptPar("SET_NUM_ART");
+ }
+ // bonifica variabile da definizione STD iniziale...
+ if (memAddr.StartsWith("STD"))
+ {
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ return memAddr;
+ }
+ }
+
+ private string memAddrCaden
+ {
+ get
+ {
+ string memAddr = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("Cadenza"))
+ {
+ memAddr = memMap.mMapWrite["Cadenza"].memAddr;
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memAddr))
+ {
+ memAddr = getOptPar("PZCAD_MODE");
+ }
+ // bonifica variabile da definizione STD iniziale...
+ if (memAddr.StartsWith("STD"))
+ {
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ return memAddr;
+ }
+ }
+
+ private string memAddrCom
+ {
+ get
+ {
+ string memAddr = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("setCommNum"))
+ {
+ memAddr = memMap.mMapWrite["setCommNum"].memAddr;
+ }
+ // se vuoto provo altra alternativa...
+ if (string.IsNullOrEmpty(memAddr) && memMap.mMapWrite.ContainsKey("setComm"))
+ {
+ memAddr = memMap.mMapWrite["setComm"].memAddr;
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memAddr))
+ {
+ memAddr = getOptPar("SET_NUM_COM");
+ }
+ // bonifica variabile da definizione STD iniziale...
+ if (memAddr.StartsWith("STD"))
+ {
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ return memAddr;
+ }
+ }
+
+ private string memAddrPzCnt
+ {
+ get
+ {
+ string memAddr = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("ContatoreParziale"))
+ {
+ memAddr = memMap.mMapWrite["ContatoreParziale"].memAddr;
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memAddr))
+ {
+ memAddr = getOptPar("PZCOUNT_MODE");
+ }
+ // bonifica variabile da definizione STD iniziale...
+ if (memAddr.StartsWith("STD"))
+ {
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ return memAddr;
+ }
+ }
+
+ private string memAddrPzCntTot
+ {
+ get
+ {
+ string memAddr = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto"))
+ {
+ memAddr = memMap.mMapWrite["ContatoreAssoluto"].memAddr;
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memAddr))
+ {
+ memAddr = getOptPar("PZGTOT_MODE");
+ }
+ // bonifica variabile da definizione STD iniziale...
+ if (memAddr.StartsWith("STD"))
+ {
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ return memAddr;
+ }
+ }
+
+ private string memAddrPzReq
+ {
+ get
+ {
+ string memAddr = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("setPzComm"))
+ {
+ memAddr = memMap.mMapWrite["setPzComm"].memAddr;
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memAddr))
+ {
+ memAddr = getOptPar("PZREQ_MODE");
+ }
+ // bonifica variabile da definizione STD iniziale...
+ if (memAddr.StartsWith("STD"))
+ {
+ memAddr = memAddr.Replace("STD.", "");
+ }
+ return memAddr;
+ }
+ }
+
+ private string memNameArt
+ {
+ get
+ {
+ string memName = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("setArtNum"))
+ {
+ memName = "setArtNum";
+ }
+ // se vuoto provo altra alternativa...
+ if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setArt"))
+ {
+ memName = "setArt";
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memName))
+ {
+ memName = "PZ_COUNT";
+ }
+ return memName;
+ }
+ }
+
+ private string memNameCaden
+ {
+ get
+ {
+ string memName = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("Cadenza"))
+ {
+ memName = "Cadenza";
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memName))
+ {
+ memName = "CICLE_CAD";
+ }
+ return memName;
+ }
+ }
+
+ private string memNameCom
+ {
+ get
+ {
+ string memName = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("setCommNum"))
+ {
+ memName = "setCommNum";
+ }
+ // se vuoto provo altra alternativa...
+ if (string.IsNullOrEmpty(memName) && memMap.mMapWrite.ContainsKey("setComm"))
+ {
+ memName = "setComm";
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memName))
+ {
+ memName = "SET_NUM_COM";
+ }
+ return memName;
+ }
+ }
+
+ private string memNamePzCnt
+ {
+ get
+ {
+ string memName = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("ContatoreParziale"))
+ {
+ memName = "ContatoreParziale";
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memName))
+ {
+ memName = "PZ_COUNT";
+ }
+ return memName;
+ }
+ }
+
+ private string memNamePzCntTot
+ {
+ get
+ {
+ string memName = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("ContatoreAssoluto"))
+ {
+ memName = "ContatoreAssoluto";
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memName))
+ {
+ memName = "PZ_GTOT";
+ }
+ return memName;
+ }
+ }
+
+ private string memNamePzReq
+ {
+ get
+ {
+ string memName = "";
+ if (memMap != null && memMap.mMapWrite != null)
+ {
+ //cerco in primis modalità NUM altrimenti standard...
+ if (memMap.mMapWrite.ContainsKey("setPzComm"))
+ {
+ memName = "setPzComm";
+ }
+ }
+ // se non trovato... leggo da OPT_PAR
+ if (string.IsNullOrEmpty(memName))
+ {
+ memName = "PZ_REQ";
+ }
+ return memName;
+ }
+ }
+
+ #endregion Private Properties
+
+ #region Private Methods
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ ///
+ private void decodeToBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+ if (connectionOk)
+ {
+ // SE SI E' CONNESSO al MITSUBISHI allora è 1=powerON...
+ if (MITSUBISHI_ref.Connected)
+ {
+ B_input += 1 << 0;
+ }
+
+ // decodifico impiegando dictionary... cercando il TIPO di memoria & co...
+ string bKey = "";
+ string bVal = "";
+ char area;
+ // valore INVERTED (default è false)
+ bool invSignal = false;
+ string memArea = "";
+ string[] memIdx;
+ int bitNum = 0;
+ int byteNum = 0;
+ int byte2check = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ bKey = string.Format("BIT{0}", i);
+ // cerco se ci sia in LUT
+ if (signLUT.ContainsKey(bKey))
+ {
+ // recupero nome variabile...
+ bVal = signLUT[bKey];
+ // se l'area è PZCOUNT... processo PUNTUALMENTE il CONTAPEZZI...
+ if (bVal.StartsWith("PZCOUNT"))
+ {
+ // procedo SOLO SE è enabled IOB
+ if (IobOnline)
+ {
+ try
+ {
+ currODL = utils.callUrl(urlGetCurrODL);
+ // solo SE HO un ODL...
+ if (string.IsNullOrEmpty(currODL) || currODL == "0")
+ {
+ if (periodicLog)
+ {
+ lgInfo(string.Format("MITSUBISHI | Lettura ODL andata a vuoto: currODL: {0}", currODL));
+ }
+ }
+ else
+ {
+ // se variato o scaduto timeout log...
+ if (periodicLog || ($"{currIdxODL}" != currODL))
+ {
+ lgInfo(string.Format("MITSUBISHI | Lettura ODL, currODL: {0} --> currIdxODL prec: {1}", currODL, currIdxODL));
+ }
+ // provo a salvare nuovo ODL
+ int.TryParse(currODL, out currIdxODL);
+ }
+ }
+ catch (Exception exc)
+ {
+ if (DateTime.Now.Subtract(lastWarnODL).TotalSeconds > 15)
+ {
+ lgError(exc, "Errore in fase di chiamata URL x ODL corrente | URL chiamato: {0}", urlGetCurrODL);
+ lastWarnODL = DateTime.Now;
+ }
+ }
+ }
+ else
+ {
+ // imposto currODL a vuoto!
+ currODL = "";
+ if (periodicLog)
+ {
+ lgInfo($"MITSUBISHI | Lettura ODL non effettuata: IobOnline: {IobOnline} | currODL impostato a vuoto");
+ }
+ }
+ if (!string.IsNullOrEmpty(currODL) && currODL != "0")
+ {
+ // controllo se è passato intervallo minimo tra 2
+ // controlli/elaborazioni x distanziare invio e ridurre letture
+ if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
+ {
+ // se sono differenti MOSTRO...
+ if (contapezziPLC != contapezziIOB)
+ {
+ // registro contapezzi
+ lgInfo($"Differenza Contapezzi: contapezziPLC: {contapezziPLC} | contapezziIOB {contapezziIOB}");
+ }
+
+ if ((enablePzCountByApp || enablePzCountByIob) && !(disablePzCountByIob))
+ {
+ // verifico se variato contapezzi...
+ if (contapezziPLC > contapezziIOB)
+ {
+ // salvo nuovo contapezzi (incremento di 1...) +
+ // richiesta refresh conteggio
+ contapezziIOB++;
+ needRefreshPzCount = true;
+ // salvo in semaforo!
+ B_input += 1 << 2;
+ // registro contapezzi
+ lgInfo($"contapezziPLC MITSUBISHI: {contapezziPLC} | contapezziIOB {contapezziIOB}");
+ }
+ // invio a server contapezzi (aggiornato)
+ string retVal = utils.callUrl(urlSetPzCount + contapezziIOB.ToString());
+ // verifica se tutto OK
+ if (retVal != contapezziIOB.ToString())
+ {
+ // errore salvataggio contapezzi
+ lgInfo($"Errore salvataggio Contapezzi MITSUBISHI: contapezziPLC {contapezziPLC} | contapezziIOB {contapezziIOB} | risposta: {retVal}");
+ // rileggo il counter pezzi da server
+ pzCntReload(true);
+ }
+ // resetto timer...
+ lastPzCountSend = DateTime.Now;
+ }
+ }
+ }
+ else
+ {
+ if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
+ {
+ lgInfo($"Attenzione: mancanza ODL non procedo con gestione contapezzi. contapezziPLC MITSUBISHI: {contapezziPLC} | contapezziIOB {contapezziIOB}");
+ // resetto timer...
+ lastPzCountSend = DateTime.Now;
+ }
+ }
+ }
+ else // area "normale" byte.bit
+ {
+ // di norma è segnale normale => 1, altrimenti inverse => 0...
+ invSignal = false;
+ // cerco se sia inverse (primo char "!") --> registro e elimino char...
+ invSignal = bVal.StartsWith("!");
+ // se è da tracciare...
+ if (mem2trace.Contains($"|{bKey}|"))
+ {
+ if (invSignal)
+ {
+ lgTrace($"Segnale invertito | bVal: {bVal}");
+ }
+ }
+ // tolgo comunque inversione...
+ bVal = bVal.Replace("!", "");
+ // recupero area...
+ area = bVal[0];
+ // altrimenti decodifico area...
+ memArea = bVal.Substring(1, bVal.Length - 1);
+ memIdx = memArea.Split('.');
+ // calcolo bit e byte number...
+ int.TryParse(memIdx[0], out byteNum);
+ if (memIdx.Length > 1)
+ {
+ int.TryParse(memIdx[1], out bitNum);
+ }
+ // in base al nome cerco in una delle aree.. e prendo solo solo quel bit
+ // di quel byte...
+ switch (area)
+ {
+ case 'G':
+ byte2check = MemBlockG[byteNum];
+ break;
+
+ case 'R':
+ byte2check = MemBlockR[byteNum];
+ break;
+
+ case 'X':
+ byte2check = MemBlockX[byteNum];
+ break;
+
+ case 'Y':
+ byte2check = MemBlockY[byteNum];
+ break;
+
+ default:
+ break;
+ }
+ // a secondo che sia segnale normale o inverso...
+ if (invSignal)
+ {
+ // controllo se il bit sia NON attivo (basso)... == 0...
+ if ((byte2check & (1 << bitNum)) == 0)
+ {
+ B_input += 1 << i;
+ }
+ }
+ else
+ {
+ // controllo se il bit sia attivo (alto)... != 0
+ if ((byte2check & (1 << bitNum)) != 0)
+ {
+ B_input += 1 << i;
+ }
+ }
+
+ // se è da tracciare...
+ if (mem2trace.Contains($"|{bKey}|"))
+ {
+ var bMapAct = Convert.ToString(byte2check, 2).PadLeft(8, '0');
+ var bMapReq = Convert.ToString((1 << bitNum), 2).PadLeft(8, '0');
+ lgTrace($"Valore | bKey: {bKey} | bVal: {bVal} | byte: {bMapAct} | tgt: {bMapReq} | B_input: {B_input}");
+ }
+ }
+ }
+ }
+ }
+ // log opzionale!
+ if (verboseLog)
+ {
+ lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
+ }
+ }
+
+ ///
+ /// Dump area D della memoria
+ ///
+ /// tipo di DUMP: START (sovrascrivendo) / SAMPLE (salva tanti campionamenti)
+ /// tipo memoria
+ /// area memoria di partenza
+ /// dimensione memoria
+ private void dump_MemArea(dumpType tipo, MITSUBISHI.MemType tipoMem, int memIndex, int memSizeByte)
+ {
+ DateTime adesso = DateTime.Now;
+ string nomeFileB = "";
+ string nomeFileW = "";
+ string nomeFileDW = "";
+ Dictionary mappaValori = new Dictionary();
+ // per sicurezza verifico < 9999 byte
+ if (memSizeByte > 9999)
+ {
+ memSizeByte = 9999;
+ }
+ // leggo TUTTI i (MAX 9999) byte della memoria D...
+ byte[] MemBlockCurr = new byte[memSizeByte];
+ if (verboseLog)
+ {
+ lgInfo("START MemDump", tipoMem);
+ }
+
+ stopwatch.Restart();
+ MITSUBISHIMemRW(R, tipoMem, memIndex, ref MemBlockCurr);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-{1}", MemBlockCurr.Length, tipoMem), stopwatch.ElapsedTicks);
+ }
+
+ if (verboseLog)
+ {
+ lgInfo("END MemDump", tipoMem);
+ }
+
+ // seconda del tipo di lettura definisco i nomi delle variabili...
+ if (tipo == dumpType.SAMPLE)
+ {
+ nomeFileB = string.Format(@"{0}\SAMPLES\{1}_{2}_Byte_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, cIobConf.codIOB, tipoMem, adesso);
+ nomeFileW = string.Format(@"{0}\SAMPLES\{1}_{2}_W_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, cIobConf.codIOB, tipoMem, adesso);
+ nomeFileDW = string.Format(@"{0}\SAMPLES\{1}_{2}_DW_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, cIobConf.codIOB, tipoMem, adesso);
+ }
+ else
+ {
+ // salvo in file i dati letti come BYTE
+ nomeFileB = string.Format(@"{0}\{1}_{2}_Byte.dat", utils.dataDatDir, cIobConf.codIOB, tipoMem);
+ nomeFileW = string.Format(@"{0}\{1}_{2}_W.dat", utils.dataDatDir, cIobConf.codIOB, tipoMem);
+ nomeFileDW = string.Format(@"{0}\{1}_{2}_DW.dat", utils.dataDatDir, cIobConf.codIOB, tipoMem);
+ }
+
+ // salvo in file i dati letti come BYTE
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockCurr.Length; i++)
+ {
+ // versione pre dotNet8 (che usa "b" come stringa formato std)
+ var bitMap = Convert.ToString(MemBlockCurr[i], 2).PadLeft(8, '0');
+ mappaValori.Add($"[{i:0000}]", $"{bitMap}={MemBlockCurr[i]}");
+ //mappaValori.Add($"[{i:0000}]", $"{MemBlockCurr[i]:b}={MemBlockCurr[i]}");
+ }
+ utils.WritePlain(mappaValori, nomeFileB);
+
+ // salvo in file i dati letti come Word (2byte)
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockCurr.Length / 2; i++)
+ {
+ mappaValori.Add($"[{i:0000}]", BitConverter.ToUInt16(MemBlockCurr, i * 2).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFileW);
+
+ // salvo in file i dati letti come DWord (4byte)
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockCurr.Length / 4; i++)
+ {
+ mappaValori.Add($"[{i:0000}]", BitConverter.ToUInt32(MemBlockCurr, i * 4).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFileDW);
+ }
+
+ ///
+ /// Dump area PARAMETRI
+ ///
+ /// tipo di DUMP: START (sovrascrivendo) / SAMPLE (salva tanti campionamenti)
+ /// Parametro di partenza
+ /// Numero parametri da esportare... memoria
+ private void dump_ParArea(dumpType tipo, int memIndex, int numPar)
+ {
+ DateTime adesso = DateTime.Now;
+ string nomeFile = "";
+ Dictionary mappaValori = new Dictionary();
+ // per sicurezza verifico < 9999 parametri
+ if (numPar > 9999)
+ {
+ numPar = 9999;
+ }
+
+ // leggo TUTTI i (MAX 9999) byte della memoria D...
+ object[] paramsArray = new object[numPar];
+ if (verboseLog)
+ {
+ lgInfo("START ParamDump");
+ }
+
+ stopwatch.Restart();
+ for (int i = 0; i < numPar; i++)
+ {
+ MITSUBISHI_ref.F_RW_Param_Integer(false, memIndex + i, 3, ref paramsArray[i]);
+ }
+
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-PAR", 4 * numPar), stopwatch.ElapsedTicks);
+ }
+
+ if (verboseLog)
+ {
+ lgInfo("END ParamDump");
+ }
+
+ // seconda del tipo di lettura definisco i nomi delle variabili...
+ if (tipo == dumpType.SAMPLE)
+ {
+ nomeFile = string.Format(@"{0}\SAMPLES\{1}_{2}_{3:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, cIobConf.codIOB, "PAR", adesso);
+ }
+ else
+ {
+ nomeFile = string.Format(@"{0}\{1}_{2}.dat", utils.dataDatDir, cIobConf.codIOB, "PAR");
+ }
+
+ // salvo in file i dati letti
+ mappaValori = new Dictionary();
+ for (int i = 0; i < paramsArray.Length; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), paramsArray[i].ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+ }
+
+ ///
+ /// Recupera il valore INT dal nome del parametro per successivo processing
+ ///
+ ///
+ ///
+ private string getValByMemAddr(string memAddr)
+ {
+ lgTrace($"inizio getValByMemAddr | memAddr: {memAddr}");
+ string answ = "";
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
+#if true
+ if (memAddr.StartsWith("STD"))
+ {
+ // inizio verifica area memoria/parametro levando prima parte codice
+ memAddr = memAddr.Replace("STD.", "");
+ }
+#endif
+ // var di appoggio
+ int cntAddr = 0;
+ object outputVal = new object();
+ // verifico se si tratta di lettura parametro... formato tipo STD.PAR.6711
+ if (memAddr.StartsWith("PAR."))
+ {
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("PAR.", ""), out cntAddr);
+ // processo parametro
+ stopwatch.Restart();
+ MITSUBISHI_ref.F_RW_Param_Integer(false, cntAddr, 3, ref outputVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R{0}-PAR", 4), stopwatch.ElapsedTicks);
+ }
+ // salvo valore
+ answ = outputVal.ToString();
+ }
+ // 2022.05.23 gestione MACRO da testare (Jetco)
+ else if (memAddr.StartsWith("MACRO."))
+ {
+ double macroVal = 0;
+ // recupero parametro...
+ int.TryParse(memAddr.Replace("MACRO.", ""), out cntAddr);
+ lgTrace($"MACRO | Read 01 | memName: {memAddr} | idx: {cntAddr} | macroVal: {macroVal}");
+ // processo parametro
+ stopwatch.Restart();
+ MITSUBISHI_ref.F_Read_macro(cntAddr, ref macroVal);
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, "R-MACRO", stopwatch.ElapsedTicks);
+ }
+ // salvo valore
+ answ = macroVal.ToString();
+ lgTrace($"MACRO | Read 02 | memName: {memAddr} | idx: {cntAddr} | macroVal: {macroVal}");
+ }
+ // altrimenti se legge da area memoria specifica leggo da li... formto tipo STD.D.1604.DW
+ else
+ {
+ memAddressMITSUBISHI areaCounter = new memAddressMITSUBISHI(memAddr);
+
+ if (isVerboseLog)
+ {
+ lgInfo("getValByParam [0] area memoria: {0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType);
+ }
+
+ // leggo!
+ stopwatch.Restart();
+ // switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
+ switch (areaCounter.vType)
+ {
+ case "B":
+ byte valB = 0;
+ MITSUBISHI_ref.F_RW_Byte(false, areaCounter.mType, areaCounter.mPos, ref valB);
+ outputVal = valB;
+ break;
+
+ case "D":
+ ushort valW = 0;
+ MITSUBISHI_ref.F_RW_Word(false, areaCounter.mType, areaCounter.mPos, ref valW);
+ outputVal = valW;
+ break;
+
+ case "DW":
+ uint valDW = 0;
+ MITSUBISHI_ref.F_RW_DWord(false, areaCounter.mType, areaCounter.mPos, ref valDW);
+ if (isVerboseLog)
+ {
+ lgInfo("[1] valDW PAR: {0}", valDW);
+ }
+
+ outputVal = valDW;
+ if (isVerboseLog)
+ {
+ lgInfo("[2] outputVal PAR: {0}", outputVal);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(cIobConf.codIOB, string.Format("R-{0}.{1}.{2}", areaCounter.mType, areaCounter.mPos, areaCounter.vType), stopwatch.ElapsedTicks);
+ }
+
+ // salvo...
+ answ = outputVal.ToString();
+ if (isVerboseLog)
+ {
+ lgInfo($"[3] Mem letta: {memAddr} | {answ}");
+ }
+ }
+ stopwatch.Stop();
+ return answ;
+ }
+
+ ///
+ /// Recupera il valore INT dal nome del parametro per successivo processing
+ ///
+ ///
+ ///
+ private string getValByParam(string varName)
+ {
+ string memAddr = getOptPar(varName);
+ string answ = getValByMemAddr(memAddr);
+ if (isVerboseLog)
+ {
+ lgInfo($"[3] PAR letto: {varName} | {answ}");
+ }
+ return answ;
+ }
+
+ #endregion Private Methods
+ }
+}
\ No newline at end of file
diff --git a/TestPrelimCli/Mitsubishi/Program.cs b/TestPrelimCli/Mitsubishi/Program.cs
index a77ada93..e449eae5 100644
--- a/TestPrelimCli/Mitsubishi/Program.cs
+++ b/TestPrelimCli/Mitsubishi/Program.cs
@@ -38,11 +38,11 @@ namespace Mitsubishi
// [Local variable declaration]
object BlockValue = "";
- int Ret = 0;
+ int iRet = 0;
//Open communication
- Ret = oEZNcAutCom.SetTCPIPProtocol("192.168.213.199", 683);
- //Console.WriteLine($"R: {Ret}");
- Ret = oEZNcAutCom.Open3(5, 1, 10, "EZNC_LOCALHOST");
+ iRet = oEZNcAutCom.SetTCPIPProtocol("192.168.213.199", 683);
+ //Console.WriteLine($"R: {iRet}");
+ iRet = oEZNcAutCom.Open3(5, 1, 10, "EZNC_LOCALHOST");
DoLog(sep);
DoLog("Retrieve Serial/Vers");
@@ -90,6 +90,12 @@ namespace Mitsubishi
// preparo memorie
string prgText = "";
int prgState = 0;
+ // solo nome...
+ iRet = oEZNcAutCom.Program_GetProgramNumber2((Int32)PROGRAMTYPE.EZNC_MAINPRG, out String strProgramNo);
+ DoLog($"ProgramName: {strProgramNo}");
+ DoLog("");
+
+ // leggo contenuto
try
{
oEZNcAutCom.Program_CurrentBlockRead(10, out prgText, out prgState);
@@ -125,7 +131,7 @@ namespace Mitsubishi
double pdPosit = 0;
for (int i = 1; i < 4; i++)
{
- Ret = oEZNcAutCom.Position_GetCurrentPosition(i, out pdPosit);
+ iRet = oEZNcAutCom.Position_GetCurrentPosition(i, out pdPosit);
DoLog($"Pos: {i} | {pdPosit}");
}
DoLog(sep);
@@ -287,7 +293,7 @@ namespace Mitsubishi
DoLog("");
// Close.
- Ret = oEZNcAutCom.Close();
+ iRet = oEZNcAutCom.Close();
//Release object
oEZNcAutCom = null;
@@ -302,6 +308,12 @@ namespace Mitsubishi
Console.WriteLine(logMessage);
}
+ public enum PROGRAMTYPE
+ {
+ EZNC_MAINPRG = 0, //メインプログラム
+ EZNC_SUBPRG = 1, //サブプログラム
+ }
+
protected static string outPath = "";
private static string sep = "------------------------";