From 2bc5177a40ec0b6de732b38952b8c73a24efc3e8 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 21 Nov 2022 19:59:35 +0100 Subject: [PATCH] SAIM - Aggiunta gestione EnableTest - step testing lettura memBlock all'avvio --- IOB-UT-NEXT/Enums.cs | 16 +- IOB-UT-NEXT/baseUtils.cs | 21 +++ IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini | 8 +- .../DATA/CONF/GIACO_SAIM_003_MBlock.json | 2 + IOB-WIN-NEXT/IobGeneric.cs | 10 ++ IOB-WIN-NEXT/IobModbusTCP.cs | 144 +++++++++++++++++- IOB-WIN-NEXT/IobModbusTCPSaim.cs | 39 +---- 7 files changed, 199 insertions(+), 41 deletions(-) diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs index 60cefa8f..8b141de7 100644 --- a/IOB-UT-NEXT/Enums.cs +++ b/IOB-UT-NEXT/Enums.cs @@ -174,12 +174,25 @@ namespace IOB_UT_NEXT public enum MachineSetupMode { ND = 0, + /// - /// Modalità Mecolpress (3 parametri IN, se variati --> porto a 1 la variabile di controllo) + /// Modalità Mecolpress (3 parametri IN, se variati --> porto a 1 la variabile di controllo) /// MECOLPRESS = 1 } + /// + /// Tipo di memoria Modbus + /// + public enum modbusMemType + { + Coil = 0, + DiscreteInput = 1, + NotDefined = 2, + InputRegister = 3, + HoldingRegister = 4 + } + /// /// StFlag32: set di 32 bit (4 word) contente semaforo di variabili /// @@ -544,5 +557,4 @@ namespace IOB_UT_NEXT /// ULog } - } \ No newline at end of file diff --git a/IOB-UT-NEXT/baseUtils.cs b/IOB-UT-NEXT/baseUtils.cs index 9e5d63f6..cf312fdd 100644 --- a/IOB-UT-NEXT/baseUtils.cs +++ b/IOB-UT-NEXT/baseUtils.cs @@ -66,6 +66,27 @@ namespace IOB_UT_NEXT #region Public Methods + /// + /// Restituisce la prima cifra (a sx) da un numero (es x decodere quale memoria modbus sia) + /// + /// Numero di cui trovare la priam cifra + /// + public static int getFirstInt(int num) + { + if (num >= 100000000) num /= 100000000; + if (num >= 10000) num /= 10000; + if (num >= 100) num /= 100; + if (num >= 10) num /= 10; + +#if false + // formulazione alternativa con ciclo... + while (num >= 10) + num /= 10; +#endif + + return num; + } + /// /// formatta un numero in forma binaria 0/1 /// diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini index b2923fa2..69721ced 100644 --- a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini +++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003.ini @@ -24,11 +24,15 @@ CMDADV1=?valore= CMDREBO=/sendReboot.aspx?idxMacchina= [MEMORY] -ADDR_READ=40001 -ADDR_WRITE=40001 +ADDR_READ=40000 +ADDR_WRITE=40000 SIZE_READ=200 SIZE_WRITE=0 HR_BASE_ADDR=40000 +;DELTA_BASE=0 +DELTA_BASE=1 +;0=false,1=true +MODBUS_EXT_REG=1 [BLINK] diff --git a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json index f20d1551..431c7d15 100644 --- a/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json +++ b/IOB-WIN-NEXT/DATA/CONF/GIACO_SAIM_003_MBlock.json @@ -1,5 +1,7 @@ { "ReadBlocks": { + "10000": 10, + "10100": 10, "40010": 10, "40100": 40, "40140": 30 diff --git a/IOB-WIN-NEXT/IobGeneric.cs b/IOB-WIN-NEXT/IobGeneric.cs index a637919c..72c9713f 100644 --- a/IOB-WIN-NEXT/IobGeneric.cs +++ b/IOB-WIN-NEXT/IobGeneric.cs @@ -340,6 +340,16 @@ namespace IOB_WIN_NEXT return baseUtils.CRB("DemoInSample"); } } + /// + /// Verifica se sia abilitato test lettura blocchi memoria all'avvio + /// + public static bool EnableTest + { + get + { + return baseUtils.CRB("enableTest"); + } + } /// /// Verifica se sia in modalità DEMO x dati OUTPUT diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs index 3c124a4a..84a92234 100644 --- a/IOB-WIN-NEXT/IobModbusTCP.cs +++ b/IOB-WIN-NEXT/IobModbusTCP.cs @@ -194,6 +194,7 @@ namespace IOB_WIN_NEXT { foreach (var item in memSetR) { + // verifico il tipo di dati da leggere e salvare... FIXME TODO FARE !!! readBlockHoldingReg(item.Key, item.Value, parametri.holdRegBaseAddr); int waitTime = rnd.Next(minWait, maxWait); Thread.Sleep(waitTime); @@ -575,14 +576,33 @@ namespace IOB_WIN_NEXT #region Protected Fields + /// + /// Copia locale dei valori in COIL (OUT) | 0.000/09.999, oppure 0.000/65.536 = 0xFFFF, come + /// array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo + /// + protected Dictionary CoilsLUT = new Dictionary(); + protected ModbusClient currPLC; /// - /// Copia locale dei valori in Holding Registry, come array chiave (int) valori int[] letti - /// tramite ModBus, da convertire secondo tipo + /// Copia locale dei valori in Discrete Inputs (IN) | 10.000/19.999, oppure 100.000/165.536 + /// = 1xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire + /// secondo tipo + /// + protected Dictionary DiscreteInputLUT = new Dictionary(); + + /// + /// Copia locale dei valori in Holding Registers | 40.000/49.999, oppure 400.000/465.536 = + /// 4xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo /// protected Dictionary HoldingRegisterLUT = new Dictionary(); + /// + /// Copia locale dei valori in Input Registers | 30.000/39.999, oppure 300.000/365.536 = + /// 3xFFFF, come array chiave (int) valori int[] letti tramite ModBus, da convertire secondo tipo + /// + protected Dictionary InputRegisterLUT = new Dictionary(); + /// /// Ultimo controllo ping x evitare ping flood... /// @@ -853,6 +873,8 @@ namespace IOB_WIN_NEXT parametri.holdRegBaseAddr = fIni.ReadInteger("MEMORY", "HR_BASE_ADDR", 40001); // valore delta base e shift deltaBase = fIni.ReadInteger("MEMORY", "DELTA_BASE", 0); + // verifico eventuale parametro memoria estesa (non 0...10'000 ma 0...xFFFF=65536) + modbusExtReg = fIni.ReadBoolean("MEMORY", "MODBUS_EXT_REG"); // salvo vettori memoria... lgInfoStartup("Set RawInput dimensions..."); RawInput = new byte[parametri.memSizeRead]; @@ -1022,6 +1044,104 @@ namespace IOB_WIN_NEXT return answ; } + /// + /// Effettua ciclo letture di ogni area configurata + /// + /// indirizzo di partenza + /// num valori da leggere + protected void testBlockReadExt(int baseAddr, int numVals) + { + int baseHold = deltaBase; + modbusMemType currMemType = modbusMemType.NotDefined; + int maxVal = 10000; + int baseMult = 10000; + int[] readTestInt = new int[2]; + bool[] readTestBool = new bool[2]; + lgTrace($"-------------------- Inizio test lettura EXT {baseAddr} --------------------"); + try + { + stopwatch.Restart(); + + // memoria estesa... 0 ... xFFFF per ogni set da 100'000... + if (modbusExtReg) + { + maxVal = 65536; + baseMult = 100000; + } + + // determino tipo di memoria + if (baseAddr <= maxVal) + { + currMemType = modbusMemType.Coil; + } + else if (baseAddr <= baseMult + maxVal) + { + currMemType = modbusMemType.DiscreteInput; + } + else if (baseAddr <= 3 * baseMult + maxVal) + { + currMemType = modbusMemType.InputRegister; + } + else + { + currMemType = modbusMemType.HoldingRegister; + } + switch (currMemType) + { + case modbusMemType.Coil: + readTestBool = currPLC.ReadCoils(baseAddr - baseHold, numVals); + break; + + case modbusMemType.DiscreteInput: + readTestBool = currPLC.ReadDiscreteInputs(baseAddr - (1 * baseMult + baseHold), numVals); + break; + + case modbusMemType.InputRegister: + readTestInt = currPLC.ReadInputRegisters(baseAddr - (3 * baseMult + baseHold), numVals); + break; + + case modbusMemType.HoldingRegister: + readTestInt = currPLC.ReadHoldingRegisters(baseAddr - (4 * baseMult + baseHold), numVals); + break; + + case modbusMemType.NotDefined: + default: + break; + } + stopwatch.Stop(); + lgTrace($"Stats lettura | {readTestInt.Length} val | {stopwatch.ElapsedMilliseconds}ms"); + } + catch + { } + + switch (currMemType) + { + case modbusMemType.Coil: + case modbusMemType.DiscreteInput: + for (int i = 0; i < readTestBool.Length; i++) + { + lgTrace($"{currMemType} | {baseAddr + i:000} | Val: {readTestBool[i]}"); + } + break; + + case modbusMemType.InputRegister: + case modbusMemType.HoldingRegister: + for (int i = 0; i < readTestInt.Length / 2; i++) + { + int[] thisSet = new int[2]; + Array.Copy(readTestInt, i * 2, thisSet, 0, 2); + lgTrace($"{currMemType} | {baseAddr + i * 2:000} | Valori: {thisSet[0]} / {thisSet[1]} | Val Int: {ModbusClient.ConvertRegistersToInt(thisSet)} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}"); + } + break; + + case modbusMemType.NotDefined: + default: + lgTrace($"Errore: tipo memoria non definitito per {baseAddr} / {numVals}"); + break; + } + lgTrace($"-------------------- Completato test lettura {baseAddr} --------------------"); + } + /// /// Test connessione CNC /// @@ -1112,7 +1232,7 @@ namespace IOB_WIN_NEXT //answ = (currStatus == OptCheckCondInt[cKey].ValOk); // controllo se il valore sia in elenco di quelli validi... answ = OptCheckCondInt[cKey].ValOk.Contains(currStatus); - lgTrace($"testIntCondition for {cKey} | BaseAddr: {OptCheckCondInt[cKey].BaseAddr} | currStatus: {currStatus} | ValOk: {string.Join(",",OptCheckCondInt[cKey].ValOk)}"); + lgTrace($"testIntCondition for {cKey} | BaseAddr: {OptCheckCondInt[cKey].BaseAddr} | currStatus: {currStatus} | ValOk: {string.Join(",", OptCheckCondInt[cKey].ValOk)}"); } else { @@ -1121,6 +1241,18 @@ namespace IOB_WIN_NEXT return answ; } + /// + /// Test di lettura dei blocchi di memoria ESTESO (considerato memorie xFFFF e tutti e 4 i + /// tipi di dati modbus) + /// + protected void testReadExt() + { + foreach (var item in memSetR) + { + testBlockReadExt(item.Key, item.Value); + } + } + #endregion Protected Methods #region Private Fields @@ -1139,6 +1271,12 @@ namespace IOB_WIN_NEXT /// private int deltaBase { get; set; } = 0; + /// + /// Indica se usare gli indirizzi estesi per ogni blocco: false = 0...10'000 true = + /// 0...65'536 (= xFFFF) + /// + private bool modbusExtReg { get; set; } = false; + #endregion Private Properties #region Private Methods diff --git a/IOB-WIN-NEXT/IobModbusTCPSaim.cs b/IOB-WIN-NEXT/IobModbusTCPSaim.cs index 973749aa..b98cfdea 100644 --- a/IOB-WIN-NEXT/IobModbusTCPSaim.cs +++ b/IOB-WIN-NEXT/IobModbusTCPSaim.cs @@ -33,12 +33,17 @@ namespace IOB_WIN_NEXT try { processDynData(); + if (EnableTest) + { + testReadExt(); + } } catch (Exception exc) { lgError($"Eccezione in processDynData iniziale x ModBus TCP SAIM:{Environment.NewLine}{exc}"); } } + } #endregion Public Constructors @@ -168,40 +173,6 @@ namespace IOB_WIN_NEXT #region Private Methods - private void testBlockRead(int baseAddr, int numByte) - { - int baseHold = 40001; - int[] readTestFull = new int[2]; - lgTrace($"-------------------- Inizio test lettura {baseAddr} --------------------"); - try - { - stopwatch.Restart(); - readTestFull = currPLC.ReadHoldingRegisters(baseAddr - baseHold, numByte); - stopwatch.Stop(); - lgTrace($"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); - lgTrace($"{baseAddr + i * 2:000} | HoldingRegisters: {thisSet[0]} / {thisSet[1]} | Val Real: {ModbusClient.ConvertRegistersToFloat(thisSet):N6}"); - } - lgTrace("-------------------- Completato test lettura {baseAddr} --------------------"); - } - - - - private void testRead() - { - foreach (var item in memSetR) - { - testBlockRead(item.Key, item.Value); - } - } - #endregion Private Methods } } \ No newline at end of file