Vai al contenuto
PLC Forum


dubbio su variabile temp usata più volte (s7-300)


coquinati

Messaggi consigliati

buonasera ragazzi.

dentro una FB  ho dichiarato una variabile DW nelle TEMP per utilizzarla in più segmenti assegnandoli vari  formati pointer, secondo voi può funzionare o sto combinando un pasticcio di quelli grandi ?

 vi incollo una parte di codice 

  L     P#21.2
  T     #pointer_var
  UN    #emergency_stop_motor
  =     DIX [#pointer_var]              //poniter var temp 
   

  L     P#21.1
  T     #pointer_var
  UN    #Coast_stop_motor
  =     DIX [#pointer_var]              //poniter var temp  


  L     P#21.7
  T     #pointer_var
  U     #W_F_ACK
  =     DIX [#pointer_var]             //poniter var temp
        

 

c'è qualche controindicazione nel farlo ?

cordiali saluti 

coquinati

Modificato: da coquinati
Link al commento
Condividi su altri siti


6 minuti fa, batta scrisse:

No, nessuna controindicazione. Solo non capisco il perché di questo codice.

buonasera batta.

in poche parole ricevo una word da un inverter e dentro di essa sono presenti dei bit di comando che io devo andar ad attivare

per esempio 21.0 è un byte  che si trova del blocco dati  e che devo inviare .

la ringrazio molto 

Modificato: da coquinati
Link al commento
Condividi su altri siti

Quote

la ringrazio molto 

Perché mi dai del lei? Qui ci si dà tutti del tu.

 

Potresti creare una struttura con i bit che ti servono (#emergency_stop_motor, #coast_stop_motor, ecc) e poi, con l'istruzione LAR1 e un puntatore, andare a scrivere tutta la struttura nella word di comando. In questo modo, anche se apporti modifiche al blocco che spostano gli indirizzi delle variabili, non devi modificare a mano questi indirizzi.

Se mi dai qualche indicazione in più su quello che devi fare, vedo di preparare un esempio.

Link al commento
Condividi su altri siti

14 ore fa, batta scrisse:

 

 

Potresti creare una struttura con i bit che ti servono (#emergency_stop_motor, #coast_stop_motor, ecc) e poi, con l'istruzione LAR1 e un puntatore, andare a scrivere tutta la struttura nella word di comando. In questo modo, anche se apporti modifiche al blocco che spostano gli indirizzi delle variabili, non devi modificare a mano questi indirizzi.

 

 seguendo i tuoi consigli ho modificato il codice in questa maniera :

  LAR1  P#20.0                      //default byte di scrittura 

  UN    #emergency_stop_motor
  =     DIX [AR1,P#1.2]             //21.2


  UN    #Coast_stop_motor
  =     DIX [AR1,P#1.1]


  U     #W_F_ACK
  =     DIX [AR1,P#1.7]

gli ho interpretati bene ?

 

14 ore fa, batta scrisse:

 

Se mi dai qualche indicazione in più su quello che devi fare, vedo di preparare un esempio.

 

volentieri cosi capisco anche come ragionare con una logica professionale, io ricevo degli input dal plc ( #emergency_stop_motor, #coast_stop_motor) questi li elaboro dentro la FB dopo di che non faccio altro che settare i bit di commando del inverter attraverso quelli mandati dal plc ,volendo posso mandarti la fb se non sono stato esaudiente .

14 ore fa, batta scrisse:

Perché mi dai del lei? Qui ci si dà tutti del tu.

 

 

fin che non mi viene detto cerco di comportarmi in maniera più cordiale possibile 😃

saluti 

 

coquinati

Link al commento
Condividi su altri siti

Quote

gli ho interpretati bene ?

In parte.

 

Io cerco sempre di evitare l'assegnazione di indirizzi all'interno di un blocco. Questo perché, se dovessi modificare l'interfaccia delle variabili, dovrei poi mettere mano al codice per correggere gli indirizzi.

Al posto di

LAR1 P#20.0

potresti scrivere:

LAR1 P##NomePrimoBit

Dove con NomePrimoBit intendo quello che, per seguire il tuo esempio, corrisponde a P#20.0.

 

Potresti però semplificare ulteriormente il tutto, mettendo i bit che ricevi dal PLC in una struttura (non è obbligatorio, ma è più ordinato), e scrivere qualcosa del genere:

      LAR1  P##MyBits
      L W [ AR1 , P#0.0 ]
      T     #CTW

Dove MyBits è il nome della struttura di bit che ricevi dal PLC, e CTW è la variabile di comando da inviare all'inverter.

Dovrai, ovviamente, dichiarare i bit della struttura nel corretto ordine, e stando attento all'eventuale inversione dei byte.

 

Queste però sono sempre soluzioni basate su AWL e utilizzo di puntatori. Personalmente (ma sono sicuro di essere in buona compagnia), date le possibilità offerte dal TIA e dalle nuove CPU, faccio sempre meno uso dei puntatori.

Per esempio, senza ricorrere a puntatori, potresti molto semplicemente usare l'istruzione GATHER (vedi esempio).

image.png.81bc1288ced4741a2b0f626293b6bcab.png

 

Con GATHER, puoi fare quello che ti serve anche in KOP o in SCL, e anche in blochhi "ottimizzati".

Anche in questo caso, dovrai sempre dichiarare la struttura di bit nel giusto ordine, e la struttura dovrà essere esattamente della dimensione della variabile CTW (se CTW è una WORD, la struttura dovrà essere di 16 bit).
Rispetto al metodo precedente (l'esempio in AWL), con l'uso di GATHER ti troverai i due byte della variabile scambiati.

Sinceramente, io abbandonerei AWL e puntatori, e opterei per questa soluzione.
Unico problema, GATHER (e l'opposto SCATTER) funziona con strutture di bit solo dalla V15. Se hai la V14, GATHER funziona solo con array di bit.
Anche l'uso di un array di bit però lo trovo sempre preferibile rispetto ad AWL e puntatori (e se te lo dico io che sono appassionato di AWL e molto restio ad abbandonarlo...).
È vero che, a differenza di una STRUCT nel caso dell'ARRAY non potrai assegnare un nome ad ogni singolo bit, ma potrai comunque assegnare un commento ad ogni singolo bit, e mantenere così la leggibilità del codice.

Link al commento
Condividi su altri siti

3 ore fa, batta scrisse:

In parte.

 

Io cerco sempre di evitare l'assegnazione di indirizzi all'interno di un blocco. Questo perché, se dovessi modificare l'interfaccia delle variabili, dovrei poi mettere mano al codice per correggere gli indirizzi.

Al posto di

LAR1 P#20.0

potresti scrivere:

LAR1 P##NomePrimoBit

Dove con NomePrimoBit intendo quello che, per seguire il tuo esempio, corrisponde a P#20.0.

 

Potresti però semplificare ulteriormente il tutto, mettendo i bit che ricevi dal PLC in una struttura (non è obbligatorio, ma è più ordinato), e scrivere qualcosa del genere:


      LAR1  P##MyBits
      L W [ AR1 , P#0.0 ]
      T     #CTW

Dove MyBits è il nome della struttura di bit che ricevi dal PLC, e CTW è la variabile di comando da inviare all'inverter.

Dovrai, ovviamente, dichiarare i bit della struttura nel corretto ordine, e stando attento all'eventuale inversione dei byte.

Con l’inversione dei byte penso che intendi dire il formato “big endian”.

comunque ho seguito alla lettera il consiglio di Eliminare l’assegnazione via indirizzo, però facendo questo ad un certo punto  mi son trovato davanti ad un problema! E  già che ci sono se posso chiedo ancora il tuo aiuto o quello del forum . 

Nelle variabili STAT ho creato due STRUCT una letteruta e scrittura , Dentro queste STRUCT sono presenti le varie parole e doppie parole del telegramma , per esempio nella lettura ricevo la velocità del motore (RPM_MOTOR)

Al posto di scrivere

 

L            DID           37

 

 

ho scritto  come sulla foto il nome simbolico ma non me lo prende mi dice che fosse come inesistente questo simbolo .

 

è per il fatto che è dichiarato dentro una STRUCT?

 

3 ore fa, batta scrisse:

I

.Queste però sono sempre soluzioni basate su AWL e utilizzo di puntatori. Personalmente (ma sono sicuro di essere in buona compagnia), date le possibilità offerte dal TIA e dalle nuove CPU, faccio sempre meno uso dei puntatori.

Per esempio, senza ricorrere a puntatori, potresti molto semplicemente usare l'istruzione GATHER (vedi esempio).

image.png.81bc1288ced4741a2b0f626293b6bcab.png

 

Con GATHER, puoi fare quello che ti serve anche in KOP o in SCL, e anche in blochhi "ottimizzati".

Anche in questo caso, dovrai sempre dichiarare la struttura di bit nel giusto ordine, e la struttura dovrà essere esattamente della dimensione della variabile CTW (se CTW è una WORD, la struttura dovrà essere di 16 bit).
Rispetto al metodo precedente (l'esempio in AWL), con l'uso di GATHER ti troverai i due byte della variabile scambiati.

Sinceramente, io abbandonerei AWL e puntatori, e opterei per questa soluzione.
Unico problema, GATHER (e l'opposto SCATTER) funziona con strutture di bit solo dalla V15. Se hai la V14, GATHER funziona solo con array di bit.
Anche l'uso di un array di bit però lo trovo sempre preferibile rispetto ad AWL e puntatori (e se te lo dico io che sono appassionato di AWL e molto restio ad abbandonarlo...).
È vero che, a differenza di una STRUCT nel caso dell'ARRAY non potrai assegnare un nome ad ogni singolo bit, ma potrai comunque assegnare un commento ad ogni singolo bit, e mantenere così la leggibilità del codice.

 

Magari ... sono ancora fermo a step7 5.5 sp3, comunque me lo son scritto giù , si sa mai magari in un futuro posso  aggiornarmi anche io se le finanze lo acconsentono .

il linguaggio AWL lo trovo estremamente affascinante e appassionante , è un linguaggio molto vicino alla cpu e utilizzarlo a mio parer rende  il tutto più professionale

 

cordiali saluti 

 

Coquinati 

A27192AE-7354-4572-ABD9-0557D06551FD.jpeg

Link al commento
Condividi su altri siti

Quote

è per il fatto che è dichiarato dentro una STRUCT?

Sì, certo.

Devi scrivere NomeStruttura.NomeVariabile.

Nel tuo caso: LETTURA_DP.rpm_motor

Due strutture possono contenere anche variabili con lo stesso nome. Anzi, si usa molto spesso.

 

Quote

il linguaggio AWL lo trovo estremamente affascinante e appassionante , è un linguaggio molto vicino alla cpu e utilizzarlo a mio parer rende  il tutto più professionale

Anche a me piace il linguaggio AWL (non per tutti i compiti, però). Molti lo considerano complicato, invece a me sembra estremamente semplice: scrivi le istruzioni, una alla volta, così come verranno eseguite dalla CPU. Si tratta però di un linguaggio che, dalla stessa Siemens, è sempre meno tenuto in considerazione. Questo almeno sulle CPU 1500. Lavorando con 300/400 l'AWL è ancora indispensabile.

In ogni caso, per un'operazione come quella che devi fare tu, anche se giocare con i puntatori può essere divertente, si va sempre a creare un codice non immediatamente comprensibile. Obbligatorio quindi riempire di commenti.
E c'è sempre un altro rischio: se il blocco viene richiamato come multiistanza, dovresti tener conto anche dell'indirizzo da cui parte la multiistanza, e sommarlo all'interno della funzione.
Nel tuo caso (CPU serie 300 e Step7 5.5) non hai l'istruzione GATHER, ma è semplice costruirsela. Io seguirei questa strada. Il codice ne guadagnerà in semplicità.

Link al commento
Condividi su altri siti

1 ora fa, batta scrisse:

è sempre meno tenuto in considerazione. Questo almeno sulle CPU 1500. 

Non ho ancora avuto l’onore di mettere mano su una 1500, so solo che é la cpu predecessore  della serie 300 , o almeno un po’ alla volta stanno cercando di portarla a pari livelli .

 sembra che si sta cercando di semplificare tutto nel mondo dell’automazione  , drive sempre più intelligenti e linguaggi più chiari veloci  e comprensibili .

 il tutto per rendere più veloce la programmazione o eventuale modifica SW in modo da risparmiare tempo e ridurre i costi ,cosa che al giorno d’oggi è fondamentale.

1 ora fa, batta scrisse:

 

Nel tuo caso (CPU serie 300 e Step7 5.5) non hai l'istruzione GATHER, ma è semplice costruirsela. Io seguirei questa strada. Il codice ne guadagnerà in semplicità.

 

Appena ho un minuto provo ragionarci sopra su come farla , può tornare sempre utile.

 

1 ora fa, batta scrisse:

Sì, certo.

Devi scrivere NomeStruttura.NomeVariabile.

Nel tuo caso: LETTURA_DP.rpm_motor

Due strutture possono contenere anche variabili con lo stesso nome. Anzi, si usa molto spesso.

 

 

 

Grazie 

Modificato: da coquinati
Link al commento
Condividi su altri siti

1 ora fa, coquinati scrisse:

Non ho ancora avuto l’onore di mettere mano su una 1500, so solo che é la cpu predecessore  della serie 300 

 Volevo scrivere il contrario , mi sono accorto ora dell’errore commesso .

scusate , buon pomeriggio .

Link al commento
Condividi su altri siti

Quote

 Volevo scrivere il contrario , mi sono accorto ora dell’errore commesso .

Sì, era chiaro.

 

Una dritta di come potresti creare una FC per copiare una struttura di 16 bit in una variabile di tipo Word.
Per poter passare una struttura come parametro ad una funzione, la struttura che passi e il parametro della funzione devono essere identici.
Ti conviene quindi creare un UDT con i 16 bit che compongono la word di comando.

Utilizzi questo UDT per creare la struttura di bit dove il PLC andrà a scrivere i comandi.

Crei una FC con una variabile INPUT di tipo "Nome_UDT" (sempre l'UDT di cui sopra), una variabile OUTPUT di tipo Word, e una variabile TEMP sempre di tipo Word.

Nella FC scrivi qualcosa tipo questo:

LAR1  P##tmpCtw

      U     #Bits._00
      =     L [AR1,P#0.0]
      U     #Bits._01
      =     L [AR1,P#0.1]
	  ......
	  ......
	  ......
	  U     #Bits._14
      =     L [AR1,P#1.6]
      U     #Bits._15
      =     L [AR1,P#1.7]

      L     #tmpCtw
      T     #CTW

Dove #Bits._xx saranno ovviamente il nome che avrai dato al parametro di Input e i nomi dei singoli bit.

Il richiamo della funzione si presenta così:

      CALL  "MiaFunzione"
       Bits:=#Bits
       CTW :=#CTW

Io penso sia più pratico e di facile comprensione rispetto l'uso dei puntatori.

Link al commento
Condividi su altri siti

Inoltre posso scriverla già predisposta per il  formato “big endian” così evito di fare un mucchio di confusione all’interno di ogni segmento .

 

Grazie ancora .

Modificato: da coquinati
Link al commento
Condividi su altri siti

il 12/1/2019 at 12:49 , batta scrisse:

Devi scrivere NomeStruttura.NomeVariabile

 

Ma è possibile che se uso il registro AR1 con l’istruzione L cioè LAR1 step7 mi fa dichiarare solo il nome della struttura , Non mi permette di inserire il nome della variabile .

 Ho provato fare vari ragionamenti per arrivare ad un che ma nulla ... 

Esempio non funzionante   :

LAR1.      P##nomestruttura.nomevariabile

 

 

 

Link al commento
Condividi su altri siti

Salve ! Per motivi personali torno solo ora a riprendere in mano quanto detto da batta . 

ho seguito il l’esempio di creare due strutture identiche per poi richiamarle , solo che mi trovo davanti un problema

nell udt ho creato una struttura bits. Che contiene i 16 bit . E in ingresso alla funzione una struct che a sua volta contiene 16 bit.

io provo copiarla in questa maniera (vedi immagine )

mi punta in modo  assoluto all’indirizzo   p#DB4.DBX0.0    Puó andare così ?

Non capisco cosa c’entra il DBX0.0 quando io devo lavorare su un intero db .

ringrazio anticipatamente , purtroppo è la prima volta che mi trovo a copiare strutture intere 

79A61E3D-F3BD-46DB-9048-FDE74F648E64.jpeg

Modificato: da coquinati
Link al commento
Condividi su altri siti

Quote

Non capisco cosa c’entra il DBX0.0 quando io devo lavorare su un intero db .

È l'indirizzo del primo bit della struttura, ovvero l'indirizzo da dove inizia la struttura.

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