batta Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 Quote anche se parliamo di due grandezze completamente diverse Appunto, parliamo di due grandezze completamente diverse. Non puoi pretendere che un flusso ed una temperatura si comportino nello stesso modo. A questo punto, se vuoi rendere la lettura ancora più stabile, filtra il valore da visualizzare sul display. Io sono sempre dell'idea che sia un'operazione inutile, perché il valore mi sembra già sufficientemente stabile, e perché non andrai a migliorare realmente la stabilità del flusso, ma solo il valore visualizzato. Poi, anche se qualcuno dice che è sbagliato filtrare il segnale in ingresso al PID, io non sono di quest'idea, soprattutto se il processo è relativamente lento e si dà priorità alla stabilità piuttosto che alla rapidità di risposta. Una cosa è un PID per il posizionamento di un asse (e qui di filtri neanche a parlarne), altra regolare una portata. Ovviamente, bisogna valutare i parametri del PID e l'entità del filtro.
Livio Orsini Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 35 minuti fa, batta scrisse: Poi, anche se qualcuno dice che è sbagliato filtrare il segnale in ingresso al PID, io non sono di quest'idea, soprattutto se il processo è relativamente lento e si dà priorità alla stabilità piuttosto che alla rapidità di risposta Se il regolatore è ben ottimizzato e il sistema ben progettato, non hai bisogno di filtrare l'ingresso per stabilizzare il processo. Filtrando l'ingresso non lo stabilizzi, mascheri la variazione che è una cosa differente. Differente è il ragionamento se non si tratta di variazioni reali ma di rumore del trasduttore. Un esempio classico è l'integratore posto all'ingresso di tachimetrica dei convertitori analogici. Si deve metterlo per abbattere il ripple della tachimetrica. Però bisogna considerare le differenti frequenze: quella del rumore è molto maggiore della massima frequenza della banda di risposta dell'azionamento. I sistemi reazionati hanno tutti delle oscillazioni, è un fatto fisiologico. In alcuni sistemi sono avvertibili "ad occhio" in altri sono solo misurabili con strumentazione adeguata. Quello che a mio parere è sbagliato è "truccare" la misura per fare apparire un sistema più stabile. Un tempo, ad esempio, si usava costruire dei "ballerini" molto inerti così che sembravano inchiodati al centro della corsa. Però misurando la tensione del materiale si registravano variazioni anche notevoli. Un ballerino che oscilla un poco attorno al suo centro sembra meno stabile, ma la tensione sul materiale è praticamente costante. Costruire un ballerino ad elevata inerzia è assimilabile ad un volano, è come mettere un integratore, che è un filtro passa basso, sull'ingresso di reazione.
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 il 7/7/2018 at 19:42 , incus scrisse: Anche io ignoro il motivo per cui tu, @Project75, debba filtrare l'ingresso analogico. Comunque sia, se non hai dimistichezza con l'scl puoi farlo anche in kop...in pratica: col fronte di salita di un clock1hz muovi nel seguente ordine Valore9 nel valore10 Valore8 nel valore9 Valore7 nel valore8 Cosi fino a Valore1 nel valore2 NuovoValore nel valore1 Cosi, campionando ogni secondo,hai dieci variabili con le ultime dieci letture Poi non devi fare altro che sommare tutti e 10 i valori e dividerli per dieci Questo è il concetto di base, numero di campionamenti e frequenza di campionamento sta a te deciderli Se vuoi il sorgente scl posso inviartelo lunedi Ciao incus se ti è possibile mi puoi mandare il sorgente. Grazie mille il 7/7/2018 at 19:42 , incus scrisse: Anche io ignoro il motivo per cui tu, @Project75, debba filtrare l'ingresso analogico. Comunque sia, se non hai dimistichezza con l'scl puoi farlo anche in kop...in pratica: col fronte di salita di un clock1hz muovi nel seguente ordine Valore9 nel valore10 Valore8 nel valore9 Valore7 nel valore8 Cosi fino a Valore1 nel valore2 NuovoValore nel valore1 Cosi, campionando ogni secondo,hai dieci variabili con le ultime dieci letture Poi non devi fare altro che sommare tutti e 10 i valori e dividerli per dieci Questo è il concetto di base, numero di campionamenti e frequenza di campionamento sta a te deciderli Se vuoi il sorgente scl posso inviartelo lunedi Ciao incus se ti è possibile mi puoi mandare il sorgente. Grazie mille
batta Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 Quote Se il regolatore è ben ottimizzato e il sistema ben progettato, non hai bisogno di filtrare l'ingresso per stabilizzare il processo. Filtrando l'ingresso non lo stabilizzi, mascheri la variazione che è una cosa differente. Differente è il ragionamento se non si tratta di variazioni reali ma di rumore del trasduttore. Appunto, qui siamo nel secondo caso, con segnale che varia anche con riferimento fisso della pompa. Non si tratta quindi di filtrare instabilità creata dal PID stesso, ma di dare in pasto al PID un segnale più pulito, che non risenta di pulsazioni causate da turbolenze o da rumore in genere. Con frequenze diverse, ma è esattamente come filtrare il segnale della tachimetrica per eliminare il ripple. Project75, perché ti sei fissato con il FIFO? Perché non provi prima a vedere il risultato che ottieni con la semplice formuletta Out = Out + (In - Out) / k Ti assicuro che funziona. E, se vuoi proprio fare una media aritmetica di N valori, piuttosto che un FIFO che ad ogni ciclo sposta tutte le variabili, potresti procedere come segue: - crea un array di N variabili (per esempio 10 variabili, da miaVar[0] a miaVar[9]). - utilizza un indice "id" (per seguire l'esempio, anche l'indice deve assumere valori da 0 a 9) - ad ogni campionamento, scrivi il dato nella variabile puntata dall'indice (miaVar[id]) ed incrementi l'indice. - se l'indice supera il valore massimo, azzeri l'indice. - Per fare la media, sommi tutti i valori dell'array e dividi per il numero di elementi dell'array (in SCL lo fai con un banale ciclo FOR). In questo modo ad ogni campionamento vai a scrivere una sola variabile nell'array. Se si parla di array di piccole dimensioni, la differenza tra scrivere una sola variabile o fare lo scroll di tutto l'array è di natura puramente filosofica. Se hai un array con qualche migliaio di elementi, la differenza si sente.
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 1 ora fa, batta scrisse: Out = Out + (In - Out) / k Quindi out è l'uscita del pid, in è l'ingresso del pid, cioè il valore misurato dal flussimeyro, k invece cos'è?
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 Mentre per quanto riguarda la media aritmetica, ho creato un array real da 1 a 5, e l'ho chiamata dati, ho inserto un contatore avanti, dopo di che ho messo il contatto del contatore al primo 'move' all'ingresso di questultimo ho messo il valore del flussimetro ed all'uscita del move ho messo 'dati [1]', poi ho messo il contatto del contatore al secondo 'move' all'ingresso di questultimo ho messo il valore del flussimetro ed all'uscita del move ho messo 'dati [2]', poi ancora ho messo il contatto del contatore al terzo 'move' all'ingresso di questultimo ho messo il valore del flussimetro ed all'uscita del move ho messo 'dati [3]', ho fatto così fino a 'dati [5], a questo punto ho sommato i valori dellarray, 'dati [1]' fino a 'dati [5], e ho diviso per 5, potrebbe andare bene così?
incus Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 1 ora fa, Project75 scrisse: Quindi out è l'uscita del pid, in è l'ingresso del pid, cioè il valore misurato dal flussimeyro, k invece cos'è? no, out sarebbe il valore del flussimetro dopo aver eseguito il calcolo, per capire meglio la formula interpretala così: ValoreFiltrato = ValoreFiltrato + (ValoreIngresso - ValoreFiltrato) / Kostante -Il ValoreFiltrato è quello che metterai come ingresso al PID -La Kostante è un valore fisso che imposti tu, in principio mettilo a 1, poi varialo e scopri i suoi effetti 😝 Ricorda che la formula di cui sopra devi farla esclusivamente con variabili di tipo REAL
Livio Orsini Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 3 ore fa, batta scrisse: Appunto, qui siamo nel secondo caso, con segnale che varia anche con riferimento fisso della pompa. E chi ti assicura che la pompa ruoti a velocità costante? E' azionata da un un inverter e non è stato specificato che sia reazionato in velocità, anzi i credo che sia in normale V/f. Non credo nemmeno che una variazione di 800 l/h, nell'intorno di 13000 l/h di portata, sia da addebitarsi al trasduttore vista la qualità dello stesso (a meno che sia difettoso). Poi come ho scritto prima, il problema non è mio ed ognuno è libero di comportarsi come preferisce. Però questo, a mio giudizio, è un caso in cui il filtraggio della reazione è un trucco.
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 Ciao incus la media aritmetica che ho postato prima potrebbe andare bene? Mi potresti mandare gentilmente l'eseguibile che mi avevi detto?
batta Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 Quote Quindi out è l'uscita del pid, in è l'ingresso del pid, cioè il valore misurato dal flussimeyro, k invece cos'è? Ti ha risposto "incus". Come utilizzare la formula era spiegato in un precedente post che, probabilmente, non hai letto. Comunque: - devi assolutamente utilizzare variabili di tipo REAL - il calcolo va eseguito ad intervalli di tempo regolari (mettilo in un OB a tempo). Per il tuo caso, penso potrebbero andar bene da 10 a 100 ms. - K la potremmo impropriamente chiamare "costante di smorzamento". Se ha valore 1, è come non ci fosse il filtro. Aumentando il valore di K aumenti lo smorzamento, ma aumenti anche il ritardo a variazioni del segnale. Devi trovare un giusto compromesso. Quote Mentre per quanto riguarda la media aritmetica, ho creato un array real da 1 a 5, e l'ho chiamata dati, ho inserto un contatore avanti, dopo di che ho messo il contatto del contatore al primo 'move' all'ingresso di questultimo ho messo il valore del flussimetro ed all'uscita del move ho messo 'dati [1]', poi ho messo il contatto del contatore al secondo 'move' all'ingresso di questultimo ho messo il valore del flussimetro ed all'uscita del move ho messo 'dati [2]', poi ancora ho messo il contatto del contatore al terzo 'move' all'ingresso di questultimo ho messo il valore del flussimetro ed all'uscita del move ho messo 'dati [3]', ho fatto così fino a 'dati [5], a questo punto ho sommato i valori dellarray, 'dati [1]' fino a 'dati [5], e ho diviso per 5, potrebbe andare bene così? Ma ti piace così tanto complicare le cose semplici? Vediamo, questo è il sorgente di una funzione in SCL, buttata giù in modo piuttosto barbaro, tanto per fare un esempio. La funzione va richiamata ad intervalli regolari. FUNCTION_BLOCK "Media" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT inValue : Real; dim : Int; // Min 1, Max 100 END_VAR VAR_OUTPUT average : Real; END_VAR VAR id : Int; data : Array[1..100] of Real; END_VAR VAR_TEMP tmpDim : Int; i : Int; tot : Real; END_VAR BEGIN #tmpDim := #dim; IF #tmpDim < 1 THEN #tmpDim := 1; ELSIF #tmpDim > 100 THEN #tmpDim := 100; END_IF; IF #id < 1 OR #id > #tmpDim THEN #id := 1; END_IF; #data[#id] := #inValue; #id := #id + 1; #tot := 0.0; FOR #i := 1 TO #tmpDim DO #tot := #tot + #data[#i]; END_FOR; #average := #tot / INT_TO_REAL(#tmpDim); END_FUNCTION_BLOCK
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 7 minuti fa, batta scrisse: Ti ha risposto "incus". Come utilizzare la formula era spiegato in un precedente post che, probabilmente, non hai letto. Comunque: - devi assolutamente utilizzare variabili di tipo REAL - il calcolo va eseguito ad intervalli di tempo regolari (mettilo in un OB a tempo). Per il tuo caso, penso potrebbero andar bene da 10 a 100 ms. - K la potremmo impropriamente chiamare "costante di smorzamento". Se ha valore 1, è come non ci fosse il filtro. Aumentando il valore di K aumenti lo smorzamento, ma aumenti anche il ritardo a variazioni del segnale. Devi trovare un giusto compromesso. Ma ti piace così tanto complicare le cose semplici? Vediamo, questo è il sorgente di una funzione in SCL, buttata giù in modo piuttosto barbaro, tanto per fare un esempio. La funzione va richiamata ad intervalli regolari. FUNCTION_BLOCK "Media" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT inValue : Real; dim : Int; // Min 1, Max 100 END_VAR VAR_OUTPUT average : Real; END_VAR VAR id : Int; data : Array[1..100] of Real; END_VAR VAR_TEMP tmpDim : Int; i : Int; tot : Real; END_VAR BEGIN #tmpDim := #dim; IF #tmpDim < 1 THEN #tmpDim := 1; ELSIF #tmpDim > 100 THEN #tmpDim := 100; END_IF; IF #id < 1 OR #id > #tmpDim THEN #id := 1; END_IF; #data[#id] := #inValue; #id := #id + 1; #tot := 0.0; FOR #i := 1 TO #tmpDim DO #tot := #tot + #data[#i]; END_FOR; #average := #tot / INT_TO_REAL(#tmpDim); END_FUNCTION_BLOCK Non ho mai utilizzato SCL, devo mettere questo codice dentro un blocco?
batta Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 Quote Non credo nemmeno che una variazione di 800 l/h, nell'intorno di 13000 l/h di portata, sia da addebitarsi al trasduttore vista la qualità dello stesso 800 l/h di variazione su 13000 non possono nemmeno essere imputati alla pompa, nemmeno se l'inverter è impostato V/f.
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 Out=out+(in-out)/k, allora 'in' è il valore letto dal flussimetro, k è la costante e la decido io, e out cos'è? È il vaLore filtrato?ma il valore filtrato non è quello che mi dovrei ricavare dalla formula? Quindi potrebbe essere Valore filtrato ( che voglio ottenere)= out+(in-out)/k , a questo punto out sarebbe il valore in uscita del pid?
incus Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 1 ora fa, Project75 scrisse: Ciao incus la media aritmetica che ho postato prima potrebbe andare bene? Mi potresti mandare gentilmente l'eseguibile che mi avevi detto? non sono riuscito a caricare il file, comunque: copia tutto il testo incollalo dentro un file di testo dopo di che modifica l'estensione da .txt a .scl poi nel tia portal nel menu ad albero del plc apri la cartella sorgenti esterne clicca su aggiungi nuovo file esterno selezionando il file scl che ti ho passato dopo averlo caricato nel tia portal, fai tasto destro sulla sorgente e clicca genera sorgente dai blocchi FUNCTION_BLOCK "FB137_FILTRO_VALORE_BY_MEDIA_ARITMETICA" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT START : Bool; // 1=start CLR : Bool; // 1=pulisci buffer di lettura CLK { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; VALUE { ExternalWritable := 'False'} : Real; // valore da filtrare DIM_BUFFER { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 5; // dimensione buffer di lettura [1..99] END_VAR VAR_OUTPUT Q_VALUE { ExternalWritable := 'False'} : Real; Q_ERR { ExternalWritable := 'False'} : Word; // %X0=outrange dimensioni buffer END_VAR VAR CLK_OLD { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // vecchio valore di clock CLK_TP { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // trig positivo clock DIM_BUFFER_OLD { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // vecchio valore buffer di lettura CNG_DIM_BUFFER { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // trig positivo cambio dimensioni buffer di lettura BUFFER { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..99] of Real; // buffer valori letti J { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // indice END_VAR BEGIN //************ TRIG POSITIVO CLOCK ************ IF #CLK AND NOT #CLK_OLD THEN #CLK_TP := TRUE; ELSE #CLK_TP := FALSE; END_IF; #CLK_OLD := #CLK; //************ TRIG CAMBIO DIMENSIONI BUFFER DI LETTURA ************ IF #DIM_BUFFER <> #DIM_BUFFER_OLD THEN #CNG_DIM_BUFFER := TRUE; ELSE #CNG_DIM_BUFFER := FALSE; END_IF; #DIM_BUFFER_OLD := #DIM_BUFFER; //************ PULIZIA BUFFER DI LETTURA ************ IF #CLR OR #CNG_DIM_BUFFER OR #Q_ERR.%X0 THEN FOR #J := 0 TO 99 BY 1 DO #BUFFER[#J] := 0.0; END_FOR; END_IF; //************ TRASFERIMENTO VALORE LETTO NEL BUFFER DI LETTURA ************ IF #START AND #CLK_TP THEN FOR #J := #DIM_BUFFER TO 0 BY -1 DO IF #J > 0 THEN #BUFFER[#J] := #BUFFER[#J - 1]; ELSIF #J = 0 THEN #BUFFER[#J] := #VALUE; END_IF; END_FOR; END_IF; //************ CALCOLO LA MEDIA ARITMETICA ************ #Q_VALUE := 0.0; FOR #J := 0 TO #DIM_BUFFER DO #Q_VALUE := #Q_VALUE + #BUFFER[#J]; END_FOR; #Q_VALUE := #Q_VALUE / (#DIM_BUFFER + 1.0); //************ ERRORI ************ //controllo inrange dimensioni buffer IF (#DIM_BUFFER < 1) OR (#DIM_BUFFER > 99) THEN #Q_ERR.%X0 := TRUE; ELSE #Q_ERR.%X0 := FALSE; END_IF; END_FUNCTION_BLOCK
incus Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 1 ora fa, Project75 scrisse: Out=out+(in-out)/k, allora 'in' è il valore letto dal flussimetro, k è la costante e la decido io, e out cos'è? È il vaLore filtrato?ma il valore filtrato non è quello che mi dovrei ricavare dalla formula? Quindi potrebbe essere Valore filtrato ( che voglio ottenere)= out+(in-out)/k , a questo punto out sarebbe il valore in uscita del pid? Ma le leggi le risposte che ti stiamo dando?????? ti riquoto le risposte 2 ore fa, incus scrisse: no, out sarebbe il valore del flussimetro dopo aver eseguito il calcolo, per capire meglio la formula interpretala così: ValoreFiltrato = ValoreFiltrato + (ValoreIngresso - ValoreFiltrato) / Kostante -Il ValoreFiltrato è quello che metterai come ingresso al PID -La Kostante è un valore fisso che imposti tu, in principio mettilo a 1, poi varialo e scopri i suoi effetti 😝 Ricorda che la formula di cui sopra devi farla esclusivamente con variabili di tipo REAL 1 ora fa, batta scrisse: Ti ha risposto "incus". Come utilizzare la formula era spiegato in un precedente post che, probabilmente, non hai letto. Comunque: - devi assolutamente utilizzare variabili di tipo REAL - il calcolo va eseguito ad intervalli di tempo regolari (mettilo in un OB a tempo). Per il tuo caso, penso potrebbero andar bene da 10 a 100 ms. - K la potremmo impropriamente chiamare "costante di smorzamento". Se ha valore 1, è come non ci fosse il filtro. Aumentando il valore di K aumenti lo smorzamento, ma aumenti anche il ritardo a variazioni del segnale. Devi trovare un giusto compromesso.
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 Scusa ma io non ho capito come funziona questa formula, se out è il valore filtrato cioè il valore che devo ricavare, come si esegue questa formula con un valore che ancora devo calcolare?
incus Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 39 minuti fa, Project75 scrisse: Scusa ma io non ho capito come funziona questa formula, se out è il valore filtrato cioè il valore che devo ricavare, come si esegue questa formula con un valore che ancora devo calcolare? Ad ogni ciclo di scansio e il valore filtrato si aggiorna, provala, cosi ti rendi conto
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 Sarà sicuramente funzionante ma io non mi rendo conto come. Forse un esempio numerico mi sarebbe più chiaro
batta Inserita: 9 luglio 2018 Segnala Inserita: 9 luglio 2018 E se scrivo: a = a + 1 ti pare una cosa impossibile? Il valore attuale di "a" viene incrementato di una unità ed il risultato viene scritto nuovamente in "a". Se in KOP richiami l'istruzione ADD, su IN1 metti "a", su IN2 metti "1" e su OUT metti ancora "a", ti sembra normale, giusto? È la stessa cosa. "ValoreFiltrato", che devi ricavare, all'inizio, avrà pure un valore, o no? Se non hai assegnato nessun valore, avrà valore zero, che è pur sempre un valore! Poi, ad ogni calcolo, si modifica. In quella banalissima formula prendi il valore filtrato (che è il risultato dei precedenti calcoli). A questo valore filtrato sommi una parte della differenza che c'è tra il valore attuale e il valore filtrato. Alla fine dell'operazione il valore filtrato sarà diverso da come era prima di eseguire l'operazione. Se ancora non sei convinto, prova a fare una semplice prova con dei numeri. Partiamo con "valoreFiltrato" = 0, "ValoreGrezzo" = 100, e k = 2. quindi: "valoreFiltrato" = 0 + (100 - 0) / 2 = 50. Al ciclo successivo avrai: "valoreFiltrato" = 50 + (100 - 50) / 2 = 75 e ancora: "valoreFiltrato" = 75 + (100 - 75) / 2 = 87.5
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 11 minuti fa, batta scrisse: E se scrivo: a = a + 1 ti pare una cosa impossibile? Il valore attuale di "a" viene incrementato di una unità ed il risultato viene scritto nuovamente in "a". Se in KOP richiami l'istruzione ADD, su IN1 metti "a", su IN2 metti "1" e su OUT metti ancora "a", ti sembra normale, giusto? È la stessa cosa. "ValoreFiltrato", che devi ricavare, all'inizio, avrà pure un valore, o no? Se non hai assegnato nessun valore, avrà valore zero, che è pur sempre un valore! Poi, ad ogni calcolo, si modifica. In quella banalissima formula prendi il valore filtrato (che è il risultato dei precedenti calcoli). A questo valore filtrato sommi una parte della differenza che c'è tra il valore attuale e il valore filtrato. Alla fine dell'operazione il valore filtrato sarà diverso da come era prima di eseguire l'operazione. Se ancora non sei convinto, prova a fare una semplice prova con dei numeri. Partiamo con "valoreFiltrato" = 0, "ValoreGrezzo" = 100, e k = 2. quindi: "valoreFiltrato" = 0 + (100 - 0) / 2 = 50. Al ciclo successivo avrai: "valoreFiltrato" = 50 + (100 - 50) / 2 = 75 e ancora: "valoreFiltrato" = 75 + (100 - 75) / 2 = 87.5 Si avevo provato a far un calcolo con numeri e ne volevo essere sicuro. A questo punto si potrebbe pensare che la media aritmetica sia più efficace....
Project75 Inserita: 9 luglio 2018 Autore Segnala Inserita: 9 luglio 2018 3 ore fa, incus scrisse: non sono riuscito a caricare il file, comunque: copia tutto il testo incollalo dentro un file di testo dopo di che modifica l'estensione da .txt a .scl poi nel tia portal nel menu ad albero del plc apri la cartella sorgenti esterne clicca su aggiungi nuovo file esterno selezionando il file scl che ti ho passato dopo averlo caricato nel tia portal, fai tasto destro sulla sorgente e clicca genera sorgente dai blocchi FUNCTION_BLOCK "FB137_FILTRO_VALORE_BY_MEDIA_ARITMETICA" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT START : Bool; // 1=start CLR : Bool; // 1=pulisci buffer di lettura CLK { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; VALUE { ExternalWritable := 'False'} : Real; // valore da filtrare DIM_BUFFER { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 5; // dimensione buffer di lettura [1..99] END_VAR VAR_OUTPUT Q_VALUE { ExternalWritable := 'False'} : Real; Q_ERR { ExternalWritable := 'False'} : Word; // %X0=outrange dimensioni buffer END_VAR VAR CLK_OLD { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // vecchio valore di clock CLK_TP { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // trig positivo clock DIM_BUFFER_OLD { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // vecchio valore buffer di lettura CNG_DIM_BUFFER { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // trig positivo cambio dimensioni buffer di lettura BUFFER { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..99] of Real; // buffer valori letti J { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // indice END_VAR BEGIN //************ TRIG POSITIVO CLOCK ************ IF #CLK AND NOT #CLK_OLD THEN #CLK_TP := TRUE; ELSE #CLK_TP := FALSE; END_IF; #CLK_OLD := #CLK; //************ TRIG CAMBIO DIMENSIONI BUFFER DI LETTURA ************ IF #DIM_BUFFER <> #DIM_BUFFER_OLD THEN #CNG_DIM_BUFFER := TRUE; ELSE #CNG_DIM_BUFFER := FALSE; END_IF; #DIM_BUFFER_OLD := #DIM_BUFFER; //************ PULIZIA BUFFER DI LETTURA ************ IF #CLR OR #CNG_DIM_BUFFER OR #Q_ERR.%X0 THEN FOR #J := 0 TO 99 BY 1 DO #BUFFER[#J] := 0.0; END_FOR; END_IF; //************ TRASFERIMENTO VALORE LETTO NEL BUFFER DI LETTURA ************ IF #START AND #CLK_TP THEN FOR #J := #DIM_BUFFER TO 0 BY -1 DO IF #J > 0 THEN #BUFFER[#J] := #BUFFER[#J - 1]; ELSIF #J = 0 THEN #BUFFER[#J] := #VALUE; END_IF; END_FOR; END_IF; //************ CALCOLO LA MEDIA ARITMETICA ************ #Q_VALUE := 0.0; FOR #J := 0 TO #DIM_BUFFER DO #Q_VALUE := #Q_VALUE + #BUFFER[#J]; END_FOR; #Q_VALUE := #Q_VALUE / (#DIM_BUFFER + 1.0); //************ ERRORI ************ //controllo inrange dimensioni buffer IF (#DIM_BUFFER < 1) OR (#DIM_BUFFER > 99) THEN #Q_ERR.%X0 := TRUE; ELSE #Q_ERR.%X0 := FALSE; END_IF; END_FUNCTION_BLOCK Grazie mille per il file sorgente incus, ho creato il blocco ora devo capire bene come funziona, allora l'ingresso start avvia il blocco quindi la campionatura, l'ingresso clr credo che cancelli i dati salvati, quando bisogna cancellarli?, l'ingresso clk cos'è?, value è il valore da stabilizzare, dimm_buffer sarebbero il numero di campioni, che va da 1 a 99, Q_value credo sia il valore filtrato, e Q_err cos'è?
Livio Orsini Inserita: 10 luglio 2018 Segnala Inserita: 10 luglio 2018 11 ore fa, batta scrisse: 800 l/h di variazione su 13000 non possono nemmeno essere imputati alla pompa, nemmeno se l'inverter è impostato V/f. E' una variazione del 6.15% non credo sia rumore di fondo, ma proprio variazione di portata.
Project75 Inserita: 10 luglio 2018 Autore Segnala Inserita: 10 luglio 2018 7 ore fa, Project75 scrisse: Grazie mille per il file sorgente incus, ho creato il blocco ora devo capire bene come funziona, allora l'ingresso start avvia il blocco quindi la campionatura, l'ingresso clr credo che cancelli i dati salvati, quando bisogna cancellarli?, l'ingresso clk cos'è?, value è il valore da stabilizzare, dimm_buffer sarebbero il numero di campioni, che va da 1 a 99, Q_value credo sia il valore filtrato, e Q_err cos'è? Incus ho capito chè l'ingresso clk è il fronte in salita, cioè la frequenza di campionatura, Q_err potrebbe essere l'indicazione di errore (come deduco i valori di errore?), mentre l'ingresso clr posso avviarlo quando ho bisogno di cancellare i dati salvati.
incus Inserita: 10 luglio 2018 Segnala Inserita: 10 luglio 2018 1 ora fa, Project75 scrisse: Incus ho capito chè l'ingresso clk è il fronte in salita, cioè la frequenza di campionatura, Q_err potrebbe essere l'indicazione di errore (come deduco i valori di errore?), mentre l'ingresso clr posso avviarlo quando ho bisogno di cancellare i dati salvati. nei commenti delle variabili c'è la descrizione da cui puoi capire a cosa servono, comunque di seguito inserisco dei commenti aggiuntivi per facilitarti: START : 1=start, avvia il bloccoCLR : 1=pulisci buffer di lettura, serve per azzerare il buffer di letturaCLK : frequenza di campionamento, nel TIA puoi abilitare le Merker di clock nelle proprietà della CPU e collegarci una di esseVALUE : valore da filtrare , valore di cui devi fare la media aritmeticaDIM_BUFFER : dimensione buffer di lettura [1..99], indica quanti valori vuoi caricare nel buffer di lettura, puoi impostare un valore da 1 a 99, se devi fare 10 campionamenti devi impostare DIM_BUFFER=9 poiche il conteggio parte da 0 Q_VALUE : valore filtratoQ_ERR : %X0=outrange dimensioni buffer, se il primo bit della word è TRUE allora significa che le dimensioni del buffer sono errate
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