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/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index 020e0aad..ffeb02eb 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -391,6 +391,9 @@ Always + + Always + Always diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs index 19dc0886..5d23e960 100644 --- a/IOB-WIN-NEXT/IobModbusTCP.cs +++ b/IOB-WIN-NEXT/IobModbusTCP.cs @@ -36,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... /// @@ -208,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 @@ -218,7 +229,10 @@ namespace IOB_WIN_NEXT foreach (var item in memItemList) { // attesa 50 ms prima di procedere x evitare burst dati - Thread.Sleep(50); + if (useLUT) + { + Thread.Sleep(50); + } double valore = 0; double valoreScal = 0; bool dataOk = false; @@ -244,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; @@ -301,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 @@ -795,29 +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("Attesa prima di rilettura"); + lgInfo($"Attesa prima di rilettura | LUT: {useLUT}"); // attendo 3 sec Thread.Sleep(3000); - lgInfo($"Effettuo rilettura per {readErrorList.Count} variabili"); - readErrorListRepeat = getDataDictionary(readErrorList, ref outVal); + 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(); @@ -830,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(); diff --git a/IOB-WIN-NEXT/IobModbusTCPHam.cs b/IOB-WIN-NEXT/IobModbusTCPHam.cs index ae55af71..12accd6a 100644 --- a/IOB-WIN-NEXT/IobModbusTCPHam.cs +++ b/IOB-WIN-NEXT/IobModbusTCPHam.cs @@ -41,8 +41,6 @@ namespace IOB_WIN_NEXT try { processDynData(); - - testRead(); } catch (Exception exc) { @@ -138,13 +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 - - //testBlockRead(40001, 32); - testBlockRead(40001, 64); - //testBlockRead(40001, 120); - - testBlockRead(40421, 72); - //testBlockRead(40401, 100); + foreach (var item in memSetR) + { + testBlockRead(item.Key, item.Value); + } } #endregion Private Methods