Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Somma di valori di una struct/array


Messaggi consigliati

Inserito:

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.


Inserita:

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.

Inserita:

perchè in KOP una follia, analoga istruzione FOR non si può usare anche in KOP? In KOP non si può indicizzare?

Inserita:

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.

Inserita:

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

Inserita:

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. 

Inserita:

 

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.

Inserita: (modificato)

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
Inserita:

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

Inserita:

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.

Inserita:

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

Inserita:

È 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.

Inserita:

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

  • 3 weeks later...
Inserita:

Scusate il ritardo, intanto grazie mille per le spiegazioni.

 

Ho risolto inserendo semplicemente un segmento in SCL.

 

Grazie a tutti

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...