diff --git a/IOB-WIN/AdapterForm.cs b/IOB-WIN/AdapterForm.cs
index 96043859..f6744ecf 100644
--- a/IOB-WIN/AdapterForm.cs
+++ b/IOB-WIN/AdapterForm.cs
@@ -632,7 +632,7 @@ namespace IOB_WIN
case tipoAdapter.SIEMENS:
iobObj = new IobSiemens(this, IOBConf);
start.Enabled = true;
- break;
+ break;
case tipoAdapter.SIEMENS_TORRI:
iobObj = new IobSiemensTorri(this, IOBConf);
start.Enabled = true;
diff --git a/IOB-WIN/DATA/CONF/MAIN.ini b/IOB-WIN/DATA/CONF/MAIN.ini
index f0e7d072..e39e0706 100644
--- a/IOB-WIN/DATA/CONF/MAIN.ini
+++ b/IOB-WIN/DATA/CONF/MAIN.ini
@@ -4,20 +4,21 @@
NAME=develop
[SERVER]
-MPIP=192.168.2.252
-;MPIP=10.74.82.219
+;MPIP=192.168.2.252
+MPIP=10.74.82.219
;MPIP=192.168.1.7
MPURL=/MP/IO
CMDREBO=/IOB/sendRebootGateway?GWIP=
CMDIOB2CALL=/IOB/getIob2call?GWIP=
[IOB]
-; OSAI
-STARTLIST=OSAI
-; KAWASAKI
+;--- OSAI ---
+;STARTLIST=OSAI
+;--- KAWASAKI ---
;STARTLIST=4000
-
-; SIEMENS TORRI
+;--- PUNZ SIEMENS ---
+STARTLIST=SIEMENS
+;--- SIEMENS TORRI ---
;STARTLIST=3013
MAXCNC=4
diff --git a/IOB-WIN/DATA/CONF/SIEMENS.ini b/IOB-WIN/DATA/CONF/SIEMENS.ini
new file mode 100644
index 00000000..53b917d8
--- /dev/null
+++ b/IOB-WIN/DATA/CONF/SIEMENS.ini
@@ -0,0 +1,63 @@
+;Configurazione IOB-WIN
+[IOB]
+CNCTYPE=SIEMENS
+PING_MS_TIMEOUT=500
+
+[MACHINE]
+VENDOR=Tecnomeccanica
+MODEL=Punzonatrice 140.000
+
+[CNC]
+; Siemens (Tecnomeccanica)
+IP=192.168.1.55
+CPUTYPE=S71200
+RACK=0
+SLOT=2
+
+[SERVER]
+MPIP=http://192.168.1.7
+MPURL=/MP/IO
+CMDBASE=/IOB/input/
+CMDFLOG=/IOB/flog/
+CMDALIVE=/IOB
+CMDENABLED=/IOB/enabled/
+CMDADV1=?valore=
+CMDREBO=/sendReboot.aspx?idxMacchina=
+
+[MEMORY]
+ADDR_READ=DB15.DBB0
+ADDR_WRITE=DB16.DBB0
+SIZE_READ=50
+SIZE_WRITE=50
+;BIT0=CONN
+BIT1=DB15.DBB1
+;BIT2=PZCOUNT.STD.DB700.DBW22
+BIT3=DB15.DBB3
+BIT4=DB15.DBB4
+
+
+[BLINK]
+;MAX_COUNTER_BLINK = 30
+MAX_COUNTER_BLINK = 15
+;bit0 = 0
+;bit1 = 0
+;bit2 = 1
+;bit3 = 1
+;bit4 = 1
+;bit5 = 0
+;bit6 = 0
+;bit7 = 0
+BLINK_FILT=0
+;BLINK_FILT=28
+
+[OPTPAR]
+;PZCOUNT_MODE=STD.[PAR/MEM].info|BIT.indice
+; attenzione memoria sempre base BYTE (1604 DW --> 6416...)
+PZCOUNT_MODE=STD.DB15.DBW22
+;PZ_CAD_MADDR=1602
+;PZ_REQ_MADDR=1603
+;PZ_DONE_MADDR=1604
+;PZ_GTOT_MADDR=1605
+
+[BRANCH]
+NAME=develop
\ No newline at end of file
diff --git a/IOB-WIN/IOB-WIN.csproj b/IOB-WIN/IOB-WIN.csproj
index 35e01fca..b832e019 100644
--- a/IOB-WIN/IOB-WIN.csproj
+++ b/IOB-WIN/IOB-WIN.csproj
@@ -201,6 +201,9 @@
Always
+
+ Always
+
Always
diff --git a/IOB-WIN/IobSiemens.cs b/IOB-WIN/IobSiemens.cs
index 0a37cb8e..6f481039 100644
--- a/IOB-WIN/IobSiemens.cs
+++ b/IOB-WIN/IobSiemens.cs
@@ -1,21 +1,1194 @@
-using System;
+using IOB_UT;
+using S7.Net;
+using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using IOB_UT;
+using System.Net;
+using System.Net.NetworkInformation;
namespace IOB_WIN
{
public class IobSiemens : IobGeneric
{
+ #region area componenti base
+
///
- /// estende l'init della classe base con i metodi x Siemens
+ /// Configurazione valori da LEGGERE dal PLC
+ ///
+ public otherData[] memMapR;
+ ///
+ /// Configurazione valori da SCRIVERE nel PLC
+ ///
+ public otherData[] memMapW;
+ ///
+ /// Byte dimensione buffer dati memoria (da file map)
+ ///
+ public int numByte = 0;
+ ///
+ /// Lungh massima stringhe
+ ///
+ protected int maxStrChar = 20;
+ ///
+ /// Oggetto PLC da ri-utilizzare...
+ ///
+ protected Plc currPLC;
+ ///
+ /// indica se serva refresh parametri e quindi PLC...
+ ///
+ bool needRefresh = true;
+ ///
+ /// Oggetto cronometro x test vari...
+ ///
+ protected Stopwatch sw = new Stopwatch();
+ ///
+ /// parametri di connessione
+ ///
+ protected connParamS7 parametri;
+ ///
+ /// Variabile x salvataggio iobConf locale
+ ///
+ protected IobConfiguration _IOBConf;
+
+ #endregion
+
+ #region area metodi lettura/Scrittura
+
+
+ ///
+ /// wrapper chiamata LETTURA in blocco MULTI BYTE...
+ ///
+ ///
+ ///
+ public bool S7ReadBB(ref byte[] Value)
+ {
+ bool answ = false;
+ sw.Restart();
+ parentForm.commPlcActive = true;
+ if (testCncConn())
+ {
+ // decodifico memoria...
+ memAreaSiemens memoria = new memAreaSiemens(parametri.memAddrRead);
+ int numByte = parametri.memSizeRead;
+ Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
+ // copio in value, sennò do errore...
+ if (memByteRead.Length == Value.Length)
+ {
+ Value = memByteRead;
+ }
+ else
+ {
+ lgError(string.Format("Mismatch dimensione array memoria: passato array di {0} byte, letti da S7 {1} byte", Value.Length, memByteRead.Length));
+ }
+ string titolo = string.Format("READ BLOCK MEM BYTE: {0} --> {1} byte", parametri.memAddrRead, numByte);
+ if (verboseLog)
+ {
+ lgInfo(titolo);
+ }
+
+ string contenuto = string.Format("Contenuto area memoria aquisita{0}", Environment.NewLine);
+ string byteVal = "";
+ for (int i = 0; i < memByteRead.Length; i++)
+ {
+ byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0');
+ contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine);
+ }
+ // loggo lettura...
+ if (verboseLog)
+ {
+ lgInfo(contenuto);
+ }
+ }
+ else
+ {
+ connectionOk = false;
+ }
+ parentForm.commPlcActive = false;
+ sw.Stop();
+ if (utils.CRB("recTime"))
+ {
+ TimingData.addResult(currIobConf.codIOB, string.Format("{0}|{1}", parametri.memAddrRead, numByte), sw.ElapsedTicks);
+ }
+
+ return answ;
+ }
+ ///
+ /// wrapper chiamata SCRITTURA in blocco MULTI BYTE...
+ ///
+ ///
+ ///
+ public bool S7WriteBB(ref byte[] Value)
+ {
+ bool answ = false;
+
+#if false
+ sw.Restart();
+ if (testCncConn())
+ {
+ // decodifico memoria...
+ memAddress memoria = new memAddress(txtMemArea.Text);
+ int numByte = 1;
+ int.TryParse(txtMemSize.Text, out numByte);
+ Byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, numByte);
+ titolo = string.Format("READ BLOCK MEM BYTE: {0} --> {1} byte", txtMemArea.Text, numByte);
+ contenuto = "";
+ string byteVal = "";
+ for (int i = 0; i < memByteRead.Length; i++)
+ {
+ byteVal = Convert.ToString(memByteRead[i], 2).PadLeft(8, '0');
+ contenuto += string.Format("B{0:000}: {1} | {2}{3}", i, byteVal, memByteRead[i], Environment.NewLine);
+ }
+ showOut(titolo, contenuto);
+ }
+ sw.Stop();
+ tslRTime.Text = string.Format("{0}", sw.Elapsed);
+#endif
+
+
+#if false
+ if (FANUC_ref.Connected)
+ {
+ try
+ {
+ parentForm.commPlcActive = true;
+ answ = FANUC_ref.F_RW_Byte(bWrite, MemType, memIndex, ref Value);
+ }
+ catch
+ { }
+ }
+ parentForm.commPlcActive = false;
+#endif
+ return answ;
+ }
+
+
+ #endregion
+
+ ///
+ /// estende l'init della classe base con i metodi x Siemens specifici x Torri
///
///
///
public IobSiemens(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf)
{
+ // gestione invio ritardato contapezzi
+ pzCountDelay = utils.CRI("pzCountDelay");
+ lastPzCountSend = DateTime.Now;
+ lastWarnODL = DateTime.Now;
+ // init conf
+ _IOBConf = IOBConf;
+ // inizializzo parametri...
+ parametri = new connParamS7()
+ {
+ ipAdrr = "127.0.0.1",
+ tipoCpu = CpuType.S7200,
+ slot = 0,
+ rack = 0,
+ pingMsTimeout = IOBConf.pingMsTimeout,
+ memAddrRead = "DB1.DBB0",
+ memAddrWrite = "DB2.DBB0",
+ memSizeRead = 0,
+ memSizeWrite = 0
+ };
+ setParamPlc();
}
+ ///
+ /// Test connessione CNC
+ ///
+ ///
+ private bool testCncConn()
+ {
+ bool answ = false;
+ IPStatus pingStatus = testPing();
+ // se passa il ping faccio il resto...
+ if (pingStatus != IPStatus.Success)
+ {
+ lgError(string.Format("Errore in testCncConn: reply Status per {0}: {1}", parametri.ipAdrr, pingStatus));
+ }
+ else
+ {
+ if (!currPLC.IsConnected)
+ {
+ currPLC.Open();
+ }
+
+ if (!currPLC.IsAvailable)
+ {
+ lgError(string.Format("PLC Siemens NON disponibile:{0} | {1}", currPLC.LastErrorCode, currPLC.LastErrorString));
+ currPLC.ClearLastError();
+ }
+ else
+ {
+ if (!currPLC.IsConnected)
+ {
+ lgError(string.Format("PLC Siemens NON connesso:{0} | {1}", currPLC.LastErrorCode, currPLC.LastErrorString));
+ currPLC.ClearLastError();
+ parentForm.updateComStats("NO connection");
+ }
+ else
+ {
+ parentForm.updateComStats("Connection OK");
+ answ = true;
+ }
+ }
+ }
+ return answ;
+ }
+ ///
+ /// test ping all'indirizzo impostato nei parametri
+ ///
+ ///
+ private IPStatus testPing()
+ {
+ IPStatus answ = IPStatus.Unknown; ;
+ IPAddress address;
+ PingReply reply;
+ Ping pingSender = new Ping();
+ address = IPAddress.Loopback;
+ IPAddress.TryParse(parametri.ipAdrr, out address);
+ int pingMsTimeout = parametri.pingMsTimeout;
+ reply = pingSender.Send(address, pingMsTimeout);
+ answ = reply.Status;
+ return answ;
+ }
+ ///
+ /// Imposto parametri PLC
+ ///
+ private void setParamPlc()
+ {
+ // Creo oggetto connessione NC
+ parentForm.commPlcActive = true;
+ lgInfo("Start init Adapter SIEMENS TORRI all'IP {0} | CPU: {1} | R/S: {2}/{3} | --> IOB {4}", _IOBConf.cncIpAddr, _IOBConf.cpuType, _IOBConf.rack, _IOBConf.slot, _IOBConf.codIOB);
+ // SE è necessario refresh...
+ if (needRefresh)
+ {
+ lgInfo("Refreshing connection...");
+ try
+ {
+ parametri.slot = _IOBConf.slot;
+ parametri.rack = _IOBConf.rack;
+ parametri.tipoCpu = (CpuType)Enum.Parse(typeof(CpuType), _IOBConf.cpuType);
+ parametri.ipAdrr = _IOBConf.cncIpAddr;
+ // leggo file init...
+ IniFile fIni = new IniFile(_IOBConf.iniFileName);
+ // ora leggo valori speciali
+ parametri.memAddrRead = fIni.ReadString("MEMORY", "ADDR_READ", "");
+ parametri.memAddrWrite = fIni.ReadString("MEMORY", "ADDR_WRITE", "");
+ parametri.memSizeRead = fIni.ReadInteger("MEMORY", "SIZE_READ", 0);
+ parametri.memSizeWrite = fIni.ReadInteger("MEMORY", "SIZE_WRITE", 0);
+ // salvo vettori memoria...
+ RawInput = new byte[parametri.memSizeRead];
+ RawOutput = new byte[parametri.memSizeWrite];
+ // salvo parametri conn!
+ lgInfo(string.Format("Parametri memoria: memAddrRead: {0} | memAddrWrite: {1} | memSizeRead: {2} | memSizeWrite: {3}", parametri.memAddrRead, parametri.memAddrWrite, parametri.memSizeRead, parametri.memSizeWrite));
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in parse parametri da IOBConf");
+ }
+ // ora tento avvio PLC... SE PING OK...
+ if (testPing() == IPStatus.Success)
+ {
+ try
+ {
+ currPLC = new Plc(parametri.tipoCpu, parametri.ipAdrr, parametri.rack, parametri.slot);
+ // disconnetto e connetto...
+ if (utils.CRB("verbose"))
+ {
+ lgInfo("SIEMENS-TORRI: tryDisconnect");
+ }
+
+ tryDisconnect();
+ lgInfo("SIEMENS-TORRI: tryConnect");
+ tryConnect();
+ lgInfo("End init Adapter SIEMENS-TORRI");
+ if (utils.CRB("verbose"))
+ {
+ lgInfo("S7+ CONNESSIONE AVVENUTA");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in INIT PLC S7+");
+ }
+ needRefresh = false;
+ }
+ parentForm.commPlcActive = false;
+ // carico conf vettore memoria...
+ loadMemConf();
+ if (utils.CRB("enableContapezzi"))
+ {
+ lgInfo("TORRI-SIEMENS: inizio gestione contapezzi");
+ try
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
+ if (currIobConf.optPar.Count > 0 && currIobConf.optPar["PZCOUNT_MODE"] != "")
+ {
+ if (currIobConf.optPar["PZCOUNT_MODE"].StartsWith("STD"))
+ {
+ pzCntReload();
+ // refresh associazione Macchina - IOB
+ sendM2IOB();
+ // per adesso imposto lettura fanuc == contapezzi (poi farà vera lettura...)
+ lastCountCNC = contapezzi;
+ }
+ else
+ {
+ contapezzi = 0;
+ lgInfo("Contapezzi STD disabilitato: modalità {0}", currIobConf.optPar["PZCOUNT_MODE"]);
+ }
+ }
+ else
+ {
+ contapezzi = 0;
+ lgInfo("Parametro mancante PZCOUNT_MODE");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in contapezzi TORRI-SIEMENS");
+ }
+ }
+ }
+ }
+ ///
+ /// Override disconnessione
+ ///
+ public override void tryDisconnect()
+ {
+ if (connectionOk)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ currPLC.Close();
+ connectionOk = false;
+ lgInfo(szStatusConnection);
+ lgInfo("Effettuata disconnessione adapter SIEMENS-TORRI!");
+ }
+ catch (Exception exc)
+ {
+ lgFatal(exc, "Errore nella disconnessione dall'adapter SIEMENS-TORRI");
+ }
+ }
+ else
+ {
+ lgError("IMPOSSIBILE effettuare disconnessione SIEMENS-TORRI: Connessione non disponibile...");
+ }
+ }
+ ///
+ /// 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("ConnKO - tryConnect");
+ }
+ // in primis salvo data ping...
+ lastPING = DateTime.Now;
+ // se passa il ping faccio il resto...
+ if (testPing() == IPStatus.Success)
+ {
+ string szStatusConnection = "";
+ try
+ {
+ // ora provo connessione...
+ parentForm.commPlcActive = true;
+ currPLC.Open();
+ parentForm.commPlcActive = false;
+ lgInfo("szStatusConnection: " + szStatusConnection);
+ connectionOk = true;
+ // refresh stato allarmi!!!
+ if (connectionOk)
+ {
+ if (adpRunning)
+ {
+ // carico status allarmi (completo)
+ lgInfo("Inizio refresh completo stato allarmi...");
+ forceAlarmCheck();
+ lgInfo("Completato refresh completo stato allarmi!");
+ }
+ else
+ {
+ lgInfo("Connessione OK");
+ }
+ }
+ else
+ {
+ lgError("Impossibile procedere, connessione mancante...");
+ }
+ }
+ catch (Exception exc)
+ {
+ lgFatal(string.Format("Errore nella connessione all'adapter SIEMENS-TORRI: {0}{1}{2}", szStatusConnection, Environment.NewLine, exc));
+ connectionOk = false;
+ lgInfo(string.Format("Eccezione in TryConnect, Adapter SIEMENS-TORRI 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: SIEMENS-TORRI controllo PING fallito per IP {0}", currIobConf.cncIpAddr));
+ }
+ }
+ }
+ }
+ // se non è ancora connesso faccio procesisng memoria caso disconnesso...
+ if (!connectionOk)
+ {
+ // processo semafori ed invio...
+ processMemoryDiscon();
+ }
+ }
+ ///
+ /// Caricamento conf memoria DB del SIEMENS
+ ///
+ private void loadMemConf()
+ {
+ // carico conf memoria
+ loadConfFile(ref memMapR, filePath("MMapR"), 1, ref numByte);
+ loadConfFile(ref memMapW, filePath("MMapW"), 1, ref numByte);
+ }
+ ///
+ /// Restituisce path completo file da chaive configurazione
+ ///
+ /// chaive conf x file richiesto
+ ///
+ protected string filePath(string keyFile)
+ {
+ string answ = "";
+ try
+ {
+ answ = string.Format(@"{0}\{1}", utils.confDir, utils.CRS(keyFile));
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Eccezione in recupero filePath");
+ }
+ return answ;
+ }
+
+ ///
+ /// Effettua vero processing contapezzi
+ ///
+ public override void processContapezzi()
+ {
+ if (utils.CRB("enableContapezzi"))
+ {
+ try
+ {
+ // verifico quale modalità sia richiesta: STD (6711) oppure BIT (Custom, con indicazione area)
+ if (currIobConf.optPar.Count > 0 && currIobConf.optPar["PZCOUNT_MODE"] != "")
+ {
+ string memAddr = currIobConf.optPar["PZCOUNT_MODE"];
+ if (memAddr.StartsWith("STD"))
+ {
+ // inizio verifica area memoria/parametro levando prima parte codice
+ memAddr = memAddr.Replace("STD.", "");
+ object outputVal = new object();
+ // verifico se si tratta di lettura area DB... formato tipo STD.DB700.DBB22.W
+ if (memAddr.StartsWith("DB"))
+ {
+ memAreaSiemens areaCounter = new memAreaSiemens(memAddr);
+
+ if (utils.CRB("verbose"))
+ {
+ lgInfo("[0] area memoria: {1}.{2}.{3}", memAddr, areaCounter.DbNum, areaCounter.indiceMem, areaCounter.tipoMem);
+ }
+ // copio da blocco già letto... con switch x tipo dati --> tipo lettura... e salvo ultimo conteggio rilevato
+ switch (areaCounter.tipoMem)
+ {
+ case "B":
+ byte valB = RawInput[areaCounter.indiceMem];
+ outputVal = valB;
+ break;
+ case "W":
+ ushort valW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(areaCounter.indiceMem).Take(2).ToArray());
+ outputVal = valW;
+ break;
+ case "DW":
+ uint valDW = S7.Net.Types.Word.FromByteArray(RawInput.Skip(areaCounter.indiceMem).Take(4).ToArray());
+ outputVal = valDW;
+ if (utils.CRB("verbose"))
+ {
+ lgInfo("[2] outputVal contapezzi: {0}", outputVal);
+ }
+
+ break;
+ default:
+ break;
+ }
+ // salvo...
+ Int32.TryParse(outputVal.ToString(), out lastCountCNC);
+ if (utils.CRB("verbose"))
+ {
+ lgInfo("[3] lastCountCNC contapezzi: {0}", lastCountCNC);
+ }
+ }
+ stopwatch.Stop();
+ }
+ }
+ }
+ catch (Exception exc)
+ {
+ lgError(exc, "Errore in contapezzi SIEMENS-TORRI");
+ }
+ }
+ }
+
+ #region da completare
+
+ ///
+ /// Recupero dati override in formato dictionary
+ ///
+ ///
+ public override Dictionary getOverrides()
+ {
+ Dictionary outVal = new Dictionary();
+ uint valDW = 0;
+ // !!!FARE!!! recuperare da conf memoria, ora HARD CODED
+ outVal.Add("FEED_OVER", RawInput[19].ToString());
+ outVal.Add("RAPID_OVER", RawInput[20].ToString());
+ outVal.Add("CURR_MODE", decodeCurrMode(RawInput[21]));
+ // recupero RPM pezzo/mola !!!FARE!!! cambio nome da config, qui sono 01:conduttrice e 02:operatrice (3013), mentre sono pezzo/mola nella V100
+ valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(24).Take(4).ToArray());
+ outVal.Add("RPM_01", valDW.ToString());
+ valDW = S7.Net.Types.DWord.FromByteArray(RawInput.Skip(28).Take(4).ToArray());
+ outVal.Add("RPM_02", valDW.ToString());
+ return outVal;
+ }
+
+ ///
+ /// lettura bit semafori
+ ///
+ public override void readSemafori()
+ {
+ base.readSemafori();
+ if (verboseLog)
+ {
+ lgInfo("inizio read semafori");
+ }
+
+ parentForm.sIN = Semaforo.SV;
+ // leggo TUTTI i byte configurati...
+ byte[] MemBlock = new byte[parametri.memSizeRead];
+ bool fatto = S7ReadBB(ref MemBlock);
+ Buffer.BlockCopy(MemBlock, 0, RawInput, 0, parametri.memSizeRead);
+ if (verboseLog)
+ {
+ lgInfo(string.Format("RawInput[0]: {0}", utils.binaryForm(RawInput[0])));
+ }
+ // salvo il solo BYTE dell'input decifrando il semaforo...
+ decodeToBaseBitmap();
+ decodeOtherData();
+ }
+
+ ///
+ /// decodifica da bitmap il CURRENT MODE del controllo
+ ///
+ ///
+ ///
+ protected string decodeCurrMode(byte currModeBitmap)
+ {
+ string answ = "";
+ if (verboseLog)
+ {
+ lgInfo(string.Format("CURR_MODE raw data: {0}", utils.binaryForm(currModeBitmap)));
+ }
+ // decodifica del MODO... B21
+ /*
+ * CURR MODE diviso in BIT:
+ * B0 (01) = AUTO
+ * B1 (02) = MDI
+ * B2 (04) = JOG
+ * B3 (08) = TeachIN (associato a MDI --> 10)
+ * B4 (16) = Repos (associato a JOG --> 20)
+ * B5 (32) = RefPoint (associato a Jog --> 36)
+ * B6 (64) = Incr1 (associato a Jog --> 68)
+ * B7 (128) = Incr10 (associato a Jog --> -124 / 132 se UInt)
+ * */
+
+ // modi principali
+ if (currModeBitmap.SelectBit(0))
+ {
+ answ = "AUTO";
+ }
+ else if (currModeBitmap.SelectBit(1))
+ {
+ answ = "MDI";
+ }
+ else if (currModeBitmap.SelectBit(2))
+ {
+ answ = "JOG";
+ }
+ // modi accessori
+ if (currModeBitmap.SelectBit(3))
+ {
+ answ += " | TEACH-IN";
+ }
+ if (currModeBitmap.SelectBit(4))
+ {
+ answ += " | REPOS";
+ }
+ if (currModeBitmap.SelectBit(5))
+ {
+ answ += " | REF-POINT";
+ }
+ if (currModeBitmap.SelectBit(6))
+ {
+ answ += " | INCR-1";
+ }
+ if (currModeBitmap.SelectBit(7))
+ {
+ answ += " | INCR-10";
+ }
+ return answ;
+ }
+ ///
+ /// Decodifica il resto dell'area TORRI x i dati accessori (allarmi, ...)
+ ///
+ private void decodeOtherData()
+ {
+ if (verboseLog)
+ {
+
+ }
+ }
+
+ ///
+ /// Effettua decodifica aree memoria alla bitmap usata x MAPO
+ ///
+ private void decodeToBaseBitmap()
+ {
+ // init a zero...
+ B_input = 0;
+ // TORRI: leggo i primi 8 bit hard coded...
+ int byteSem = RawInput[0];
+ // azzero i bit NON gestiti (2-5-6-7)
+ byteSem &= ~(1 << 2);
+ byteSem &= ~(1 << 5);
+ byteSem &= ~(1 << 6);
+ byteSem &= ~(1 << 7);
+ // salvo infine variabile bit x invio
+ B_input = byteSem;
+
+
+ string currODL = "";
+ try
+ {
+ currODL = utils.callUrl(urlGetCurrODL);
+ lgInfo(string.Format("Lettura ODL, {0} --> {1}", currIdxODL, currODL));
+ // 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;
+ }
+ }
+ if (currODL != null && currODL != "" && currODL != "0")
+ {
+ // ora processo il contapezzi...
+ // controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture
+ if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
+ {
+ // verifico se variato contapezzi... e se passato ritardo minimo...
+ if (lastCountCNC > contapezzi)
+ {
+ // salvo nuovo contapezzi (incremento di 1...)
+ contapezzi++;
+ // salvo in semaforo!
+ B_input += 1 << 2;
+ }
+ // registro contapezzi
+ lgInfo(string.Format("Contapezzi SIEMENST-TORRI: {0} | Contapezzi interno {1}", lastCountCNC, contapezzi));
+
+ // 2018.06.26 NON resetto perché si deve resettare da solo da conteggio TC POST cambio ODL...
+#if false
+ else if (contapezzi > lastCountCNC) // in questo caso resetto
+ {
+ contapezzi = lastCountCNC;
+ }
+#endif
+ // invio a server contapezzi (aggiornato)
+ string retVal = utils.callUrl(urlSetPzCount + contapezzi.ToString());
+ // verifica se tutto OK
+ if (retVal != "OK")
+ {
+ // errore salvataggio contapezzi
+ lgInfo(string.Format("Errore salvataggio Contapezzi SIEMENST-TORRI: {0} | Contapezzi interno {1} | Errore salvataggio: {2}", lastCountCNC, contapezzi, retVal));
+ }
+ // resetto timer...
+ lastPzCountSend = DateTime.Now;
+ }
+ }
+ else
+ {
+ if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
+ {
+ lgInfo(string.Format("Attenzione: mancanza ODL non procedo con gestione contapezzi. Contapezzi SIEMENST-TORRI: {0} | Contapezzi interno {1}", lastCountCNC, contapezzi));
+ // resetto timer...
+ lastPzCountSend = DateTime.Now;
+ }
+ }
+
+#if false
+ // SE SI E' CONNESSO al PLC allora è 1=powerON...
+ if (connectionOk)
+ {
+ 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"))
+ {
+ // controllo se è passato intervallo minimo tra 2 controlli/elaborazioni x distanziare invio e ridurre letture
+ if (DateTime.Now >= lastPzCountSend.AddMilliseconds(pzCountDelay))
+ {
+ // verifico se variato contapezzi in area STD PAR6711... e se passato ritardo minimo...
+ if (lastCountCNC > contapezzi)
+ {
+ // salvo nuovo contapezzi (incremento di 1...)
+ contapezzi++;
+ // salvo in semaforo!
+ B_input += 1 << 2;
+ // registro contapezzi
+ lgInfo(string.Format("Contapezzi FANUC: {0} | Contapezzi interno {1}", lastCountCNC, contapezzi));
+ }
+ else if (contapezzi > lastCountCNC) // in questo caso resetto
+ {
+ contapezzi = lastCountCNC;
+ }
+ // invio a server contapezzi (aggiornato)
+ utils.callUrl(urlSetPzCount + contapezzi.ToString());
+ // resetto timer...
+ lastPzCountSend = DateTime.Now;
+ }
+ }
+ else // area "normale" byte.bit
+ {
+ // di norma è segnale normale => 1, altrimenti inverse => 0...
+ invSignal = false;
+ // cerco se sia inverse (ultimo char "!") --> registro e elimino char...
+ invSignal = bVal.StartsWith("!");
+ // 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;
+ }
+ }
+ }
+
+ }
+ }
+ // log opzionale!
+ if (verboseLog) lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
+#endif
+
+ // log opzionale!
+ if (verboseLog)
+ {
+ lgInfo(string.Format("Trasformazione B_input: {0}", B_input));
+ }
+ }
+ ///
+ /// Recupero programma in lavorazione
+ ///
+ ///
+ public override string getPrgName()
+ {
+ string prgName = "";
+#if false
+ // recupero NUOVO prgName...
+ try
+ {
+ // recupero nome programma MAIN
+ prgName = utils.purgedChar2String(FANUC_ref.getPrgNameMain());
+ // trimmo path del programma, ovvero "CNCMEMUSERPATH1"
+ prgName = prgName.Replace(utils.CRS("basePrgMemPath"), "");
+ }
+ catch (Exception exc)
+ {
+ lgError(string.Format("Eccezione in recupero PRG NAME MAIN:{0}{1}", Environment.NewLine, exc));
+ }
+#endif
+ return prgName;
+ }
+
+ ///
+ /// Recupero programma in lavorazione come Dictionary FANUC...
+ /// - 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();
+#if false
+ inizio = DateTime.Now;
+ CncLib.Focas1.ODBSYS answ = FANUC_ref.getSysInfo();
+ if (utils.CRB("recTime")) TimingData.addResult(string.Format("SYS-INFO"), DateTime.Now.Subtract(inizio).Ticks);
+ 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 = answ.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");
+ }
+#endif
+ return outVal;
+ }
+ ///
+ /// Esegue processing MODE (e nel contempo recupera altri dati dell'area G)
+ ///
+ public override void processMode()
+ {
+ if (utils.CRB("enableMode"))
+ {
+#if false
+ try
+ {
+ inizio = DateTime.Now;
+ // leggo tutto da 0 a 43...
+ int memIndex = 0;
+ FanucMemRW(R, FANUC.MemType.G, memIndex, ref MemBlockG);
+ if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-G-AREA", MemBlockG.Length), DateTime.Now.Subtract(inizio).Ticks);
+ // 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, "Errore in process Mode G43");
+ }
+#endif
+ }
+ }
+#if false
+ ///
+ /// decodifica il modo dai valori del byte G43
+ ///
+ ///
+ ///
+ protected 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;
+ }
+#endif
+ ///
+ /// Recupero dati dinamici...
+ ///
+ public override Dictionary getDynData()
+ {
+ Dictionary outVal = new Dictionary();
+#if false
+ inizio = DateTime.Now;
+ CncLib.Focas1.ODBDY2_1 answ = FANUC_ref.getAllDynData();
+ if (utils.CRB("recTime")) TimingData.addResult(string.Format("PROC-DYN-DATA"), DateTime.Now.Subtract(inizio).Ticks);
+ try
+ {
+ string actf = answ.actf.ToString();
+ string acts = answ.acts.ToString();
+ //string numAlarm = answ.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...
+ CncLib.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");
+ }
+#endif
+ return outVal;
+ }
+
+ ///
+ /// Override salvataggio valori in memoria...
+ ///
+ /// tipo di DUMP
+ public override void saveMemDump(dumpType tipo)
+ {
+#if false
+ dump_MemAreaD();
+ dump_MemAreaY();
+#endif
+ }
+ ///
+ /// Dump PERIODICO area D della memoria
+ ///
+ /// area memoria di partenza
+ ///
+ private void dump_MemAreaD(int memIndex, int memSyzeByte)
+ {
+ // leggo TUTTI i 9999 byte della memoria D...
+ byte[] MemBlockD = new byte[memSyzeByte];
+ stopwatch.Restart();
+ if (verboseLog)
+ {
+ lgInfo("START MemDump AreaD");
+ }
+#if false
+ FanucMemRW(R, FANUC.MemType.D, memIndex, ref MemBlockD);
+ if (verboseLog) lgInfo("END MemDump AreaD");
+ if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-MemDumpD", MemBlockD.Length), DateTime.Now.Subtract(inizio).Ticks);
+ // file out!
+ string nomeFile = "";
+ Dictionary mappaValori = new Dictionary();
+ // salvo in file i dati letti come DWord (4byte)
+ nomeFile = string.Format(@"{0}\SAMPLES\MemDump_D_DW_{1:yyyyMMdd_HHmmss}.dat", utils.dataDatDir, DateTime.Now);
+ for (int i = 0; i < MemBlockD.Length / 4; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockD, i * 4).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+#endif
+ }
+ ///
+ /// Dump area D della memoria
+ ///
+ private void dump_MemAreaD()
+ {
+ // faccio chaimate e salvo in file dump...
+ int memIndex = 0;
+ // leggo TUTTI i 9999 byte della memoria D...
+ byte[] MemBlockD = new byte[9999];
+ stopwatch.Restart();
+ if (verboseLog)
+ {
+ lgInfo("START MemDump AreaD");
+ }
+#if false
+ FanucMemRW(R, FANUC.MemType.D, memIndex, ref MemBlockD);
+ if (verboseLog) lgInfo("END MemDump AreaD");
+ if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-MemDumpD", MemBlockD.Length), DateTime.Now.Subtract(inizio).Ticks);
+ //
+ string nomeFile = "";
+ // salvo in file i dati letti come BYTE
+ nomeFile = string.Format(@"{0}\MemDump_D_Byte.dat", utils.dataDatDir);
+ Dictionary mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockD.Length; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), MemBlockD[i].ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+
+ // salvo in file i dati letti come DWord (4byte)
+ nomeFile = string.Format(@"{0}\MemDump_D_DW.dat", utils.dataDatDir);
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockD.Length / 4; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockD, i * 4).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+
+ // salvo in file i dati letti come DWord (4byte)
+ nomeFile = string.Format(@"{0}\MemDump_D_W.dat", utils.dataDatDir);
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockD.Length / 2; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt16(MemBlockD, i * 2).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+#endif
+ }
+ ///
+ /// Dump area Y della memoria
+ ///
+ private void dump_MemAreaY()
+ {
+ // faccio chaimate e salvo in file dump...
+ int memIndex = 0;
+ // leggo TUTTI i 9999 byte della memoria Y...
+ byte[] MemBlockY = new byte[10];
+ stopwatch.Restart();
+ if (verboseLog)
+ {
+ lgInfo("START MemDump AreaY");
+ }
+#if false
+ FanucMemRW(R, FANUC.MemType.Y, memIndex, ref MemBlockY);
+ if (verboseLog) lgInfo("END MemDump AreaY");
+ if (utils.CRB("recTime")) TimingData.addResult(string.Format("R{0}-MemDumpY", MemBlockY.Length), DateTime.Now.Subtract(inizio).Ticks);
+ //
+ string nomeFile = "";
+ // salvo in file i dati letti come BYTE
+ nomeFile = string.Format(@"{0}\MemDump_Y_Byte.dat", utils.dataDatDir);
+ Dictionary mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockY.Length; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), MemBlockY[i].ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+
+ // salvo in file i dati letti come DWord (4byte)
+ nomeFile = string.Format(@"{0}\MemDump_Y_DW.dat", utils.dataDatDir);
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockY.Length / 4; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt32(MemBlockY, i * 4).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+
+ // salvo in file i dati letti come DWord (4byte)
+ nomeFile = string.Format(@"{0}\MemDump_Y_W.dat", utils.dataDatDir);
+ mappaValori = new Dictionary();
+ for (int i = 0; i < MemBlockY.Length / 2; i++)
+ {
+ mappaValori.Add(i.ToString("0000"), BitConverter.ToUInt16(MemBlockY, i * 2).ToString());
+ }
+ utils.WritePlain(mappaValori, nomeFile);
+#endif
+ }
+ #endregion
}
}
diff --git a/IOB-WIN/IobSiemensTorri.cs b/IOB-WIN/IobSiemensTorri.cs
index 01dc522f..bbecdcb0 100644
--- a/IOB-WIN/IobSiemensTorri.cs
+++ b/IOB-WIN/IobSiemensTorri.cs
@@ -44,7 +44,7 @@ namespace IOB_WIN
///
/// parametri di connessione
///
- protected connParamS7Torri parametri;
+ protected connParamS7 parametri;
///
/// Variabile x salvataggio iobConf locale
///
@@ -178,7 +178,7 @@ namespace IOB_WIN
// init conf
_IOBConf = IOBConf;
// inizializzo parametri...
- parametri = new connParamS7Torri()
+ parametri = new connParamS7()
{
ipAdrr = "127.0.0.1",
tipoCpu = CpuType.S7200,
diff --git a/IOB-WIN/specialConfig.cs b/IOB-WIN/specialConfig.cs
index de013531..43a1d416 100644
--- a/IOB-WIN/specialConfig.cs
+++ b/IOB-WIN/specialConfig.cs
@@ -3,25 +3,46 @@
namespace IOB_WIN
{
///
- /// Implementazione classe connessione SIEMENS con S7.net
+ /// Implementazione classe connessione SIEMENS con S7.net,
+ /// comprensiva dei parametri delle aree di memoria
///
public class connParamS7
{
+ ///
+ /// Indirizzo IP del PLC
+ ///
public string ipAdrr = "";
-
+ ///
+ /// Tipo CPU Siemens
+ ///
public CpuType tipoCpu = CpuType.S7300;
+ ///
+ /// Slot comunicazione
+ ///
public short slot = 0;
+ ///
+ /// Rack comunicazione
+ ///
public short rack = 0;
+ ///
+ /// Timeout ping
+ ///
public int pingMsTimeout = 250;
- }
- ///
- /// Configurazione specifiche memoria x S7 Torri
- ///
- public class connParamS7Torri : connParamS7
- {
+ ///
+ /// Base area x lettura
+ ///
public string memAddrRead = "";
+ ///
+ /// Base area x scrittura
+ ///
public string memAddrWrite = "";
+ ///
+ /// Size memoria lettura
+ ///
public int memSizeRead = 0;
+ ///
+ /// Size memoria scrittura
+ ///
public int memSizeWrite = 0;
}
}