Vai al contenuto
PLC Forum


Accesso Alle Variabili Interne Dell'istanza Di Una Funzione


batta

Messaggi consigliati

Dopo tanto tempo che lavoro quasi esclusivamente con Siemens, ecco che mi ritrovo a prendere in mano Omron.

Sto usando una CPU CJ2M.

Ho bisogno di portare da Siemens a Omron una mia funzione di posizionamento.

Per quanto riguarda la scrittura del codice (in strutturato), nessun problema.

La mia funzione però prevede l'utilizzo di variabili di setup interne, che vengono impostate da HMI oppure scritte direttamente.

Ho scelto questa strada (setup su variabili interne, che in Siemens significa variabili del DB di istanza) perché i parametri da impostare sono parecchi, e sarebbe molto scomodo doverli inserire come variabili in ingresso.

Non riesco però ad accedere alle variabili dell'istanza della funzione.

È possibile?

E se sì, qual è la sintassi?

Per esempio, se voglio accedere alla variabile interna "MiaVarInterna" dell'istanza "MiaIstanza", cosa devo scrivere?

Grazie.

Link al commento
Condividi su altri siti


Per accedere a una variabile interna, questa la si chiama ISTANZA.NOMEVAR

Supponiamo che l'istanza della funzione sia ASD, e che la variabile interna sia Pippo, allora potrai farci riferimento come ASD.Pippo

Però per accederci dall'esterno, come un display, temo sia complicato (non ho mai provato), perchè la variabile interna non ha indirizzo fisso, ma viene assegnata dal compilatore a seconda della sua necessità.

In tali casi, conviene definire una struttura allocata fisicamente che passerai alla funzione (oppure meglio la fai globale e ci accedi da dentro la tua funzione), e il display accederà agli indirizzi fisici dei singoli elementi della struttura.

Link al commento
Condividi su altri siti

È quello che immaginavo e che provavo a fare. Quando compilo però mi viene segnalato il seguente errore: "ERRORE: Passo in rung 4 (6, 2) - Indirizzo - H547 è riservato per l'utilizzo blocco funzione".

Lo stesso errore mi appare anche se accedo direttamente a H547.

Link al commento
Condividi su altri siti

Si, aspetta, io intendevo accedere da pannello. Le variabili interne delle FB vengono messe in area autoallocata H500->, che non è accessibile dal tuo programma.

Per far quello, basta che definisci le tue interne in indirizzo fisso condivisibile, mediante l'attributo AT nella definizione.

Link al commento
Condividi su altri siti

Per far quello, basta che definisci le tue interne in indirizzo fisso condivisibile, mediante l'attributo AT nella definizione.

Nel caso specifico, devo controllare un solo asse, quindi posso permettermi di fare un blocco funzione con accesso a variabili con indirizzi fissi.

Nel caso però dovessi controllare due assi, non potrei quindi richiamare due volte la funzione con istanza diversa?

Quindi, se seguo la strada delle due istanze, non posso accedere da programma alle variabile interne delle istanze, mentre se definisco gli indirizzi mediante l'attributo AT, non posso usare la stessa funzione per due assi.

Ho capito bene?

Penso di aver risolto creando un "Tipo di dati" con la struttura delle mie variabili di setup.

Nella funzione poi ho inserito il tipo di dati nel gruppo variabili Ingresso/Uscita (come dati di setup mi sarebbe andato bene metterle come variabili in ingresso, ma non è possibile).

I valori di setup li vado a scrivere, per esempio, a partire da D1000 seguendo lo stesso ordine della struttura definita nel Tipo di dati.

Poi, quando richiamo la funzione, collego D1000.

Mi pare, comunque, che l'area di memoria dedicata ai blocchi funzione sia piuttosto limitata.

Io sono abituato a programmare Siemens, e la gestione di una FB con più istanze è banale.

Ora, non voglio certo scatenare le solite guerre su quale sia il PLC migliore (io continuo a sostenere che il migliore è quello che si conosce meglio),

ma il prossimo che mi viene a dire, come accade spesso, che Siemens è complicato e Omron è semplice, lo uccido ;)

Link al commento
Condividi su altri siti

Forse non ho capito bene il problema.

Innanzi tutto, l'accesso da software alle variabili interne a una funzione non è di solito consigliabile, vedi per esempio la programmazione in C dove le variabili interne sono assolutamente invisibili dall'esterno (come in tutti i linguaggi di programmazione di livello superiore all'assembler...)

Chiamare più istanze di una funzione è possibilissimo, basta dargli un nome diverso (altrimenti usa la stessa istanza e può succedere casino).

Io ho una FB che controlla un asse a treno di impulsi con i suoi parametri, e ne metto 4 per controllare 4 assi contemporaneamente senza il minimo problema.

Per passare dati, come in C, gli si passa una struttura (col CJ ed NJ solamente, purtroppo...). L'unica cosa è che devi definire la variabile di scambio della FB come ingresso/uscita (come in C che si passa un puntatore e si varieranno effettivamente i dati della struttura). In questo caso, hai a disposizione tutta la memoria che c'è per tutti i dati. Le memorie interne alla FB servono solo di appoggio. E non sono mai riuscito ad avvicinarmi al loro limite, neppure con programmi pieni di FB...

La gestione multi istanze è trasparente, le FB si programmano facilmente (ST o ladder che sia...) manca solo che si possano usare chiamate al C (che permetterebbe funzionalità migliori).

E anche io se mi dicono che programmare il Siemens è agevole e di "alto livello" (vedi AWL...) lo piglio a schiaffoni... :thumb_yello:

Link al commento
Condividi su altri siti

Chiamare più istanze di una funzione è possibilissimo, basta dargli un nome diverso (altrimenti usa la stessa istanza e può succedere casino).

Sì, certo. Il mio problema era nel poter accedere ai dati interni delle varie istanze.

Per passare dati, come in C, gli si passa una struttura (col CJ ed NJ solamente, purtroppo...). L'unica cosa è che devi definire la variabile di scambio della FB come ingresso/uscita

Quindi, correggimi se sbaglio, ho seguito la strada giusta: nelle variabili IN/OUT ho dichiarato la struttura (creata in "Tipo di dati"), e poi ho passato alla funzione l'indirizzo della prima variabile che desidero venga usata per quella struttura.

Link al commento
Condividi su altri siti

Si, va bene così. Non usi memoria interna, passi solo una struttura. E' comodo. Io infatti sono incazzato con l'Omron che non mi mettono le strutture sui CP1. Come non mi mettono le UNION del C (ci sono per il NJ, ma non proprio uguali...)

Ovviamente scherzavo degli schiaffoni... Io presto dovrò fare la cosa inversa, trasportare delle mie routine da Omron a Siemens...

Link al commento
Condividi su altri siti

Ovviamente scherzavo degli schiaffoni... Io presto dovrò fare la cosa inversa, trasportare delle mie routine da Omron a Siemens...

Anch'io non ucciderò nessuno, ovviamente :smile:

E se avrai bisogno di una mano su Siemens, sai dove trovarmi.

Per ora, grazie dell'aiuto.

Link al commento
Condividi su altri siti

Credevo di aver risolto tutti i miei problemi, invece no.

All'interno di un Blocco Funzione in linguaggio strutturato, devo lavorare con degli array.

Per provare ho creato, in "Tipi di dati", una struttura che contiene due array (ognuno composta da 5 INT), come segue:

MyStruct

- FirstArray

- SecondArray

Nel FB ho dichiarato, nel gruppo Ingresso/Uscita, una variabile "Prova" alla quale ho assegnato come tipo di dati "MyStruct"

Se nel blocco funzione scrivo:

Prova.FirstArray[0] := 0 ;

Il compilatore mi dà 0 errori, zero avvisi.

Se invece scrivo:

Prova.FirstArray[index] := 0 ;

Dove Index è una variabile interna di tipo INT (ma ho provato anche con variabili IN/OUT e di diverso tipo), il compilatore mi dice:

ERRORE: Linea 5: Indice di matrice non valido

Ma se non mi accetta questa sintassi, cosa devo fare per lavorare con array da collegare alla funzione come parametri?

Link al commento
Condividi su altri siti

Provvisoriamente ho risolto dichiarando le variabili dei due array come variabili interne alla funzione, ed indirizzando le DM da usare nel parametro AT.

Nel caso specifico, la funzione mi serve una sola volta, e mi sta bene così (anche se non mi piace molto).

Ma se dovessi richiamare la funzione più volte, utilizzando ogni volta aree di memoria diverse, cosa dovrei fare?

Dovrei fare una copia della funzione e modificare l'indirizzamento nel parametro AT?

Possibile, tornando al post precedente, che se utilizzo le strutture create nei tipi di dati (con la possibilità, quindi, di indicare l'inizio dell'area dati da utilizzare come parametro) non posso, all'interno della funzione, usare un indice per puntare all'elemento desiderato dell'array?

Per essere sicuro di essermi spiegato bene, descrivo un po' l'applicazione che devo fare.

Si tratta di una foratrice, con la quale devo fare cicli di foratura fino a 100 fori.

Ho creato un array di 100 variabili REAL (da D1000 a D1199) con la quota dove effettuare il foro, e un array di 100 variabili INT (da D1200 a D1299) con un codice con informazioni su come eseguire la foratura.

Ad ogni foro incremento l'indice, e la funzione mi deve restituire quota e tipo di foro.

Ora, nella funzione, ho dichiarato come variabili interne un array "QtForo" composto da 100 REAL ed ho indicato nel parametro AT l'indirizzo D1000, e un array "TipoForo" composto da 100 variabili INT a partire da D1200.

Invece io volevo creare una struttura (in Tipi di dati) contenente i due array (quello da 100 REAL e quello da 100 INT).

Poi volevo dichiarare all'interno della funzione una variabile (nel gruppo Ingresso/Uscita) alla quale associare la struttura.

In questo modo, al richiamo della funzione mi bastava linkare D1000.

È esattamente quello che ho fatto per la funzione di posizionamento (vedi post precedenti), nella quale però non avevo array e non utilizzavo indici.

Per gestire un eventuale secondo ciclo basterebbe quindi richiamare un'altra volta la stessa funzione (ovviamente associata ad una nuova istanza), e passare il nuovo indirizzo di inizio area quote e tipo foro.

Come detto sopra, in questo momento devo usare la funzione una sola volta, e mi può anche andare bene così, ma mi pare strano che non ci sia un modo per fare quello che avrei voluto fare.

Link al commento
Condividi su altri siti

Ciao.

L'errore non è nella struttura, ma nel limite del CJ, che non ammette l'uso di una variabile come indice di un array (cosa fattibile nel NJ).

Ho già segnalato tale limitazione della programmazione, ma pare che al momento non venga risolta.

Per fare quel che vuoi fare tu, bisogna che usi i registri indice. Lo fai puntare al primo elemento (indice 0), poi lo incrementi per puntare agli elementi successivi. In pratica, usi un puntatore all'array.

Così facendo, eviti il fatto di avere una struttura ad indirizzamento fisso, rendendo più flessibile il tutto.

Ripeto, è un limite noto degli array nei CJ, segnalatelo anche voi, forse se lo diciamo in parecchi lo sistemeranno (generalmente lo fanno)

Link al commento
Condividi su altri siti

Per fare quel che vuoi fare tu, bisogna che usi i registri indice. Lo fai puntare al primo elemento (indice 0), poi lo incrementi per puntare agli elementi successivi.

Ti ringrazio per la risposta.

Purtroppo, dati i miei limiti nella programmazione dell'Omron, ho capito il concetto ma non ho capito come fare per metterlo in pratica.

Già che ci siamo, approfitto della tua disponibilità e della tua competenza per farti una domanda che non c'entra con l'argomento della discussione: in testo strutturato, come si richiamano le istruzioni (tipo INI, CTBL, TSR per fare un esempio)?

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