hellf Inserito: 21 novembre 2010 Segnala Share Inserito: 21 novembre 2010 Salve a tutti,premetto che sono neofita quindi probabilmente sto sbagliando io qualcosa, ma non riesco a cavarne piede perciò mi affido alla vostra competenza.Stavo provando un semplice codice SCL con delle Function CallAnzitutto ho creato due FC (una chiamata GUADAGNO che moltiplica una variabile in ingresso per una costante, e l'altra CONV_REAL che, data una variabile di tipo TIME la converte in un'altra di tipo REAL)Ho poi creato l'OB1 che le richiami e in fase di simulazione (con s7-PLCSIM) ottenevo i risultati corretti.Il problema è giunto non appena ho creato un semplice IF nell'OB1 del tipo:IF out1 <= 250 THEN IF Ts <= 25 THEN err := 0; ELSE err := 2; END_IF; ELSE IF Ts <= 25 THEN err := 1; ELSE err := 3; END_IF; END_IF;Dove Ts è la variabile REAL ottenuta tramite conversione della VAR_TIME tempoMentre out1 è semplicemente un INT ottenuto tramite la funzione guadagno descritta poche righe fa..In simulazione non ottengo il valore corretto di Ts e non capisco perché!Spero di essere stato chiaro, se qualcuno mi può dire dove sto sbagliando mi farebbe un grossissimo favore! Link al commento Condividi su altri siti More sharing options...
mubeta Inserita: 21 novembre 2010 Segnala Share Inserita: 21 novembre 2010 Posta l'intero codice, perchè così non è affatto chiaro.In simulazione non ottengo il valore corretto di TsNel codice postato, Ts non viene mai scritto, ma, sempre e solo letto. Dove è il problema?Se Ts è un REAL, il confronto dovrebbe essere , come minimo:IF Ts <= 25.0 THEN //Sicuro di non avere avuto errori di compilazione e semplicemente, hai provato il blocco senza le modifiche caricate? Link al commento Condividi su altri siti More sharing options...
hellf Inserita: 21 novembre 2010 Autore Segnala Share Inserita: 21 novembre 2010 Posta l'intero codice, perchè così non è affatto chiaro.ok allora questo è l'OB1:ORGANIZATION_BLOCK CICLO VAR_TEMP dati_sistema : ARRAY[0..20] OF INT; END_VAR BEGIN out1 := GUADAGNO(in1); // out1 = 5*in1 Ts := conv_real(Ta); // TIME_TO_REAL IF out1 <= 250 THEN IF Ts <= 25.0 THEN err := 0; ELSE err := 2; END_IF; ELSE IF Ts <= 25.0 THEN err := 1; ELSE err := 3; END_IF; END_IF; END_ORGANIZATION_BLOCKCon PLCSIM vedo questo:Come vedi il valore di Ts è sbagliato...ma se elimino l'IF mi restituisce il valore corretto!e non capisco il perchéSicuro di non avere avuto errori di compilazione e semplicemente, hai provato il blocco senza le modifiche caricate?Nono non mi da alcun errore ne alcun avviso!Poi te l'ho detto, se elimino l'IF è tutto ok..non mi ci raccapezzo...Che poi la cosa strana è che ho anche provato a fare una cosa, cioè ho creato un'altra variabile out2 di tipo REALe se faccio: out2 := Ts;mi restituisce il valore corretto Link al commento Condividi su altri siti More sharing options...
mubeta Inserita: 22 novembre 2010 Segnala Share Inserita: 22 novembre 2010 Scusa, ma se quello è l'intero OB1:- dove sono le dichiarazioni di out1, Ts, in1 ed err ??? Sono forse delle variabili dell'area M?- cosa è GUADAGNO()?? Una funzione tua ?- non ho mai visto conv_real(). E' di SCL od una funzione tua ?Per la conversione da REAL ad INT o DINT, io conosco: REAL_TO_INT() e REAL_TO_DINT().Questo è un estrtto di codice mio, che funziona benone: IF P > 32767.0 THEN P := 32767.0; ELSIF P < -32767.0 THEN P := -32767.0; END_IF;Dubito che il problema sia lo statement IF. Prima di tutto, dichiara le variabili allinterno del blocco, così che sia più facile capire cosa stai facendo.Poi, non fare funzioni in OB1, falle dentro degli FC od FB, ed usa OB1 solo per il loro richiamo. (Non è qui il problema, è solo per chiarezza). Link al commento Condividi su altri siti More sharing options...
hellf Inserita: 22 novembre 2010 Autore Segnala Share Inserita: 22 novembre 2010 Scusa, ma se quello è l'intero OB1:- dove sono le dichiarazioni di out1, Ts, in1 ed err ??? Sono forse delle variabili dell'area M?- cosa è GUADAGNO()?? Una funzione tua ?- non ho mai visto conv_real(). E' di SCL od una funzione tua ?Beh, ora, e correggimi se sbaglio, ma nell'OB1 non si possono dichiarare le variabili In e Out, ma solo var_temp, per questo motivo ho dichiarato il tipo nella lista dei simboli!la funzione GUADAGNO() E CONV_REAL() sono due semplici FC che ho creato io per provare a programmare in SCL e fare function call, nulla di impegnativo...Poi, non fare funzioni in OB1, falle dentro degli FC od FB, ed usa OB1 solo per il loro richiamo. (Non è qui il problema, è solo per chiarezza).Ok provo a fare l'IF in una FC e faccio il richiamo da OB1 e poi ti faccio sapereComunque la cosa strana è che comunque se assegno Ts (che è il valore REAL del tempo) ad un'altra variabile ritorna tutto giusto! Link al commento Condividi su altri siti More sharing options...
mubeta Inserita: 22 novembre 2010 Segnala Share Inserita: 22 novembre 2010 Beh, ora, e correggimi se sbaglio, ma nell'OB1 non si possono dichiarare le variabili In e Out, ma solo var_temp, per questo motivo ho dichiarato il tipo nella lista dei simboli!Non ti correggo; OB1, come altri OB, è un blocco organizzativo, con una funzione ben determinata. Non ammette la dichiarazione di variabili di ingresso od uscita, perché non è possibile effettuarne la chiamata volontaria. Le funzioni utente si fanno con FC ed FB.In merito al tuo problema: le funzioni Guadagno() e conv_real() sono già testate? Se posti il codice solo in modo parziale, è evidente che viene subito da pensare che il problema sia altrove. Link al commento Condividi su altri siti More sharing options...
hellf Inserita: 22 novembre 2010 Autore Segnala Share Inserita: 22 novembre 2010 (modificato) Non ti correggo; OB1, come altri OB, è un blocco organizzativo, con una funzione ben determinata. Non ammette la dichiarazione di variabili di ingresso od uscita, perché non è possibile effettuarne la chiamata volontaria. Le funzioni utente si fanno con FC ed FB.Ah ok..pensavo di non aver capito proprio niente In merito al tuo problema: le funzioni Guadagno() e conv_real() sono già testate? Se posti il codice solo in modo parziale, è evidente che viene subito da pensare che il problema sia altrove.Le funzioni le ho testate singolarmente e producono il risultato corretto, comunque, ecco i codici delle FC:GUADAGNO():FUNCTION GUADAGNO : INT VAR_INPUT valore : INT; END_VAR BEGIN IF valore <= 180 THEN guadagno := 5 * valore; //Calcolo del valore della funzione ELSE guadagno := 900; // in caso di overflow END_IF; END_FUNCTION CONV_REAL(): FUNCTION CONV_REAL : REAL VAR_INPUT tempo : TIME; END_VAR BEGIN conv_real := 0.001*DINT_TO_REAL(TIME_TO_DINT(tempo)); //0.001 per fare in modo che 1s == 1.0 END_FUNCTION Mentre la lista dei simboli è questa: CICLO OB 1 OB 1 CONV_REAL FC 43 FC 43 err QW 755 INT GUADAGNO FC 42 FC 42 in1 IW 752 INT out1 QW 752 INT out2 QD 758 REAL Ta ID 1 TIME Ts QD 754 REALComunque, come ti ho detto, le FC funzionano correttamente, ma quando inserisco l'IF mi si incasina il risultato finaleps: Grazie per l'aiuto! Modificato: 22 novembre 2010 da hellf Link al commento Condividi su altri siti More sharing options...
mubeta Inserita: 22 novembre 2010 Segnala Share Inserita: 22 novembre 2010 Facciamo un passo alla volta:Gli indirizzi di alcune aree I e Q sono un poco alti. Non so come si comporta il simulatore; nella realtà avresti già molti problemi, il più delle CPU allocano 256 o 512 di IPI ed IPO.1) Comincia col riportare gli indirizzi delle tue variabili a valori più ragionevoli, magari partendo da 100, in sù. IW100, ID102, etc.2) Lo statement IF vedo che lo hai già usato altrove, quindi, come ti dicevo, non è questo il problema. Inutile che insisti nel guardare lì. Link al commento Condividi su altri siti More sharing options...
hellf Inserita: 23 novembre 2010 Autore Segnala Share Inserita: 23 novembre 2010 Facciamo un passo alla volta:Gli indirizzi di alcune aree I e Q sono un poco alti. Non so come si comporta il simulatore; nella realtà avresti già molti problemi, il più delle CPU allocano 256 o 512 di IPI ed IPO.1) Comincia col riportare gli indirizzi delle tue variabili a valori più ragionevoli, magari partendo da 100, in sù. IW100, ID102, etc.2) Lo statement IF vedo che lo hai già usato altrove, quindi, come ti dicevo, non è questo il problema. Inutile che insisti nel guardare lì.Ah io ho utilizzato quegli indirizzi perché nella configurazione hardware mi mette di default questo:E siccome volevo provare il codice fisicamente per provare a vedere come sono le uscite e gli ingressi analogici ho pensato di usare quegli indirizzi...ps: ti rimetto anche la tabella simboli (solo IN e OUT)..secondo te sto sbagliando qualcosa qui?Ta ID 1 TIME in1 IW 752 INT Ts QD 754 REAL out2 QD 758 REAL out1 QW 752 INT err QW 755 INTps: spostando gli indirizzi a partire da 100 non funziona O_o Link al commento Condividi su altri siti More sharing options...
hellf Inserita: 23 novembre 2010 Autore Segnala Share Inserita: 23 novembre 2010 ok ho risolto finalmente il problema era, come mi dicevi tu, su come indirizzavo i diversi simboli!!!ho risolto dichiarando Ts come Merker (anche perché effettivamente non mi interessava visualizzarlo come un uscita!) penso il problema sia che si accavallavano dei bit di err (che era indirizzo QW 755) con i bit di Ts (QD 754)..visto che la D prende due indirizzi..almeno così mi sembra di aver capito!!Secondo te può essere questo il motivo per cui entrava in conflitto???ps: l'ho notato perché facendo alcune prove, in base al valore di err mi si modificava di un valore pari a 10e-3 il valore di Ts Link al commento Condividi su altri siti More sharing options...
mubeta Inserita: 23 novembre 2010 Segnala Share Inserita: 23 novembre 2010 Siemens, per tradizione, indirizza tutto a byte. Se allochi una word od una dword, ecc, devi fare molta attenzione a non sovrapporre gli indirizzi: esempio, una dword indirizzata a MD100, prende: MB103, MB102, MB101 e MB100. Link al commento Condividi su altri siti More sharing options...
hellf Inserita: 23 novembre 2010 Autore Segnala Share Inserita: 23 novembre 2010 Siemens, per tradizione, indirizza tutto a byte. Se allochi una word od una dword, ecc, devi fare molta attenzione a non sovrapporre gli indirizzi: esempio, una dword indirizzata a MD100, prende: MB103, MB102, MB101 e MB100.ghgh me ne sono accorto a mie spese!! in ogni caso davvero grazie mille per le risposte e lo stress che ti ho provocato sti giorni..mi sei stato davvero d'aiuto!!!! Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
Crea un account o accedi per commentare
Devi essere un utente per poter lasciare un commento
Crea un account
Registrati per un nuovo account nella nostra comunità. è facile!
Registra un nuovo accountAccedi
Hai già un account? Accedi qui.
Accedi ora