Vai al contenuto
PLC Forum


Somma di valori di una struct/array


bhef

Messaggi consigliati

Buonasera ragazzi. Avrei una curiosità.

 

Mettiamo che ho una DB con all'interno una struttura o array di n interi (per esempio n = 100) e volessi sommare il valori di tutti questi interi.

Come faccio in KOP a sommare tutti questi valori al posto di creare un ADD di 100 IN? Esiste un'istruzione più rapida che possa farlo?

 

Grazie per le risposte.

Link al commento
Condividi su altri siti


In kop una follia, in scl 3 righe:

 

Cattura.JPG.1e29c19cbc12065f658e44dcaa53e08f.JPG

Attento quando sommi tanti interi che rischi di andare oltre il valore consentito in una variabile INT, ti conviene per la variabile somma usare un DINT.

Link al commento
Condividi su altri siti

Hai ragione, ma non ho mai preso in considerazione di fare un ciclo FOR NEXT in KOP quindi la mia idea era fare una serie di somme, ma in SCL è talmente banale.

Link al commento
Condividi su altri siti

Ah ok è che l'ho sempre fatto in Ladder con altri marchi mi sembrava strano non si potesse fare in Kop con Siemens, grazie acquaman

vero è che in SCL è abbastanza più semplice o sintetico

Link al commento
Condividi su altri siti

For_1.thumb.png.abd185b3dde506df4af6da9da3eaaeae.png

Effettivamente in Kop perde qualcosa in leggibilità,ma si fa.

Rispetto a SCL si deve aggiungere fisicamente la parte dove si inizializza e si incrementa l'indice (in SCL lo fa automaticamente la sintassi del 'For Indice:=0 To 99 DO..')

Nel mio esempio c' è già la conversione del valore INT con DINT, necessaria per sommare valori dello stesso tipo( 'dati' è un array di INT mentre Somma è una DINT come giustamente consigliava acquaman) ed è gestito anche il comando per effettuare la somma. 

Link al commento
Condividi su altri siti

 

20 ore fa, acquaman ha scritto:

Hai ragione, ma non ho mai preso in considerazione di fare un ciclo FOR NEXT

Io intendevo un ciclo tipo FOR NEXT, con il 1500 quelle istruzioni non ci sono.

Link al commento
Condividi su altri siti

Si può fare in ladder anche con il 1200/1500.
Esempio:

immagine.png.6f0c6f0a35b0a2757de3ab4d83e7319a.png

 

Ma, sinceramente, non lo farei mai.
Non dimentichiamo che, nei 1200/1500, in un blocco in ladder posso inserire segmenti in testo strutturato.
Se ciò non fosse possibile, dovrei creare appositamente un blocco in testo strutturato da richiamare dal blocco in ladder.
In questo caso, potrebbe avere senso anche costruire il ciclo in ladder.
Ma, come detto sopra, potendo inserire un segmento in testo strutturato all'interno di un blocco in ladder, direi che fare il ciclo in ladder ha senso solo per i più masochisti.

 

Non me ne voglia poi Acquaman se mi permetto di modificare un po' il suo codice. Codice che non contiene errori, sia chiaro, ma solo per specificare che la variabile del ciclo FOR può tranquillamente essere una variabile locale (anzi, il più delle volte si usa così), per tenere conto di quanto già detto da Acquaman, che se non sono certo che la somma di tutti gli elementi INT rimanga sempre nel campo di un INT, la somma la devo mettere in un DInt (quindi faccio la conversione INT_TO_DINT), e per illustrare l'uso dell'operatore += (che come -=, *= e /= è possibile, mi pare, da TIA V15 o V15.1 in poi).
Inoltre (ma questa è una mia abitudine), preferisco eseguire il ciclo for appoggiando la somma ad una variabile locale, e solo all'uscita del ciclo trasferire il risultato nella variabile globale.

#tmpTotale := 0;
FOR #i := 0 TO 99 DO
    #tmpTotale += INT_TO_DINT("MyDB".Element[#i]);
END_FOR;
"MyDB".Totale := #tmpTotale;


 

Modificato: da batta
Link al commento
Condividi su altri siti

Scusami batta ma il FOR iniziale non c'è nel tuo esempio, si indroduce direttamente il NEXT a inizio loop?

L'ultima istruzione che hai introdotto in SCL è davvero potente, mi sembra faccia la somma diretta di tutti i campi presenti nel loop

Link al commento
Condividi su altri siti

Infatti Batta usa una istruzione di salto il "NEXT" è l'etichetta di dove saltare e la poteva chiamare in qualunque modo, anche PIPPO.

3 ore fa, batta ha scritto:

Non me ne voglia poi Acquaman

Assolutamente, c'è sempre da imparare.

Link al commento
Condividi su altri siti

Scusatemi sono un po' arrugginito con Siemens lo sto usando poco ultimamente, è vero NEXT è l'etichetta, pardon

comunque è un escamotage senza l'uso del FOR  .... NEXT

Link al commento
Condividi su altri siti

È esattamente come dice Acquaman.
Ho ricreato un ciclo FOR-NEXT facendo un salto all'indietro, perché nel Siemens non esiste un'istruzione FOR-NEXT in ladder.
In realtà, più che ad un ciclo FOR, sarebbe assimilabile ad un WHILE.
Attenzione poi che i salti all'indietro sono molto pericolosi: se ci sono errori, rischi di mandare in stop la cpu.
Che poi, è esattamente il rischio che si corre anche con un WHILE.

Per dire, nell'esempio che ho postato, se dovessi passare alla funzione di somma valori non coerenti, l'uscita del box non si attiverebbe, e non uscirei più dal loop.
Meglio sarebbe mettere l'incremento dell'indice e la successiva comparazione sotto a tutte le altre operazioni, senza nessun vincolo, in modo da avere l'assoluta certezza che l'incremento dell'indice e la comparazione vengano sempre eseguite.

In strutturato, volendolo fare con un WHILE, diventerebbe così:

#tmpTotale := 0;
#i := 0;
WHILE #i <= 99 DO
    #tmpTotale += INT_TO_DINT("MyDB".Element[#i]);
    #i += 1;
END_WHILE;
"MyDB".Totale := #tmpTotale;

Con il FOR è più comodo, e non si corre il rischio di mandare in stop la cpu perché, magari in una modifica online, ci si è stupidamente dimenticati la riga con l'incremento dell'indice.

 

Da precisare, inoltre, che con le cpu 1200/1500, l'azzeramento delle variabili locali viene eseguito in automatico.
Nel 300/400, invece, una variabile locale che non viene prima inizializzata potrebbe avere un valore qualsiasi.
Personalmente però preferisco, anche con il 1500, fare l'inizializzazione in modo evidente, scrivendola nel codice.

 

1 ora fa, acquaman ha scritto:

Assolutamente, c'è sempre da imparare.

Credo di non avere nulla da insegnarti.

Link al commento
Condividi su altri siti

Ottima chiarimento batta

vero è che come dici sempre meglio utilizzare un FOR e non si corre nessun rischio, daltronde quello è un loop da ripetere le volte che si vuole,

l'ho utilizzato tantissimo con altri marchi lo utilizzerò in SCL visto che è più semplice e meno arzigorgolato

Link al commento
Condividi su altri siti

  • 3 weeks later...

Scusate il ritardo, intanto grazie mille per le spiegazioni.

 

Ho risolto inserendo semplicemente un segmento in SCL.

 

Grazie a tutti

Link al commento
Condividi su altri siti

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 account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...