Vai al contenuto
PLC Forum


Trovare il valore maggiore su s7-1200


Messaggi consigliati

Inserito:

Buongiorno a tutti,

vado subito al quesito:

ho 10 valori in 10 variabili differenti vorrei capire come fare per trovare quella con il valore maggiore

 

grazie a tutti


Inserita:

Semplice.

Confronti tra loro le prime 2 variabili e la maggiore la memorizzi in dato che potremmo chiamare "valore_massimo"

Poi esegui un ciclo n volte quante sono le variabili rimanenti. Ogni volta confronti una variabile con "valore_massimo"; se è minore, lasci invariato, salore il valore della variabile è maggiore, sostituisci.

Inserita:

Se hai 10 variabili (supponiamo 10 interi) ti crei puoi creare questa funzione in scl:

FUNCTION "valore_maggiore" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      var_1 : Int;
      var_2 : Int;
      var_3 : Int;
      var_4 : Int;
      var_5 : Int;
      var_6 : Int;
      var_7 : Int;
      var_8 : Int;
      var_9 : Int;
      var_10 : Int;
   END_VAR

   VAR_OUTPUT 
      valore_maggiore : Int;
   END_VAR

   VAR_TEMP 
      val_mag_tmp : Int;
   END_VAR


BEGIN
	#val_mag_tmp := #var_1;
	IF #var_2 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_2;
	END_IF;
	IF #var_3 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_3;
	END_IF;
	IF #var_4 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_4;
	END_IF;
	IF #var_4 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_4;
	END_IF;
	IF #var_5 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_5;
	END_IF;
	IF #var_6 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_6;
	END_IF;
	IF #var_7 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_7;
	END_IF;
	IF #var_8 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_8;
	END_IF;
	IF #var_9 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_9;
	END_IF;
	IF #var_10 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_10;
	END_IF;
	#valore_maggiore := #val_mag_tmp;
	
	
END_FUNCTION

 oppure puoi usare questa funzione in STL :

 

FUNCTION "valore_maggiore_STL" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      var_1 : Int;
      var_2 : Int;
      var_3 : Int;
      var_4 : Int;
      var_5 : Int;
      var_6 : Int;
      var_7 : Int;
      var_8 : Int;
      var_9 : Int;
      var_10 : Int;
   END_VAR

   VAR_OUTPUT 
      valore_maggiore : Int;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #var_1;
      L #var_2;
      <=I;
      JC next1;
      TAK;
next1:      L #var_3;
      <=I;
      JC next2;
      TAK;
next2:      L #var_4;
      <=I;
      JC next3;
      TAK;
next3:      L #var_5;
      <=I;
      JC next4;
      TAK;
next4:      L #var_6;
      <=I;
      JC next5;
      TAK;
next5:      L #var_6;
      <=I;
      JC next6;
      TAK;
next6:      L #var_7;
      <=I;
      JC next7;
      TAK;
next7:      L #var_8;
      <=I;
      JC next8;
      TAK;
next8:      L #var_9;
      <=I;
      JC next9;
      TAK;
next9:      L #var_10;
      <=I;
      JC next10;
      TAK;
next10:      T #valore_maggiore;





END_FUNCTION

oppure se hai un array di 10 interi puoi farla ancora molto più semplice in SCL facendo cosi:

 

FUNCTION "valore_maggiore_array" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      "array" : Array[0..9] of Int;
   END_VAR

   VAR_OUTPUT 
      valore_maggiore : Int;
   END_VAR

   VAR_TEMP 
      val_mag_tmp : Int;
      n1 : Int;
   END_VAR


BEGIN
	#val_mag_tmp := #array[0];
	FOR #n1 := 1 TO 9 DO
	    IF (#array[#n1] >= #val_mag_tmp) THEN
	        #val_mag_tmp := #array[#n1];
	    END_IF;
	END_FOR;
	
	#valore_maggiore := #val_mag_tmp;
END_FUNCTION

ho usato una variabile temporanea ma dovrebbe andare bene anche usando direttamente l'output della funzione.

 

Inserita:

Dipende; se deve ordinare il vettore in ordine crescente o decrescente è una cosa, ma se deve solo trovare il valore maggiore le 2 funzioni sono U.C.A.S.

Inserita: (modificato)

Ciao Livio, scusa non ho esattamente capito cosa vuoi dire, cioè mi spiego meglio, la funzione che ho scritto, ovvero questa:

FUNCTION "valore_maggiore_array" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      "array" : Array[0..9] of Int;
   END_VAR

   VAR_OUTPUT 
      valore_maggiore : Int;
   END_VAR

   VAR_TEMP 
      val_mag_tmp : Int;
      n1 : Int;
   END_VAR


BEGIN
	#val_mag_tmp := #array[0];
	FOR #n1 := 1 TO 9 DO
	    IF (#array[#n1] >= #val_mag_tmp) THEN
	        #val_mag_tmp := #array[#n1];
	    END_IF;
	END_FOR;
	
	#valore_maggiore := #val_mag_tmp;
END_FUNCTION

è adatta solo per trovare il valore maggiore (oppure modificandola leggermente, il valore minore) all'interno di un array.

Se invece devo ordinare un array in ordine crescente o decrescente uso l'algoritmo bubble sort, e quindi devo sicuramente fare due cicli for, oppure un while e un for, ad esempio se devo ordinare un array in ordine crescente faccio cosi:

FUNCTION "array_in_ordine_crescente" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      array_in : Array[0..9] of Int;
   END_VAR

   VAR_OUTPUT 
      array_out : Array[0..9] of Int;
   END_VAR

   VAR_TEMP 
      n1 : Int;
      m1 : Int;
      tmp : Int;
   END_VAR


BEGIN
	(*riceve in ingresso un array, e restituisce in uscita un array con gli elementi
	del primo ma in ordine crescente*)
	#m1 := 9;
	#array_out := #array_in;
	WHILE #m1>0 DO
	    FOR #n1 := 0 TO #m1-1 DO
	        IF #array_out[#n1] >= #array_out[#n1 + 1] THEN
	            #tmp := #array_out[#n1];
	            #array_out[#n1] := #array_out[#n1 + 1];
	            #array_out[#n1 + 1] := #tmp;
	        END_IF;
	    END_FOR;
	    #m1 := #m1 - 1;
	END_WHILE;
	
	
	
END_FUNCTION

dove avrei anche potuto utilizzare solo un array dichiarato come variabile InOut se non è problema perdere l'ordine dell'array in ingresso.

Modificato: da android633
Inserita:

Per me che non sono un esperto in programmazione è un pò complesso l'esempio di android, proverò la soluzione di Livio anche se pensavo che nel 1200 esistesse una funzione già fatta per questo scopo...

Grazie a tutti

Inserita: (modificato)

Intanto le variabili potrebbero essere 10 (o n con n qualsiasi) variabili non organizzate in un array

   VAR_OUTPUT 
      valore_maggiore : Int;
      END_VARIF 
     IF
          var1 >= var2 
       THEN
	      valore_maggiore := var1;
	 END_IF;
     IF 
      var3 >= valore_maggiore 
     THEN
	      valore_maggiore := var3;
     ENDIF 
     IF 
         var"n" >= valore_maggiore 
     THEN
	          valore_maggiore := var"n";
     ENDIF

Quindi la funzione più generale per ricercare il massimo o il minimo (o entrambi) segue questo schema

Nel caso di ricerca del minimo e/o del massimo di un vettore la funzione è simile e si usa solo un test di if inglobato in loop reiterato n volte quanti sono gli elementi del vettore -1.

Questo lo ricordo bene perchè era il primo esercizio dell'insegnamento di calcolo automatico del corso di laurea di fisica ad indirizzo elettronico - informatico (50 anni fa l'informatica non era una disciplina propria). L'esercizio chiedeva la ricerca del minimo e del massimo di un vettore di "n" elementi, poi chiedeva l'ordinamento dello stesso vettore in ordine crescente e decrescente; dei 3 problemi bisognava scrivere l'analisi, disegnare il diagramma di flusso, scrivere il listato in fortran4. Ricordo che la parte che fece ammattire lu la parte di formamttazione dell'uscita dove bisognava mettere a posto gli "hollerit" per ogni riga di uscita.:huh:

Io ho una memoria come una PROM; una volta memorizzato un epeisodio/concetto non c'è verso di cancellarlo se non distruggendo la cella di memoria.

Purtroppo comincio ad avere qaulche cluster danneggiato.:(:(

PS non garantisco che la sintassi sia perfetta perchè non conosco il 1200 e sono più di 10 anni che non programmo in step7

 

Modificato: da Livio Orsini
Inserita:

Io ho una memoria come una PROM; una volta memorizzato un epeisodio/concetto non c'è verso di cancellarlo se non distruggendo la cella di memoria.

Purtroppo comincio ad avere qaulche cluster danneggiato.:(:(

Livio allora ci vorrebbe una copia di backup di tutte le cose che hai imparato avrebbe un bel valore di esperienza:tongue_smilie:

Inserita:

Potessi farlo il back-up lo farei.

Oramai è strumentalmente provata la decadenza cerebrale. Comparamdo due due tomografie celebrali, eseguite sullo stesso individuo, una all'età di circa 20-25 anni e l'altra 50 anni dopo mostra una rididuzione della massa cerebrale del 20%.

Molti dipende dalle condizioni di partenza, oltre che dal tipo di vita; infatti la professoressa Montalcini a quasi 100 anni aveva ancora unìintelligenza vivace, mentre ci sono in circolazione dei 40 enni che sono oramai dementi perchè già le condizioni iniziali erano scadenti, poi l'abuso di alcol e l'uso di droghe anche "leggere" fa il resto.

Oggi purtroppo o fortunatamente, è possibile misurare strumentalmente l'intelligenza.

Inserita:

è vero, però c è la memoria e se l intelligenza inizia a scendere con l età se nella vita si è formato un bel bagaglio di esperienza questa compensa il tutto facendo si che molti di età superiore a 60anni sono piu produttivi di 20 enni cervelloni ma senza esperienza. é un po come il detto, il giovane va veloce ma non conosce la strada,l anziano va lento ma conosce  già bene la strada;)

Inserita:

Quindi la funzione più generale per ricercare il massimo o il minimo (o entrambi) segue questo schema

Nel caso di ricerca del minimo e/o del massimo di un vettore la funzione è simile e si usa solo un test di if inglobato in loop reiterato n volte quanti sono gli elementi del vettore -1.

È esattamente quello che ha fatto "android633" nei suoi esempi. Non vedo UCAS.

Inserita:

È esattamente quello che ha fatto "android633" nei suoi esempi. Non vedo UCAS.

Non è esattamente quello che ha fatto android.

Inserita:

Esempio di android:

#val_mag_tmp := #var_1;
	IF #var_2 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_2;
	END_IF;
	IF #var_3 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_3;
	END_IF;
	IF #var_4 >= #val_mag_tmp THEN
	    #val_mag_tmp := #var_4;
	END_IF;

Esempio di Livio:

     IF
          var1 >= var2 
       THEN
	      valore_maggiore := var1;
	 END_IF;
     IF 
      var3 >= valore_maggiore 
     THEN
	      valore_maggiore := var3;
     ENDIF 

L'unica differenza è che android ha, correttamente, inizializzato la variabile #val_mag_tmp.

Nel secondo caso, se la variabile maggiore fosse "var2", il suo valore non verrebbe rilevato. Si potrebbe aggiungere un ELSE. Ma questo è dovuto solo al fatto che il codice è stato scritto in fretta, con l'unico scopo di fornire un esempio. E, come esempio, a me sembra assolutamente identico a quello di android.

 

Poi, personalmente, io userei > al posto di >=. Ma cambia poco.

Inserita:

Questo si il Mio riferimento all'UCAS si riferiva al primo esempio, quello che realizza l'ordinamento del vettore, mentre è stato richiesto una semplice richiesta del valore massimo.

Poi, personalmente, io userei > al posto di >=. Ma cambia poco.

Infatti è solo una questione concettuale.

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