pegu Inserito: 25 giugno 2021 Segnala Share Inserito: 25 giugno 2021 Buongiorno, devo calcolare la media di un segnale analogico su un periodo di 5 secondi. Dopo aver visitato il forum e aver trovato diversi esempi ( come questo) ho capito che la strategia è riempire un array (con i quali purtroppo non ho dimestichezza in TIA Portal) e quando l'array è pieno fare la somma edividere per la dimensione dell'array. Ho provato a mettere in pratica quanto descritto (in KOP e nell'ultima versione in SCL) ma purtroppo continuo ad imbattermi nelle stesse problematiche legate al funzionamento del PLC: in particolare non riesco a riempire l'array ed aumentare il contatore che è responsabile di puntare gli elementi dell'array. Sono abituato ad altri linguaggi di programmazione (C, C++) e faccio fatica a capire come riempire l'array in questo ambiente. Vi lascio le schermate dell'ultima versione (noterete che è fermo al contatore=1) Link al commento Condividi su altri siti More sharing options...
Mattia Spoldi Inserita: 25 giugno 2021 Segnala Share Inserita: 25 giugno 2021 il problema nasce dal fatto che stai usando una FC, le variabili che dichiari nella sezione temp, vengono reinizializzate ad ogni scansione, perdendo il loro valore. Riscrivi il blocco usando un FB e sposta le variabili che adesso sono in area temp nell'area stat. Link al commento Condividi su altri siti More sharing options...
pegu Inserita: 25 giugno 2021 Autore Segnala Share Inserita: 25 giugno 2021 Grazie mille per l'input, ho riscitto il programma in un blocco FB e l'ho rielaborato parecchio, adesso funziona. Lascio qualche screeshot per aiutare chi ha un compito simile e per chi ha qualche consiglio su come migliorarlo. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 25 giugno 2021 Segnala Share Inserita: 25 giugno 2021 Piccole cose. #Campiona è una variabile booleana. Non serve scrivere IF #Campiona = 1 THEN, basta scrivere IF #Campiona THEN (come in C). Per fare incrementi, al posto di k := k + 1; si puiò scrivere k += 1; (come in C) . Anche per la somma potersti scrivere: Somma += Valori[i]; Poi, abitudine mia personale: preferisco moltiplicare per 10 piuttosto che dividere per 0.1 Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 26 giugno 2021 Segnala Share Inserita: 26 giugno 2021 11 ore fa, batta scrisse: Poi, abitudine mia personale: preferisco moltiplicare per 10 piuttosto che dividere per 0.1 E corretto anche perchè le moltiplicazioni sono eseguite sempre in un tempo minore delle divisioni. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 26 giugno 2021 Segnala Share Inserita: 26 giugno 2021 2 ore fa, Livio Orsini scrisse: E corretto anche perchè le moltiplicazioni sono eseguite sempre in un tempo minore delle divisioni. E' il motivo all'origine di questa mia abitudine: la divisione, tra le quattro operazioni base, è la più pesante. Con le prestazioni delle cpu attuali non è molto importante, ma la considero comunque una buona abitudine. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 26 giugno 2021 Segnala Share Inserita: 26 giugno 2021 Tutte le operazioni inverse sono più gravose di quelle dirette. E vero che con l'attuale velocità di elaborazione delle CPU il tempo maggiore di una divisione, rispetto ad una moltiplicazione, non è sigificativo; però giustamente che lavora da parcchi anni è abituato a tener conto anche di quello che oggi non è più così rilevante. Qualche decennio fa anche assegnare al moltiplicando il dato di valore maggiore, rispetto al valore del moltoplicatore, favoriva la riduzione del tempo di elaborazione. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 26 giugno 2021 Segnala Share Inserita: 26 giugno 2021 1 ora fa, Livio Orsini scrisse: che lavora da parcchi anni è abituato a tener conto anche di quello che oggi non è più così rilevante. Già, ora non ci si bada più, mentre una volta era importante. Per lo stesso motivo, se si dovevano fare moltiplicazioni o divisioni, con interi, per potenze di due, si preferifa fare shift a sinistra o a destra. Tutti piccoli accorgimenti che solo chi ha una certa età ha assimilato. Devo comunque ammettere che io stesso non mi curo più di tanto di alleggerire il compito della attuali cpu. Per esempio, un tempo era d'obbligo lavorare in virgola mobile solo nei casi strettamente necessari. Si cercava il più possibile di lavorare sempre con interi, moltiplicando opportunamente i valori per mantenere la precisione necessaria. Ora faccio larghissimo uso di Real e, in qualche caso, anche di LReal. Link al commento Condividi su altri siti More sharing options...
leleviola Inserita: 26 giugno 2021 Segnala Share Inserita: 26 giugno 2021 58 minuti fa, batta scrisse: Per esempio, un tempo era d'obbligo lavorare in virgola mobile solo nei casi strettamente necessari. Si cercava il più possibile di lavorare sempre con interi, moltiplicando opportunamente i valori per mantenere la precisione necessaria. Ora faccio larghissimo uso di Real e, in qualche caso, anche di LReal. come non condividere, quella dello shift non la ricordavo davvero ma quella degli interi è stata un abitudine dura a morire, oggigiorno merita molto di più passare al Real senza troppe fisime mentali, così si standardizza sia l'indirizzamento che la metodologia di calcolo, addirittura un tempo si economizzava sull'uso degli interi e dei doppi interi, e va beh n'è passato dl tempo... Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 27 giugno 2021 Segnala Share Inserita: 27 giugno 2021 16 ore fa, leleviola scrisse: e va beh n'è passato dl tempo... E l'evoluzione .... della spece programmatore🙂. Link al commento Condividi su altri siti More sharing options...
ilghezzi Inserita: 6 marzo 2022 Segnala Share Inserita: 6 marzo 2022 riguardo i numeri real bisogna fare attenzione al risultato nei calcoli sempre meglio usare interi o passare real in interi e poi in real quando serve moltiplicando e dividendo opportunamente in modo da sopprimere decimali non voluti i risultati sui confronti tra real non danno sempre il risultato aspettato Link al commento Condividi su altri siti More sharing options...
ilghezzi Inserita: 6 marzo 2022 Segnala Share Inserita: 6 marzo 2022 FUNCTION_BLOCK "Media_AP" { S7_Optimized_Access := 'TRUE' } VERSION : 0.1 VAR_INPUT "Var_Input" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; Media_Type { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // 0=aritmetica 1=ponderata N_Stack { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // min 4 max 64 END_VAR VAR_OUTPUT "Var_Output" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; END_VAR VAR Stack { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..63] of Int; END_VAR VAR_TEMP i : Int; Somma : DInt; Media_A : Real; Media_P : Real; Varianza : Array[0..63] of Real; Sum_Varianza : Real; Varianza_Tot : Real; Variante : Array[0..63] of Real; Peso : Array[0..63] of Real; Sum_Variante : Real; Sum_Peso : Real; END_VAR BEGIN IF (#Media_Type = 0 OR #Media_Type = 1) AND #N_Stack >= 4 AND #N_Stack <= 64 THEN #Somma := 0; FOR #i := #N_Stack - 1 TO 1 BY -1 DO #Stack[#i] := #Stack[#i - 1]; END_FOR; #Stack[0] := #Var_Input; FOR #i := 0 TO #N_Stack - 1 DO #Somma := #Somma + #Stack[#i]; END_FOR; #Media_A := DINT_TO_REAL(#Somma) / INT_TO_REAL(#N_Stack); IF #Media_Type = 1 THEN #Sum_Varianza := 0.0; #Sum_Variante := 0.0; #Sum_Peso := 0.0; FOR #i := 0 TO #N_Stack - 1 DO #Varianza [#i] := SQR(#Media_A - #Stack[#i]); #Sum_Varianza += #Varianza[#i]; END_FOR; #Varianza_Tot := #Sum_Varianza / INT_TO_REAL( #N_Stack - 1); FOR #i := 0 TO #N_Stack - 1 DO IF #Varianza[#i] <> 0.0 THEN #Variante[#i] := #Varianza_Tot / #Varianza[#i] / 2; ELSE; #Variante[#i] := #Stack[#i]; END_IF; #Sum_Variante += #Variante[#i]; END_FOR; FOR #i := 0 TO #N_Stack - 1 DO #Peso[#i] := #Stack[#i] * #Variante[#i]; #Sum_Peso += #Peso[#i]; END_FOR; #Media_P := #Sum_Peso / #Sum_Variante; END_IF; CASE #Media_Type OF 0: #Var_Output := ROUND(#Media_A) ; 1: #Var_Output := ROUND(#Media_P) ; END_CASE; ELSE #Var_Output := #Var_Input; END_IF; END_FUNCTION_BLOCK Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati