From f7e8ef8b2f06d68347c0c0e7398a7e2efb89bd20 Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli" Date: Tue, 12 Nov 2019 22:44:53 +0100 Subject: [PATCH] Completate READ/WRITE x OMRON EDF --- IOB-WIN/IobOmron.cs | 349 +++++++++++++++++++++----------------------- 1 file changed, 167 insertions(+), 182 deletions(-) diff --git a/IOB-WIN/IobOmron.cs b/IOB-WIN/IobOmron.cs index 43dab2a6..9a9660dc 100644 --- a/IOB-WIN/IobOmron.cs +++ b/IOB-WIN/IobOmron.cs @@ -52,52 +52,72 @@ namespace IOB_WIN /// protected short[] memWriteWR; - // + /// /// Calcola la conversione da byte --> num decimale --> HEX --> conversione come stringa in INT /// /// /// - protected int convDHD(short valore) + protected static int convDHD(short valore) { + // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) + // esempio 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] int answ = 0; string hexVal = valore.ToString("x"); int.TryParse(hexVal, out answ); return answ; } - // + /// /// Calcola la conversione da INTERO a intero HEX x OMRON /// /// /// - protected int convHD(string hexVal) + protected static int convHD(string hexVal) { int answ = 0; - try + if (!string.IsNullOrEmpty(hexVal)) { - if (!hexVal.StartsWith("0x")) + try { - hexVal = "0x" + hexVal; + if (!hexVal.StartsWith("0x")) + { + hexVal = "0x" + hexVal; + } + answ = Convert.ToInt32(hexVal, 16); } - answ = Convert.ToInt32(hexVal, 16); + catch + { } } - catch - { } return answ; } /// + /// Converte un valore INT in un array di due SHORT valido x scrivere su OMRON + /// + /// + /// + protected static short[] intToShort(int value) + { + short[] valDM = new short[2]; + short highVal = (short)(value / 10000); + short lowVal = (short)(value - highVal * 10000); + valDM[0] = (short)convHD("0x" + lowVal.ToString("0000")); + valDM[1] = (short)convHD("0x" + highVal.ToString("0000")); + return valDM; + } + /// /// Converte un valore di 2 short in un unico numero accostato: /// es: legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) /// 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] /// /// /// - protected int convFromHex(short[] valori) + protected static int convFromHex(short[] valori) { int answ = 0; string fullVal = $"{convDHD(valori[1]).ToString("D4")}{convDHD(valori[0]).ToString("D4")}"; int.TryParse(fullVal, out answ); return answ; } +#if false /// /// Converte un valore intero in 2 short che il PLC riporterà ad HEX x visualizzare: /// es: legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) @@ -113,7 +133,8 @@ namespace IOB_WIN answ[0] = (short)convHD(fullVal.Substring(4, 4)); answ[1] = (short)convHD(fullVal.Substring(0, 4)); return answ; - } + } +#endif /// /// estende l'init della classe base... @@ -126,105 +147,7 @@ namespace IOB_WIN pzCountDelay = utils.CRI("pzCountDelay"); lastPzCountSend = DateTime.Now; lastWarnODL = DateTime.Now; - - - // test conversione valori... - short[] valDM = new short[2]; - // cario dati - valDM[0] = 9472; - valDM[1] = 1; - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) - // esempio 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] - var testDec = convFromHex(valDM); - - var testHex = convToHex(testDec); - -#if false - OMRON_ref = new OmronFinsTCP.Net.EtherNetPLC(); - OMRON_ref.Link("192.168.250.1", 9600, 500); - short[] response; - short[] response2; - short bit1; - short bit2; - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 20, 2, out response); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 22, 2, out response2); - - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) - - // esempio 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] - - - // spostamento memorie: canale 65, 65.0 (era 50.15) x reset fineciclo; 65.1, era 53.10 scrittura pesatura - OMRON_ref.ReadWord(OmronFinsTCP.Net.PlcMemory.CIO, 0, out bit1); - OMRON_ref.ReadWord(OmronFinsTCP.Net.PlcMemory.CIO, 4, out bit2); - - short[] valoriWord = new short[10]; - for (int i = 0; i < 10; i++) - { - valoriWord[i] = (short)i; - } - - OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, valoriWord); -#endif - -#if false - // init connessione - setConnection(); -#endif } - - /// - /// Test completo funzioni OMRON - /// - private void omronWriteTest() - { - // faccio un try-catch di test vari... - short[] response; - short[] response2; - short bit1; - short bit2; - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 20, 2, out response); - OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 22, 2, out response2); - - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) - - // esempio 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] - - - // spostamento memorie: canale 65, 65.0 (era 50.15) x reset fineciclo; 65.1, era 53.10 scrittura pesatura - OMRON_ref.ReadWord(OmronFinsTCP.Net.PlcMemory.CIO, 0, out bit1); - OMRON_ref.ReadWord(OmronFinsTCP.Net.PlcMemory.CIO, 4, out bit2); - - - // scrivo commessa come lettere abcdefghil - byte[] valByte = Encoding.ASCII.GetBytes("OMRON EDF TEST"); - short[] valoriWord = new short[10]; - Buffer.BlockCopy(valByte, 0, valoriWord, 0, valByte.Length); - OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, valoriWord); - - // scrivo portata - int intVal = 444; - short portata = (short)convHD("0x" + intVal.ToString("0000")); - - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, 50, portata); - - // scrivo pesatura richiesta - pesoRichiesto = 22222; - - // scrivo DM 52-53 del lotto richiesto - quantitaLotto = 66666; - - // sollevo bit 65.0 x azzeramento - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 1); - Thread.Sleep(500); - // ora sollevo bit e 65.1 x indicare nuovo valore... - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 2); - // ora attendo ed abbasso tutto - Thread.Sleep(500); - OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 0); - } - - /// /// Processo i task richiesti e li elimino dalla coda 1:1 /// @@ -360,46 +283,6 @@ namespace IOB_WIN #endif return answ; } - -#if false - /// - /// Imposto connessione - /// - protected virtual void setConnection() - { - // Creo oggetto connessione NC - parentForm.commPlcActive = true; - lgInfo("Start init Adapter OMRON all'IP {0} | --> IOB {1}", cIobConf.cncIpAddr, cIobConf.codIOB); - - // inizializzo correttamente aree memoria secondo CONF - iniFileName - IniFile fIni = new IniFile(cIobConf.iniFileName); - - // SE è necessario refresh... - if (needRefresh) - { - lgInfo("Refreshing connection..."); - // ora tento avvio PLC... SE PING OK... - if (testPing == IPStatus.Success) - { - try - { - short esitoLink = doConnect(); - lgInfo($"End init Adapter OMRON, esitoLink: {esitoLink}"); - if (utils.CRB("verbose")) - { - lgInfo("OMRON CONNESSIONE AVVENUTA"); - } - } - catch (Exception exc) - { - lgError(exc, "Errore in INIT OMRON Commu"); - } - needRefresh = false; - } - parentForm.commPlcActive = false; - } - } -#endif /// /// Vera connessione ad OMRON /// @@ -414,7 +297,6 @@ namespace IOB_WIN short esitoLink = OMRON_ref.Link(cIobConf.cncIpAddr, port, 500); return esitoLink; } - /// /// Override disconnessione /// @@ -518,6 +400,11 @@ namespace IOB_WIN } } + #region Metodi specifici (da verificare/completare in implementazione) + + /// + /// controllo allarmi + /// public override void forceAlarmCheck() { // controllo tutta la memoria allarmi SE richiesto @@ -543,9 +430,8 @@ namespace IOB_WIN return answ; } } - /// - /// Oggetto per lettura (DM22-23) /scrittura (DM26-27) PESO RICHIESTO + /// Oggetto get/set per lettura (DM22-23) /scrittura (DM26-27) PESO RICHIESTO /// protected int pesoRichiesto { @@ -556,8 +442,6 @@ namespace IOB_WIN { short[] valDM; OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 22, 2, out valDM); - // legge delle coppie di valori INT, vanno trasformati in HEX e POI accodati, dove il primo è x 1 e il secondo x 10000 (in pratica va in testa) - // esempio 12540 --> diviso in 1 | 2540 --> in HEX diventa 1 | 9472, ma il 9472 va su byte[0] e 1 su byte[1] answ = convDHD(valDM[0]) + 10000 * convDHD(valDM[1]); } catch @@ -566,40 +450,106 @@ namespace IOB_WIN } set { - // DA PROVARE!!! - short[] valDM = new short[2]; - short highVal = (short)(value / 10000); - short lowVal = (short)(value - highVal * 10000); - - - //string hexVal = "0x"+highVal.ToString("0000"); - //short.TryParse(hexVal, out valDM[1]); - - //hexVal = "0x" + lowVal.ToString("0000"); - //short.TryParse(hexVal, out valDM[0]); - - valDM[0] = (short)convHD("0x" + lowVal.ToString("0000")); - valDM[1] = (short)convHD("0x" + highVal.ToString("0000")); + short[] valDM = intToShort(value); OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.DM, 26, 2, valDM); + // ora devo "comandare scrittura" su OMRON... + + // sollevo bit 65.0 x azzeramento + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 1); + Thread.Sleep(500); + // ora sollevo bit e 65.1 x indicare nuovo valore... + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 2); + // ora attendo ed abbasso tutti i bit + Thread.Sleep(500); + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 0); } } - + /// + /// Oggetto get/set x quantità richiesta LOTTO + /// protected int quantitaLotto { + get + { + int answ = 0; + try + { + short[] valDM; + OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.DM, 52, 2, out valDM); + answ = convDHD(valDM[0]) + 10000 * convDHD(valDM[1]); + } + catch + { } + return answ; + } set { - short[] valDM = new short[2]; - short highVal = (short)(value / 10000); - short lowVal = (short)(value - highVal * 10000); - valDM[0] = (short)convHD("0x" + lowVal.ToString("0000")); - valDM[1] = (short)convHD("0x" + highVal.ToString("0000")); + short[] valDM = intToShort(value); OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.DM, 52, 2, valDM); } } - #region Metodi specifici (da verificare/completare in implementazione) - - + /// + /// Oggetto get/set x portata + /// + protected int portata + { + get + { + int answ = 0; + try + { + short valDM; + OMRON_ref.ReadWord(OmronFinsTCP.Net.PlcMemory.DM, 50, out valDM); + answ = convDHD(valDM); + } + catch + { } + return answ; + } + set + { + // scrivo portata su memoria DM50... + short portata = (short)convHD("0x" + value.ToString("0000")); + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, 50, portata); + } + } + /// + /// Lettura scrittura commessa da OMRON (come array di coppie di byte) + /// + protected string commessa + { + get + { + string answ = ""; + short[] response; + byte[] byteData = new byte[20]; + try + { + // leggo + OMRON_ref.ReadWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, out response); + // copio come byte... + Buffer.BlockCopy(response, 0, byteData, 0, response.Length); + answ = Encoding.ASCII.GetString(byteData); + } + catch + { } + return answ; + } + set + { + // converto in byte la mia stringa + byte[] valByte = Encoding.ASCII.GetBytes(value); + // limite 20 char... imposto a 20! + int maxChar = valByte.Length < 20 ? valByte.Length : 20; + // creao un array di 10 short MAX + short[] valoriWord = new short[10]; + // copio i valori + Buffer.BlockCopy(valByte, 0, valoriWord, 0, maxChar); + // scrivo su OMRON! + OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, valoriWord); + } + } /// /// Effettua vero processing contapezzi /// @@ -683,7 +633,6 @@ namespace IOB_WIN } } - /// /// Effettua lettura semafori principale /// Parametri da aggiornare x display in form @@ -718,7 +667,6 @@ namespace IOB_WIN currDispData.semIn = Semaforo.SR; } } - /// /// Verifico se abbia ALMENO un errore... /// @@ -745,7 +693,6 @@ namespace IOB_WIN return answ; } } - /// /// Effettua decodifica aree memoria alla bitmap usata x MAPO /// @@ -881,7 +828,6 @@ namespace IOB_WIN lgInfo(string.Format("Trasformazione B_input: {0}", B_input)); } } - /// /// Recupero dati dinamici... /// @@ -898,6 +844,45 @@ namespace IOB_WIN return outVal; } + + + + + + /// + /// Test completo funzioni OMRON + /// + private void omronWriteTest() + { + + // scrivo commessa come lettere abcdefghil + byte[] valByte = Encoding.ASCII.GetBytes("OMRON EDF TEST"); + short[] valoriWord = new short[10]; + Buffer.BlockCopy(valByte, 0, valoriWord, 0, valByte.Length); + OMRON_ref.WriteWords(OmronFinsTCP.Net.PlcMemory.WR, 0, 10, valoriWord); + + // scrivo portata + int intVal = 444; + short portata = (short)convHD("0x" + intVal.ToString("0000")); + + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.DM, 50, portata); + + // scrivo pesatura richiesta + pesoRichiesto = 22222; + + // scrivo DM 52-53 del lotto richiesto + quantitaLotto = 66666; + + // sollevo bit 65.0 x azzeramento + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 1); + Thread.Sleep(500); + // ora sollevo bit e 65.1 x indicare nuovo valore... + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 2); + // ora attendo ed abbasso tutto + Thread.Sleep(500); + OMRON_ref.WriteWord(OmronFinsTCP.Net.PlcMemory.CIO, 65, 0); + } + #endregion } }