diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs index 090ffaf6..3208a847 100644 --- a/IOB-UT-NEXT/ToMapo.cs +++ b/IOB-UT-NEXT/ToMapo.cs @@ -189,82 +189,6 @@ namespace IOB_UT_NEXT #endregion Public Methods } -#if false - /// - /// Struttura della conf memoria ModBus - /// - public class BaseModbusConf - { - public enum DataType - { - ND = 0, - BIT, - INT, - REAL - } - - public enum MemType - { - ND = 0, - DiscreteInput = 1, - Coil = 2, - InputRegister = 3, - HoldingRegister = 4 - } - - /// - /// Elenco aree memoria ModBus in lettura - /// - public List mMapRead { get; set; } = new List(); - - /// - /// Elenco aree memoria ModBus in scrittura - /// - public List mMapWrite { get; set; } = new List(); - - /// - /// struttura di base memoria ModBus - /// - public class ModbusMemArea - { - public ushort BaseAddr { get; set; } = 0; - public string RawAddr { get; set; } = ""; - public ushort Size { get; set; } = 0; - - [JsonConverter(typeof(StringEnumConverter))] - public MemType Type { get; set; } = MemType.ND; - - public List VarList { get; set; } = new List(); - } - - public class VarConf - { - public string description { get; set; } = ""; - public int factor { get; set; } = 1; - - public bool hasRange - { - get - { - return !this.minVal.Equals(this.maxVal); - } - } - - public ushort index { get; set; } = 0; - public int maxVal { get; set; } = 0; - public string memAddr { get; set; } = ""; - public int minVal { get; set; } = 0; - public string name { get; set; } = "none"; - public ushort size { get; set; } = 0; - - [JsonConverter(typeof(StringEnumConverter))] - public DataType tipoMem { get; set; } = DataType.ND; - - public string value { get; set; } = ""; - } - } -#endif - /// /// Classe gestione configurazione parametri di base x configuraizone estesa (es MTConnect, OPC-UA, ...) /// @@ -377,6 +301,18 @@ namespace IOB_UT_NEXT #endregion Public Properties } + /// + /// COnfigurazione blocchi x accesso memoria ottimizzato + /// + public class MemBlockConf + { + #region Public Properties + + public Dictionary ReadBlocks { get; set; } = new Dictionary(); + + #endregion Public Properties + } + /// /// Classe gestione configurazione parametri specifici MTC da BaseParamConf /// diff --git a/IOB-WIN-NEXT/App.config b/IOB-WIN-NEXT/App.config index 8ce1851f..0e3ca8f3 100644 --- a/IOB-WIN-NEXT/App.config +++ b/IOB-WIN-NEXT/App.config @@ -1,155 +1,155 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini index 45436e05..4528af4b 100644 --- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini +++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini @@ -72,6 +72,6 @@ CLI_INST=SteamWareSim ;STARTLIST=FP_TR2 ;STARTLIST=PING ;STARTLIST=SIM_PIZ03 -STARTLIST=PIZ04 +STARTLIST=PIZ05 MAXCNC=10 \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini b/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini index 0f90a0d0..2ca54e21 100644 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04.ini @@ -58,12 +58,14 @@ FORCE_DYN_DATA=TRUE DELTA_VAL=0.1 ; clock base (da 10ms) -timerIntMs=150 +timerIntMs=125 ; conf parametri memoria READ/WRITE PARAM_CONF=PIZ04.json NO_PING=FALSE +; conf blocchi memoria x READ +MEM_BLOCK=PIZ04_MBlock.json ; conf aree allarme ALARM_CONF=PIZ04_alarm.json diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ04.json b/IOB-WIN-NEXT/DATA/CONF/PIZ04.json index 44bf0e8b..d7e8b895 100644 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ04.json +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04.json @@ -8,20 +8,20 @@ "index": 489, "size": 2, "minVal": -200, - "maxVal": 200, - "unit": "C" - }, - "SetHighTempGNC": { - "name": "SetHighTempGNC", - "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", - "memAddr": "40491", - "tipoMem": "Real", - "index": 491, - "size": 2, - "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, + //"SetHighTempGNC": { + // "name": "SetHighTempGNC", + // "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", + // "memAddr": "40491", + // "tipoMem": "Real", + // "index": 491, + // "size": 2, + // "minVal": -200, + // "maxVal": 301, + // "unit": "C" + //}, "SetLowTempAmb": { "name": "SetLowTempAmb", "description": "Set point di avviso per bassa temperatura ambiente nell'impianto", @@ -30,7 +30,7 @@ "index": 421, "size": 2, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "SetHighTempAmb": { @@ -41,7 +41,7 @@ "index": 423, "size": 2, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" } }, @@ -54,7 +54,7 @@ "index": 1, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 360, "minVal": 0, "maxVal": 100, @@ -68,7 +68,7 @@ "index": 3, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": 0, "maxVal": 400, @@ -82,7 +82,7 @@ "index": 19, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": 0, "maxVal": 400, @@ -96,7 +96,7 @@ "index": 21, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": 0, "maxVal": 400, @@ -110,10 +110,10 @@ "index": 27, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "TempAmb": { @@ -124,10 +124,10 @@ "index": 11, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "SetLowTempGNC": { @@ -138,26 +138,26 @@ "index": 489, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, - "unit": "C" - }, - "SetHighTempGNC": { - "name": "SetHighTempGNC", - "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", - "memAddr": "40491", - "tipoMem": "Real", - "index": 491, - "size": 2, - "func": "MEDIAN", - "period": 120, - "factor": 1, - "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, + //"SetHighTempGNC": { + // "name": "SetHighTempGNC", + // "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", + // "memAddr": "40491", + // "tipoMem": "Real", + // "index": 491, + // "size": 2, + // "func": "MEDIAN", + // "period": 90, + // "factor": 1, + // "minVal": -200, + // "maxVal": 301, + // "unit": "C" + //}, "SetLowTempAmb": { "name": "SetLowTempAmb", "description": "Set point di avviso per bassa temperatura ambiente nell'impianto", @@ -166,10 +166,10 @@ "index": 421, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "SetHighTempAmb": { @@ -180,10 +180,10 @@ "index": 423, "size": 2, "func": "MEDIAN", - "period": 120, + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" } } diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ04_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/PIZ04_MBlock.json new file mode 100644 index 00000000..e6c4623d --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ04_MBlock.json @@ -0,0 +1,6 @@ +{ + "ReadBlocks": { + "40001": 64, + "40421": 72 + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ05.ini b/IOB-WIN-NEXT/DATA/CONF/PIZ05.ini index 6a5cddd4..6a2d8c6c 100644 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ05.ini +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ05.ini @@ -13,8 +13,8 @@ IP=hambaganzola.dyndns.org PORT=502 [SERVER] -;MPIP=https://localhost:44339 -MPIP=https://gwms.egalware.com +MPIP=https://localhost:44339 +;MPIP=https://gwms.egalware.com MPURL=/api CMDBASE=/IOB/input/ CMDFLOG=/IOB/flog/ @@ -27,7 +27,6 @@ CMDREBO=/IOB/sendReboot?idxMacchina= ADDR_READ=40001 ADDR_WRITE=40401 SIZE_READ=34 -;SIZE_READ=5046 SIZE_WRITE=358 @@ -59,12 +58,14 @@ FORCE_DYN_DATA=TRUE DELTA_VAL=0.1 ; clock base (da 10ms) -timerIntMs=150 +timerIntMs=125 ; conf parametri memoria READ/WRITE PARAM_CONF=PIZ05.json NO_PING=TRUE +; conf blocchi memoria x READ +MEM_BLOCK=PIZ05_MBlock.json ; conf aree allarme ALARM_CONF=PIZ05_alarm.json diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ05.json b/IOB-WIN-NEXT/DATA/CONF/PIZ05.json index 994c5db7..45da7ad0 100644 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ05.json +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ05.json @@ -8,20 +8,20 @@ "index": 489, "size": 2, "minVal": -200, - "maxVal": 200, - "unit": "C" - }, - "SetHighTempGNC": { - "name": "SetHighTempGNC", - "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", - "memAddr": "40491", - "tipoMem": "Real", - "index": 491, - "size": 2, - "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, + //"SetHighTempGNC": { + // "name": "SetHighTempGNC", + // "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", + // "memAddr": "40491", + // "tipoMem": "Real", + // "index": 491, + // "size": 2, + // "minVal": -200, + // "maxVal": 301, + // "unit": "C" + //}, "SetLowTempAmb": { "name": "SetLowTempAmb", "description": "Set point di avviso per bassa temperatura ambiente nell'impianto", @@ -30,7 +30,7 @@ "index": 421, "size": 2, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "SetHighTempAmb": { @@ -41,7 +41,7 @@ "index": 423, "size": 2, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" } }, @@ -53,8 +53,8 @@ "tipoMem": "Real", "index": 1, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 270, "minVal": 0, "maxVal": 100, @@ -67,8 +67,8 @@ "tipoMem": "Real", "index": 3, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": 0, "maxVal": 400, @@ -81,8 +81,8 @@ "tipoMem": "Real", "index": 19, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": 0, "maxVal": 400, @@ -95,8 +95,8 @@ "tipoMem": "Real", "index": 21, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": 0, "maxVal": 400, @@ -109,11 +109,11 @@ "tipoMem": "Real", "index": 27, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "TempAmb": { @@ -123,11 +123,11 @@ "tipoMem": "Real", "index": 11, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "SetLowTempGNC": { @@ -137,27 +137,27 @@ "tipoMem": "Real", "index": 489, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, - "unit": "C" - }, - "SetHighTempGNC": { - "name": "SetHighTempGNC", - "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", - "memAddr": "40491", - "tipoMem": "Real", - "index": 491, - "size": 2, - "func": "MAX", - "period": 120, - "factor": 1, - "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, + //"SetHighTempGNC": { + // "name": "SetHighTempGNC", + // "description": "Set point di avviso per alta temperatura all'uscita del vaporizzatore GNC", + // "memAddr": "40491", + // "tipoMem": "Real", + // "index": 491, + // "size": 2, + // "func": "MEDIAN", + // "period": 90, + // "factor": 1, + // "minVal": -200, + // "maxVal": 301, + // "unit": "C" + //}, "SetLowTempAmb": { "name": "SetLowTempAmb", "description": "Set point di avviso per bassa temperatura ambiente nell'impianto", @@ -165,11 +165,11 @@ "tipoMem": "Real", "index": 421, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" }, "SetHighTempAmb": { @@ -179,11 +179,11 @@ "tipoMem": "Real", "index": 423, "size": 2, - "func": "MAX", - "period": 120, + "func": "MEDIAN", + "period": 90, "factor": 1, "minVal": -200, - "maxVal": 200, + "maxVal": 301, "unit": "C" } } diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ05_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/PIZ05_MBlock.json new file mode 100644 index 00000000..e6c4623d --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ05_MBlock.json @@ -0,0 +1,6 @@ +{ + "ReadBlocks": { + "40001": 64, + "40421": 72 + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json b/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json index 8be1bfee..bcb583bc 100644 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json @@ -4,7 +4,7 @@ "tipoMem": "DInt", "memAddr": "40901", "index": 901, - "size": 4, + "size": 2, "messages": [ "Basso livello serbatoio", "Alto livello serbatoio", @@ -21,22 +21,6 @@ "##", "Allarme rilevatore gas 3", "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", "##" ] }, @@ -45,7 +29,7 @@ "tipoMem": "DInt", "memAddr": "40907", "index": 907, - "size": 4, + "size": 2, "messages": [ "##", "Pulsante di Emergenza Premuto", @@ -62,22 +46,6 @@ "##", "##", "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", "##" ] } diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json.bak b/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json.bak deleted file mode 100644 index bcb583bc..00000000 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ05_alarm.json.bak +++ /dev/null @@ -1,52 +0,0 @@ -[ - { - "description": "Allarmi Impianto", - "tipoMem": "DInt", - "memAddr": "40901", - "index": 901, - "size": 2, - "messages": [ - "Basso livello serbatoio", - "Alto livello serbatoio", - "Errore trasmettitore livello", - "Bassa pressione serbatoio", - "Alta pressione serbatoio", - "##", - "##", - "Allarme rilevatore gas 1", - "##", - "##", - "Allarme rilevatore gas 2", - "##", - "##", - "Allarme rilevatore gas 3", - "##", - "##" - ] - }, - { - "description": "Emergenza", - "tipoMem": "DInt", - "memAddr": "40907", - "index": 907, - "size": 2, - "messages": [ - "##", - "Pulsante di Emergenza Premuto", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##", - "##" - ] - } -] \ No newline at end of file diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index 57662873..ffeb02eb 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -391,6 +391,12 @@ Always + + Always + + + Always + Always diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs index c38ea12b..57f284f0 100644 --- a/IOB-WIN-NEXT/IobGeneric.cs +++ b/IOB-WIN-NEXT/IobGeneric.cs @@ -2964,7 +2964,7 @@ namespace IOB_WIN_NEXT { // invio su cloud conf memoria... string rawData = JsonConvert.SerializeObject(memMap); - utils.callUrlNow($"{urlSaveMemMap}", rawData); + var resp = utils.callUrlNow($"{urlSaveMemMap}", rawData); // salvo ANCHE come parametri i valori... objItem currItem = new objItem(); List allParam = new List(); diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs index 7d798664..5d23e960 100644 --- a/IOB-WIN-NEXT/IobModbusTCP.cs +++ b/IOB-WIN-NEXT/IobModbusTCP.cs @@ -5,11 +5,13 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Windows.Forms; namespace IOB_WIN_NEXT { @@ -34,6 +36,11 @@ namespace IOB_WIN_NEXT protected ModbusClient currPLC; + /// + /// Copia locale dei valori in Holding Registry, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo + /// + protected Dictionary HoldingRegisterLUT = new Dictionary(); + /// /// Ultimo controllo ping x evitare ping flood... /// @@ -49,11 +56,6 @@ namespace IOB_WIN_NEXT /// protected Dictionary memSetR = new Dictionary(); - /// - /// Setup blocchi memorie write (indirizzo inizio, size) - /// - protected Dictionary memSetW = new Dictionary(); - /// /// parametri di connessione /// @@ -75,7 +77,6 @@ namespace IOB_WIN_NEXT public IobModbusTCP(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { lgInfo("NEW IOB ModBus TCP"); - setupMemBlocks(); memMap = new plcMemMap(); if (IOBConf != null) { @@ -212,7 +213,13 @@ namespace IOB_WIN_NEXT return valUInt; } - private Dictionary getDataDictionary(Dictionary memItemList, ref Dictionary outVal) + /// + /// Recupero dati da singole letture + /// + /// Valori da processare + /// Dizionario valori in uscita + /// Errori di lettura + private Dictionary getDataDictionary(Dictionary memItemList, bool useLUT, ref Dictionary outVal) { Dictionary readErrorList = new Dictionary(); // inizializzo i valori @@ -221,6 +228,11 @@ namespace IOB_WIN_NEXT // procedo x ogni valore configurato... foreach (var item in memItemList) { + // attesa 50 ms prima di procedere x evitare burst dati + if (useLUT) + { + Thread.Sleep(50); + } double valore = 0; double valoreScal = 0; bool dataOk = false; @@ -246,7 +258,18 @@ namespace IOB_WIN_NEXT break; case modBusAddrType.HoldingRegister: - listInt = readHoldReg(item.Value.index - 1, item.Value.size); + if (useLUT) + { + int lutAddress = 40000 + item.Value.index; + if (HoldingRegisterLUT.ContainsKey(lutAddress)) + { + listInt = HoldingRegisterLUT[lutAddress]; + } + } + else + { + listInt = readHoldReg(item.Value.index - 1, item.Value.size); + } valore = convertFromReg(listInt, item.Value.size, item.Value.tipoMem); break; @@ -303,6 +326,54 @@ namespace IOB_WIN_NEXT } } + /// + /// Effettua lettura blocco memoria indicato e lo salva in copia locale HoldingRegisterLUT + /// + /// Indirizzo di aprtenza + /// NUm registri da leggere (max 120) + private void readBlockHoldingReg(int startAddr, int numReg) + { + // fix massima lunghezza pacchetto + if (numReg > 120) + { + lgError($"Attenzione richiesta lettura blocco troppo grande: numReg {numReg} --> 120"); + numReg = 120; + } + // si lavora rispetto all'indirizzo base 40001 + int baseAddr = 40001; + int[] rawData = new int[2]; + try + { + stopwatch.Restart(); + rawData = currPLC.ReadHoldingRegisters(startAddr - baseAddr, numReg); + stopwatch.Stop(); + lgInfo($"Lettura in blocco HoldingRegisters| startAddr: {startAddr} | numReg {numReg} | {stopwatch.ElapsedMilliseconds}ms"); + // salvo in LUT la versione ESPLOSA 2 byte alla volta... + if (rawData.Length > 0) + { + for (int i = 0; i < rawData.Length / 2; i++) + { + int[] thisSet = new int[2]; + Array.Copy(rawData, i * 2, thisSet, 0, 2); + // salvo nel registro... + int currAddr = startAddr + i * 2; + if (HoldingRegisterLUT.ContainsKey(currAddr)) + { + HoldingRegisterLUT[currAddr] = thisSet; + } + else + { + HoldingRegisterLUT.Add(currAddr, thisSet); + } + } + } + } + catch (Exception exc) + { + lgError($"Eccezione in readBlockHoldingReg{Environment.NewLine}{exc}"); + } + } + #endregion Private Methods #region Protected Methods @@ -490,45 +561,11 @@ namespace IOB_WIN_NEXT { lgError(exc, "Errore in parse parametri da IOBConf"); } - // ora tento avvio PLC... SE PING OK... - IPStatus esitoPing = testPingMachine; - if (esitoPing == IPStatus.Success) - { - needRefresh = false; - try - { - //Ip-Address and Port of Modbus-TCP-Server - currPLC = new ModbusClient(parametri.ipAdrr, parametri.port); - // disconnetto e connetto... - if (isVerboseLog) - { - lgInfo("ModBus TCP: tryDisconnect"); - } - tryDisconnect(); - - // lo ripeto x evitare che ci sia un loop... e tryConnect richiami la procedura corrente... - needRefresh = false; - lgInfo("ModBus TCP: tryConnect"); - tryConnect(); - lgInfo("End init Adapter ModBusTCP"); - if (isVerboseLog) - { - lgInfo("ModBus TCP CONNESSIONE AVVENUTA"); - } - } - catch (Exception exc) - { - lgError(exc, "Errore in INIT ModBusTCP"); - } - } - else - { - lgError($"Errore in ping: esito {esitoPing}"); - } - parentForm.commPlcActive = false; // carico conf vettore memoria... loadMemConf(); + // avvio conf blocchi memoria + setupMemBlocks(); // aggiungo DELTA x calcolo min/MAX... string deltaValStr = getOptPar("DELTA_VAL"); if (!string.IsNullOrEmpty(deltaValStr)) @@ -572,6 +609,44 @@ namespace IOB_WIN_NEXT lgError(exc, "Errore in contapezzi ModBusTCP"); } } + + // ora tento avvio PLC... SE PING OK... + IPStatus esitoPing = testPingMachine; + if (esitoPing == IPStatus.Success) + { + needRefresh = false; + try + { + //Ip-Address and Port of Modbus-TCP-Server + currPLC = new ModbusClient(parametri.ipAdrr, parametri.port); + + // disconnetto e connetto... + if (isVerboseLog) + { + lgInfo("ModBus TCP: tryDisconnect"); + } + tryDisconnect(); + + // lo ripeto x evitare che ci sia un loop... e tryConnect richiami la procedura corrente... + needRefresh = false; + lgInfo("ModBus TCP: tryConnect"); + tryConnect(); + lgInfo("End init Adapter ModBusTCP"); + if (isVerboseLog) + { + lgInfo("ModBus TCP CONNESSIONE AVVENUTA"); + } + } + catch (Exception exc) + { + lgError(exc, "Errore in INIT ModBusTCP"); + } + } + else + { + lgError($"Errore in ping: esito {esitoPing}"); + } + parentForm.commPlcActive = false; } else { @@ -583,8 +658,33 @@ namespace IOB_WIN_NEXT /// /// effettua il setup dei memblock da gestire (NON leggo intera memoria ma tanti blocchi...) /// - protected virtual void setupMemBlocks() - { } + protected void setupMemBlocks() + { + // se configurato -_> deserializzo + string confFile = getOptPar("MEM_BLOCK"); + if (!string.IsNullOrEmpty(confFile)) + { + string jsonFileName = $"{Application.StartupPath}/DATA/CONF/{confFile}"; + lgInfo($"Apertura file {jsonFileName}"); + using (StreamReader reader = new StreamReader(jsonFileName)) + { + string jsonData = reader.ReadToEnd(); + if (!string.IsNullOrEmpty(jsonData)) + { + lgInfo($"File json MemBlock composto da {jsonData.Length} caratteri"); + try + { + var currMem = JsonConvert.DeserializeObject(jsonData); + memSetR = currMem.ReadBlocks; + } + catch (Exception exc) + { + lgError($"Errore in setupMemBlock{Environment.NewLine}{exc}"); + } + } + } + } + } /// /// Test connessione CNC @@ -768,26 +868,39 @@ namespace IOB_WIN_NEXT } else { + Dictionary readErrorList = new Dictionary(); + Dictionary readErrorListRepeat = new Dictionary(); + bool useLUT = memSetR != null && memSetR.Count > 0; + // se configurato leggo IN BLOCCHI da memoria... + if (useLUT) + { + foreach (var item in memSetR) + { + readBlockHoldingReg(item.Key, item.Value); + } + } + // procedo ... try { // processo x ogni valore configurato... if (memMap.mMapRead.Count > 0) { - Dictionary readErrorList = new Dictionary(); - Dictionary readErrorListRepeat = new Dictionary(); var memItemList = memMap.mMapRead; - readErrorList = getDataDictionary(memItemList, ref outVal); + readErrorList = getDataDictionary(memItemList, useLUT, ref outVal); // se qualcosa è andato storto riprovo a caricare SOLO gli errori... 1 sola volta if (readErrorList.Count > 0) { - lgInfo($"Effettuo rilettura per {readErrorList.Count} variabili"); - readErrorListRepeat = getDataDictionary(readErrorList, ref outVal); + lgInfo($"Attesa prima di rilettura | LUT: {useLUT}"); + // attendo 3 sec + Thread.Sleep(3000); + lgInfo($"Effettuo rilettura per {readErrorList.Count} variabili | LUT: {useLUT}"); + readErrorListRepeat = getDataDictionary(readErrorList, useLUT, ref outVal); } // se avessi ancora errori --> disconnetto if (readErrorListRepeat.Count > 0) { - lgInfo("Trovati valori non validi al secondo tentativo --> invalido valori letti e resetto adapter con tryDisconnect!"); + lgInfo($"Trovati valori non validi al secondo tentativo | LUT: {useLUT} --> invalido valori letti e resetto adapter con tryDisconnect!"); tryDisconnect(); // invalido output outVal = new Dictionary(); @@ -800,12 +913,12 @@ namespace IOB_WIN_NEXT } else { - lgInfo($"getDynData: {memMap.mMapRead.Count} record in mMapRead"); + lgInfo($"getDynData: {memMap.mMapRead.Count} record in mMapRead | LUT: {useLUT}"); } } catch (Exception exc) { - lgError(exc, "Errore in getDynData x ModBus TCP PLC --> ciclo disconnect/reconnect"); + lgError(exc, "Errore in getDynData x ModBus TCP PLC --> ciclo disconnect/reconnect | LUT: {useLUT}"); tryDisconnect(); outVal = new Dictionary(); tryConnect(); @@ -880,9 +993,16 @@ namespace IOB_WIN_NEXT public int[] readInputReg(int startAddr, int qty) { int[] answ = new int[2]; - if (currPLC.Connected) + try { - answ = currPLC.ReadInputRegisters(startAddr, qty); + if (currPLC.Connected) + { + answ = currPLC.ReadInputRegisters(startAddr, qty); + } + } + catch (Exception exc) + { + lgError($"Errore in readInputReg{Environment.NewLine}{exc}"); } return answ; } diff --git a/IOB-WIN-NEXT/IobModbusTCPHam.cs b/IOB-WIN-NEXT/IobModbusTCPHam.cs index 83148ecb..12accd6a 100644 --- a/IOB-WIN-NEXT/IobModbusTCPHam.cs +++ b/IOB-WIN-NEXT/IobModbusTCPHam.cs @@ -34,6 +34,7 @@ namespace IOB_WIN_NEXT public IobModbusTCPHam(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) { lgInfo("NEW IOB ModBus TCP HAM"); + // provo lettura una prima volta i dati DYN if (currPLC != null && currPLC.Connected) { @@ -102,6 +103,30 @@ namespace IOB_WIN_NEXT #region Private Methods + private void testBlockRead(int baseAddr, int numByte) + { + int baseHold = 40001; + int[] readTestFull = new int[2]; + lgInfo($"-------------------- Inizio test lettura {baseAddr} --------------------"); + try + { + stopwatch.Restart(); + readTestFull = currPLC.ReadHoldingRegisters(baseAddr - baseHold, numByte); + stopwatch.Stop(); + lgInfo($"Stats lettura | {readTestFull.Length} val | {stopwatch.ElapsedMilliseconds}ms"); + } + catch + { } + + for (int i = 0; i < readTestFull.Length / 2; i++) + { + int[] thisSet = new int[2]; + Array.Copy(readTestFull, i * 2, thisSet, 0, 2); + lgInfo($"{baseAddr + i * 2:000} | HoldingRegisters: {thisSet[0]} / {thisSet[1]} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}"); + } + lgInfo("-------------------- Completato test lettura {baseAddr} --------------------"); + } + private void testRead() { //Ip-Address and Port of Modbus-TCP-Server @@ -111,22 +136,10 @@ namespace IOB_WIN_NEXT //modbusClient.WriteMultipleCoils(4, new bool[] { true, true, true, true, true, true, true, true, true, true }); //Write Coils starting with Address 5 //bool[] readCoils = modbusClient.ReadCoils(9, 10); //Read 10 Coils from Server, starting with address 10 //int[] readHoldingRegisters = currPLC.ReadHoldingRegisters(0, 34); //Read 10 Holding Registers from Server, starting with Address 1 - - int[] readHR1000 = currPLC.ReadHoldingRegisters(0, 100); //Read 10 Holding Registers from Server, starting with Address 1 - - //// Console Output - //for (int i = 0; i < readCoils.Length; i++) - // Console.WriteLine("Value of Coil " + (9 + i + 1) + " " + readCoils[i].ToString()); - - for (int i = 0; i < readHR1000.Length / 2; i++) + foreach (var item in memSetR) { - Console.WriteLine($"Value of HoldingRegister {(i)} | {readHR1000[i]} / {readHR1000[i + 1]}"); - int[] thisSet = new int[2]; - Array.Copy(readHR1000, i, thisSet, 0, 2); - Console.WriteLine($"Convert val HoldingRegister {(i)} | {ModbusClient.ConvertRegistersToFloat(thisSet)}"); + testBlockRead(item.Key, item.Value); } - //Console.Write("Press any key to continue . . . "); - //Console.ReadKey(true); } #endregion Private Methods @@ -174,15 +187,6 @@ namespace IOB_WIN_NEXT B_input = byteSignals; } - /// - /// effettua il setup dei memblock da gestire (NON leggo intera memoria ma tanti blocchi...) - /// - protected override void setupMemBlocks() - { - // da calcolare... ora setup cablato... - memSetR.Add(1, 34); - } - #endregion Protected Methods #region Public Methods