diff --git a/IOB-WIN-NEXT/DATA/CONF/PIZ05.json b/IOB-WIN-NEXT/DATA/CONF/PIZ05.json index e77f9da2..ff8260ec 100644 --- a/IOB-WIN-NEXT/DATA/CONF/PIZ05.json +++ b/IOB-WIN-NEXT/DATA/CONF/PIZ05.json @@ -1,4 +1,50 @@ { + "mMapWrite": { + "SetLowTempGNC": { + "name": "SetLowTempGNC", + "description": "Set point di avviso per bassa temperatura all'uscita del vaporizzatore GNC", + "memAddr": "40489", + "tipoMem": "Real", + "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, + "unit": "C" + }, + "SetLowTempAmb": { + "name": "SetLowTempAmb", + "description": "Set point di avviso per bassa temperatura ambiente nell'impianto", + "memAddr": "40421", + "tipoMem": "Real", + "index": 421, + "size": 2, + "minVal": -200, + "maxVal": 200, + "unit": "C" + }, + "SetHighTempAmb": { + "name": "SetHighTempAmb", + "description": "Set point di avviso per alta temperatura ambiente nell'impianto", + "memAddr": "40423", + "tipoMem": "Real", + "index": 423, + "size": 2, + "minVal": -200, + "maxVal": 200, + "unit": "C" + } + }, "mMapRead": { "Level": { "name": "Level", @@ -55,6 +101,90 @@ "minVal": 0, "maxVal": 400, "unit": "bar" + }, + "TempGNC": { + "name": "TempGNC", + "description": "Temperatura all'uscita del vaporizzatore GNC", + "memAddr": "40027", + "tipoMem": "Real", + "index": 27, + "size": 2, + "func": "MAX", + "period": 60, + "factor": 1, + "minVal": -200, + "maxVal": 200, + "unit": "C" + }, + "TempAmb": { + "name": "TempAmb", + "description": "Temperatura ambiente nell'impianto", + "memAddr": "40011", + "tipoMem": "Real", + "index": 11, + "size": 2, + "func": "MAX", + "period": 60, + "factor": 1, + "minVal": -200, + "maxVal": 200, + "unit": "C" + }, + "SetLowTempGNC": { + "name": "SetLowTempGNC", + "description": "Set point di avviso per bassa temperatura all'uscita del vaporizzatore GNC", + "memAddr": "40489", + "tipoMem": "Real", + "index": 489, + "size": 2, + "func": "MAX", + "period": 60, + "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": 60, + "factor": 1, + "minVal": -200, + "maxVal": 200, + "unit": "C" + }, + "SetLowTempAmb": { + "name": "SetLowTempAmb", + "description": "Set point di avviso per bassa temperatura ambiente nell'impianto", + "memAddr": "40421", + "tipoMem": "Real", + "index": 421, + "size": 2, + "func": "MAX", + "period": 60, + "factor": 1, + "minVal": -200, + "maxVal": 200, + "unit": "C" + }, + "SetHighTempAmb": { + "name": "SetHighTempAmb", + "description": "Set point di avviso per alta temperatura ambiente nell'impianto", + "memAddr": "40423", + "tipoMem": "Real", + "index": 423, + "size": 2, + "func": "MAX", + "period": 60, + "factor": 1, + "minVal": -200, + "maxVal": 200, + "unit": "C" } } } \ No newline at end of file diff --git a/IOB-WIN-NEXT/IobModbusTCP.cs b/IOB-WIN-NEXT/IobModbusTCP.cs index 72b50d73..22c4281d 100644 --- a/IOB-WIN-NEXT/IobModbusTCP.cs +++ b/IOB-WIN-NEXT/IobModbusTCP.cs @@ -133,7 +133,7 @@ namespace IOB_WIN_NEXT /// /// /// - private static double convertVal(int[] listInt, int size, plcDataType tipoMem) + private static double convertFromReg(int[] listInt, int size, plcDataType tipoMem) { double valore = 0; //verifico se sia INT o real x convertire... @@ -165,6 +165,58 @@ namespace IOB_WIN_NEXT return valore; } + /// + /// Converte valore reale nel tipo desiderato in forma di int[] adatti a scrivere nei registri + /// + /// + /// + /// + /// + private static int[] convertToReg(object origVal, int size, plcDataType tipoMem) + { + int[] answ = new int[2]; + //verifico se sia INT o real x convertire... + switch (tipoMem) + { + case plcDataType.Real: + if (size == 4) + { + answ = ModbusClient.ConvertDoubleToRegisters((double)origVal); + } + else if (size == 2) + { + answ = ModbusClient.ConvertFloatToRegisters((float)origVal); + } + break; + + case plcDataType.Int: + default: + if (size == 4) + { + answ = ModbusClient.ConvertLongToRegisters((long)origVal); + } + else if (size == 2) + { + answ = ModbusClient.ConvertIntToRegisters((int)origVal); + } + break; + } + return answ; + } + + private static double getScaledDouble(dataConf currMem) + { + double valDouble; + // prima faccio eventuale fattore di scala... + double.TryParse(currMem.value, out valDouble); + if (currMem.factor > 1) + { + valDouble = valDouble * (double)currMem.factor; + } + + return valDouble; + } + private static int getScaledInt(dataConf currMem) { int valInt; @@ -219,13 +271,13 @@ namespace IOB_WIN_NEXT case modBusAddrType.InputRegister: listInt = readInputReg(item.Value.index, item.Value.size); - valore = convertVal(listInt, item.Value.size, item.Value.tipoMem); + valore = convertFromReg(listInt, item.Value.size, item.Value.tipoMem); break; case modBusAddrType.HoldingRegister: listInt = readHoldReg(item.Value.index - 1, item.Value.size); - valore = convertVal(listInt, item.Value.size, item.Value.tipoMem); + valore = convertFromReg(listInt, item.Value.size, item.Value.tipoMem); break; default: @@ -307,10 +359,9 @@ namespace IOB_WIN_NEXT /// protected override void plcWriteParams(ref List updatedPar) { -#if false dataConf currMem = null; int byteSize = 0; - byte[] MemBlock = new byte[1]; + int[] CurrVal = new int[1]; string memAddrWrite = ""; bool fatto = false; string serObj = ""; @@ -324,6 +375,7 @@ namespace IOB_WIN_NEXT memAddrWrite = ""; int valInt = 0; uint valUInt = 0; + double valDouble = 0; // cerco in area memMapWrite... if (memMap.mMapWrite.ContainsKey(item.uid)) { @@ -331,7 +383,7 @@ namespace IOB_WIN_NEXT currMem = memMap.mMapWrite[item.uid]; byteSize = currMem.size; memAddrWrite = currMem.memAddr; - MemBlock = new byte[byteSize]; + CurrVal = new int[byteSize]; // faccio preliminarmente upsertKey... upsertKey(currMem.name, currMem.value); serObj = JsonConvert.SerializeObject(item, Formatting.Indented); @@ -345,45 +397,47 @@ namespace IOB_WIN_NEXT case plcDataType.Int: valInt = getScaledInt(currMem); - saveIntOnMemBlock(ref MemBlock, 0, valInt.ToString()); + CurrVal = convertToReg(valInt, 2, plcDataType.Int); + fatto = writeInputReg(currMem.index, CurrVal); break; case plcDataType.DInt: - valInt = getScaledInt(currMem); - saveDIntOnMemBlock(ref MemBlock, 0, valInt.ToString()); + valUInt = getScaledUInt(currMem); + CurrVal = convertToReg(valInt, 4, plcDataType.Int); + fatto = writeInputReg(currMem.index, CurrVal); break; - case plcDataType.Word: - valUInt = getScaledUInt(currMem); - saveWordOnMemBlock(ref MemBlock, 0, valInt.ToString()); - break; + //case plcDataType.Word: + // valUInt = getScaledUInt(currMem); + // saveWordOnMemBlock(ref MemBlock, 0, valInt.ToString()); + // break; - case plcDataType.DWord: - valUInt = getScaledUInt(currMem); - saveDWordOnMemBlock(ref MemBlock, 0, valInt.ToString()); - break; + //case plcDataType.DWord: + // valUInt = getScaledUInt(currMem); + // saveDWordOnMemBlock(ref MemBlock, 0, valInt.ToString()); + // break; case plcDataType.Real: - saveRealOnMemBlock(ref MemBlock, 0, currMem.value); + valDouble = getScaledDouble(currMem); + CurrVal = convertToReg(valInt, 2, plcDataType.Real); + fatto = writeInputReg(currMem.index, CurrVal); break; - case plcDataType.String: - // se ho writePre --> "allungo" di 2 la dimensione della stringa x MemBlock... - if (writePre) - { - MemBlock = new byte[byteSize + 2]; - } - saveStringOnMemBlock(ref MemBlock, 0, currMem.size, currMem.value); - break; + //case plcDataType.String: + // // se ho writePre --> "allungo" di 2 la dimensione della stringa x MemBlock... + // if (writePre) + // { + // MemBlock = new byte[byteSize + 2]; + // } + // saveStringOnMemBlock(ref MemBlock, 0, currMem.size, currMem.value); + // break; default: break; } - lgInfo($"---------------MemBlock data---------------{Environment.NewLine}{BitConverter.ToString(MemBlock)}{Environment.NewLine}--------------- END data ---------------"); + lgInfo($"---------------MemBlock data---------------{Environment.NewLine}CurrVal: {CurrVal}{Environment.NewLine}--------------- END data ---------------"); if (!string.IsNullOrEmpty(memAddrWrite)) { - // scrivo su ModBusTCP - fatto = S7WriteBB(ref MemBlock, memAddrWrite); // se fatto --> aggiorno! if (fatto) { @@ -391,6 +445,7 @@ namespace IOB_WIN_NEXT item.reqValue = ""; item.lastRead = DateTime.Now; } +#if false // se configurato faccio verifica write... if (getOptPar("WRITE_CHECK") == "TRUE") { @@ -406,6 +461,7 @@ namespace IOB_WIN_NEXT lgInfo($"Scrittura corretta: {BitConverter.ToString(MemBlockRead)}"); } } +#endif } else { @@ -423,7 +479,6 @@ namespace IOB_WIN_NEXT } } } -#endif } /// @@ -849,324 +904,6 @@ namespace IOB_WIN_NEXT } } - /// - /// wrapper chiamata LETTURA in blocco MULTI BYTE dell'area read DI DEFAULT... - /// - /// - /// - public bool S7ReadBB(ref byte[] Value) - { - return S7ReadBB(ref Value, parametri.memAddrRead, parametri.memSizeRead); - } - - /// - /// wrapper chiamata LETTURA in blocco MULTI BYTE... - /// - /// MATRICE valori letti - /// Area memoria da leggere... - /// Numero byte da leggere - /// - public bool S7ReadBB(ref byte[] Value, string memAddrRead, int numByte) - { - bool answ = false; - if (Value != null) - { - sw.Restart(); - parentForm.commPlcActive = true; -#if false - if (testCncConn()) - { - // decodifico memoria... - memAreaSiemens memoria = new memAreaSiemens(memAddrRead); - 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($"Mismatch dimensione array memoria: indirizzo: {memAddrRead} | passato array di {Value.Length} byte, letti da S7 {memByteRead.Length} byte"); - } - string titolo = $"READ BLOCK MEM BYTE: {parametri.memAddrRead} --> {numByte} byte"; - if (verboseLog) - { - lgInfo(titolo); - } - - string contenuto = $"Contenuto area memoria acquisita{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; - } -#endif - parentForm.commPlcActive = false; - sw.Stop(); - if (utils.CRB("recTime")) - { - TimingData.addResult(cIobConf.codIOB, string.Format("{0}|{1}", parametri.memAddrRead, numByte), sw.ElapsedTicks); - } - } - return answ; - } - - /// - /// wrapper chiamata LETTURA in blocco MULTI BYTE... default size a parametri.memSizeRead - /// - /// - /// Area memoria da leggere... - /// - public bool S7ReadBB(ref byte[] Value, string memAddrRead) - { - bool answ = false; - answ = S7ReadBB(ref Value, memAddrRead, parametri.memSizeRead); - return answ; - } - - /// - /// wrapper chiamata SCRITTURA in blocco MULTI BYTE, DI DEFAULT su area configurata x scrittura CONTINUA... - /// - /// - /// - public bool S7WriteBB(ref byte[] Value) - { - return S7WriteBB(ref Value, parametri.memAddrWrite); - } - - /// - /// Override scrittura in area DBB - /// - /// - /// - /// - public bool S7WriteBB(ref byte[] Value, string memAddrWrite) - { - bool answ = false; - if (Value == null) - { - lgError($"Errore in S7WriteBB: Value è null"); - } - else - { - if (string.IsNullOrEmpty(memAddrWrite)) - { - lgError($"Errore in S7WriteBB: memAddrWrite è vuoto"); - } - else - { - sw.Restart(); -#if false - if (testCncConn()) - { - try - { - // decodifico memoria... - memAreaSiemens memoria = new memAreaSiemens(memAddrWrite); - int numByte = Value.Length; - ErrorCode errorCode = currPLC.WriteBytes(DataType.DataBlock, memoria.DbNum, memoria.indiceMem, Value); - switch (errorCode) - { - case ErrorCode.NoError: - answ = true; - maybeLogWrite(memAddrWrite, $"S7WriteBB-01 Effettuata correttamente scrittura su PLC: MEMORIA {memAddrWrite} | numByte: {Value.Length} | ValOriginale: {Value}"); - break; - - case ErrorCode.WrongCPU_Type: - case ErrorCode.ConnectionError: - case ErrorCode.IPAddressNotAvailable: - case ErrorCode.WrongVarFormat: - case ErrorCode.WrongNumberReceivedBytes: - case ErrorCode.SendData: - case ErrorCode.ReadData: - case ErrorCode.WriteData: - lgError($"Errore in S7WriteBB su {memAddrWrite}: {errorCode.ToString()} | numByte: {Value.Length}| {Value.ValToBinString()}"); - answ = false; - break; - - default: - break; - } - } - catch (Exception exc) - { - lgError($"Eccezione in S7WriteBB | memAddrWrite {memAddrWrite} | numByte: {Value.Length}{Environment.NewLine}{exc}"); - } - } -#endif - sw.Stop(); - } - } - return answ; - } - - /// - /// Override scrittura in area DBB - /// - /// Valore byte[] da scrivere - /// Numero del DB (es 700 per DB700) - /// Indice interno al datablock del byte da cui partire - /// - public bool S7WriteBB(ref byte[] Value, int DbNum, int IndiceMem) - { - bool answ = false; - if (Value == null) - { - lgError($"Errore in S7WriteBB: Value è null"); - } - else - { - if (DbNum < 0 || IndiceMem < 0) - { - lgError($"Errore in S7WriteBB | DbNum: {DbNum} | IndiceMem: {IndiceMem}"); - } - else - { - sw.Restart(); -#if false - if (testCncConn()) - { - try - { - int numByte = Value.Length; - ErrorCode errorCode = currPLC.WriteBytes(DataType.DataBlock, DbNum, IndiceMem, Value); - switch (errorCode) - { - case ErrorCode.NoError: - lgInfo($"S7WriteBB-02 Effettuata correttamente scrittura su PLC: DB {DbNum}.{IndiceMem} | numByte: {Value.Length}| {Value.ValToBinString()}"); - break; - - case ErrorCode.WrongCPU_Type: - case ErrorCode.ConnectionError: - case ErrorCode.IPAddressNotAvailable: - case ErrorCode.WrongVarFormat: - case ErrorCode.WrongNumberReceivedBytes: - case ErrorCode.SendData: - case ErrorCode.ReadData: - case ErrorCode.WriteData: - lgError($"Errore in S7WriteBB su DB {DbNum}.{IndiceMem}: {errorCode.ToString()} | numByte: {Value.Length}| {Value.ValToBinString()}"); - break; - - default: - break; - } - answ = true; - } - catch (Exception exc) - { - lgError($"Eccezione in S7WriteBB: DbNum {DbNum}, IndiceMem: {IndiceMem}, numByte: {Value.Length}{Environment.NewLine}{exc}"); - } - } -#endif - sw.Stop(); - } - } - return answ; - } - - /// - /// Salvo in memblock il valore Int indicato con formattazione ModBus TCP - /// - /// Blocco memoria come byte[] dove scrivere - /// Posizione inizio scrittura - /// valore da scrivere - public void saveIntOnMemBlock(ref byte[] MemBlock, int startPos, string valore) - { - try - { - short valInt = 0; - short.TryParse(valore, out valInt); - byte[] strByte = S7.Net.Types.Int.ToByteArray(valInt); - int byteLen = 2; - Buffer.BlockCopy(strByte, 0, MemBlock, startPos, byteLen); - //var verifica = S7.Net.Types.String.FromByteArray(MemBlock); - } - catch (Exception exc) - { - lgError($"Errore in gestione scrittura INT {valore} alla posizione {startPos} byte{Environment.NewLine}{exc}"); - } - } - - /// - /// Salvo in memblock il valore Int indicato con formattazione ModBus TCP - /// - /// Blocco memoria come byte[] dove scrivere - /// Nome del parametro da recuperare da prodData x scrivere - /// Posizione inizio scrittura - public void saveIntOnMemBlock(ref byte[] MemBlock, string stringKey, int startPos) - { - if (currProdData.ContainsKey(stringKey)) - { - try - { - string valore = currProdData[stringKey]; - saveIntOnMemBlock(ref MemBlock, startPos, valore); - } - catch (Exception exc) - { - lgError($"Errore in gestione scrittura INT {stringKey}{Environment.NewLine}{exc}"); - } - } - } - - /// - /// Salvo in memblock il valore stringa indicato con formattazione ModBus TCP - /// - /// Blocco memoria come byte[] dove scrivere - /// Posizione inizio scrittura - /// Valore scrivere - public void saveRealOnMemBlock(ref byte[] MemBlock, int startPos, string valore) - { - try - { - byte[] stringPar = new byte[2]; - - double valReal = 0; - double.TryParse(valore, out valReal); - byte[] strByte = S7.Net.Types.Double.ToByteArray(valReal); - int byteLen = 4; - Buffer.BlockCopy(strByte, 0, MemBlock, startPos, byteLen); - //var verifica = S7.Net.Types.String.FromByteArray(MemBlock); - } - catch (Exception exc) - { - lgError($"Errore in gestione scrittura REAL {valore} alla posizione {startPos} byte{Environment.NewLine}{exc}"); - } - } - - /// - /// Salvo in memblock il valore stringa indicato con formattazione ModBus TCP - /// - /// Blocco memoria come byte[] dove scrivere - /// Valore scrivere - /// Posizione inizio scrittura - public void saveRealOnMemBlock(ref byte[] MemBlock, string stringKey, int startPos) - { - if (currProdData.ContainsKey(stringKey)) - { - try - { - string valore = currProdData[stringKey]; - saveRealOnMemBlock(ref MemBlock, startPos, valore); - } - catch (Exception exc) - { - lgError($"Errore in gestione scrittura REAL {stringKey}{Environment.NewLine}{exc}"); - } - } - } - /// /// Effettua salvataggio in LUT del valore ricevuto (double) /// @@ -1291,6 +1028,50 @@ namespace IOB_WIN_NEXT } } + /// + /// Scrittura di un singolo valore COIL (1...) + /// + /// + /// + /// + public bool writeCoil(int startAddr, bool currValue) + { + bool answ = false; + if (currPLC.Connected) + { + try + { + currPLC.WriteSingleCoil(startAddr, currValue); + answ = true; + } + catch + { } + } + return answ; + } + + /// + /// Scrittura di un valore Input Register (4...) + /// + /// + /// Valore in formato INT da registri + /// + public bool writeInputReg(int startAddr, int[] currRegVal) + { + bool answ = false; + if (currPLC.Connected) + { + try + { + currPLC.WriteMultipleRegisters(startAddr, currRegVal); + answ = true; + } + catch + { } + } + return answ; + } + #endregion Public Methods } } \ No newline at end of file