coquinati Inserito: 10 gennaio 2019 Segnala Inserito: 10 gennaio 2019 (modificato) 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: 10 gennaio 2019 da coquinati
batta Inserita: 10 gennaio 2019 Segnala Inserita: 10 gennaio 2019 No, nessuna controindicazione. Solo non capisco il perché di questo codice.
coquinati Inserita: 10 gennaio 2019 Autore Segnala Inserita: 10 gennaio 2019 (modificato) 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: 10 gennaio 2019 da coquinati
batta Inserita: 10 gennaio 2019 Segnala Inserita: 10 gennaio 2019 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.
coquinati Inserita: 11 gennaio 2019 Autore Segnala Inserita: 11 gennaio 2019 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
batta Inserita: 11 gennaio 2019 Segnala Inserita: 11 gennaio 2019 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). 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.
coquinati Inserita: 12 gennaio 2019 Autore Segnala Inserita: 12 gennaio 2019 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). 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
batta Inserita: 12 gennaio 2019 Segnala Inserita: 12 gennaio 2019 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à.
coquinati Inserita: 12 gennaio 2019 Autore Segnala Inserita: 12 gennaio 2019 (modificato) 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: 12 gennaio 2019 da coquinati
coquinati Inserita: 12 gennaio 2019 Autore Segnala Inserita: 12 gennaio 2019 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 .
batta Inserita: 12 gennaio 2019 Segnala Inserita: 12 gennaio 2019 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.
coquinati Inserita: 12 gennaio 2019 Autore Segnala Inserita: 12 gennaio 2019 (modificato) 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: 12 gennaio 2019 da coquinati
coquinati Inserita: 15 gennaio 2019 Autore Segnala Inserita: 15 gennaio 2019 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
coquinati Inserita: 21 gennaio 2019 Autore Segnala Inserita: 21 gennaio 2019 (modificato) 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 Modificato: 21 gennaio 2019 da coquinati
batta Inserita: 22 gennaio 2019 Segnala Inserita: 22 gennaio 2019 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.
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora