Vai al contenuto
PLC Forum


Lettura variabli da nodo ethercat


luca_82

Messaggi consigliati

Ciao  a tutti, stò sviluppando la mia prima applicazione con una Cpu NJ1 e mi trovo di fronte a questa difficoltà...Sulla rete Ethercat ho configurato una scheda di un controllore di un robot che scambia 32 Byte di uscite e 32 byte di ingressi con la Cpu. Ogni byte però è letto dalla Cpu come un parametro USINT  e così memorizzato nella tabella delle variabili.

Io dovrei andare a leggere e scrivere ogni singolo Bit all'interno del mio programma, qualcuno di voi sa dirmi quale è la strada più sbrigativa considerando le funzioni di cui dispone questa CPU?

Ciao e grazie a tutti coloro che possono aiutarmi.

Link al commento
Condividi su altri siti


Bisogna aggirarlo un po', e utilizzare le Union, come nel C.

Generalmente se si assegna un tipo diverso alla variabile di scambio con Ethercat, il sistema si incavola e non compila.

Allora io generalmente faccio così (quando mi serve una variabile che deve essere indirizzata sia al bit che come word, o byte nel tuo caso).

Definisco una Union e la chiamo Pippo (per dire) composta da due elementi, il primo sarà W di tipo BYTE (se gli assegnerai valori in esadecimale 00..FF) o USINT (se glieli assegnerai in decimale 0..255), il secondo sarà b di tipo Array[0..7] OF Bool:

Pippo  UNION

  W    BYTE

  b     ARRAY[0..15] OF BOOL

 

A questo punto, definisci due variabili array di 32 elementi che serviranno per lo scambio dati

scambio1  ARRAY[0..31] OF USINT  %D100

scambio2  ARRAY[0..31] OF Pippo   %D100

La forzatura dell'indirizzo a D100 serve a far si che entrambi gli array puntino alla stessa area di memoria, altrimenti il trucco non funziona.

 

Imposti che l'EtherCat utilizzi l'array scambio1, ma nel tuo programma userai lo scambio2.

 

Se quindi vorrai alzare il bit 3 del byte 4, farai

scambio2[4].b[3] := TRUE;

e se vorrai leggere il valore del byte 6, farai

asd := scambio2[6].W

 

Spero di essere stato chiaro...

Link al commento
Condividi su altri siti

Ciao Ctec, scusami ma ci sono dei punti che non mi sono molto chiari....Le variabili che devo definire per lo scambio dati scambio1 e scambio2 le devo definire nelle variabili globali? Poi un altra domanda è, qual'è il significato della scrittura %D100 nella postazione Sysmac?

nell'interfaccia del nodo Ethercat ho 32 USINT di ingressi e 32 di uscite a cui ho dato un nome, premesso che li ho chiamati BYTE1_I.....BYTE32_I per gli ingressi e BYTE1_O...BYTE32_O per le uscite dove dovrei andare a scrivere le variabili con questi nomi, allinterno della Union o nelle variabili globali?

Io ho pensato di aggirare il problema in questa maniera ma ti chiedo conferma del fatto che possa funzionare...Ho creato due strutture sotto la voce "Tipi dati"-"Strutture" in cui su una metto gli ingressi e sull'altra le uscite.

STRUCT

Nome

Ingressi_Kawa_a_bit

Byte1_I array (0..7) of bool

Byte2_I array(0..7) of bool

--

Byte32_I array(0..7) of bool

Nelle variabili globali ho creato una variabile con il "nome" Ingressi Kawa e la voce "Tipo dati" Ingressi_Kawa_a_bit. A questo punto se voglio leggere da programma lo stato del Bit 0 del primo Byte di scambio dati scrivo sul contatto N.O. :

Ingressi_Kawa.byte1_I[0]

Così credi possa funzionare ugualmente?

Purtroppo sono abituato a lavorare con Software che facilitano molto di più la gestione delle variabili e delle aree di memoria e devo dire che con questo se non si ha un pò di esperienza si fa poca strada...Mia culpa nell'averlo scelto!!

Grazie mille!!

Link al commento
Condividi su altri siti

Si, le devi definire globali.

Se vedi la tabella delle variabili globali, c'è un campo denominato AT. Serve a definire un indirizzo fisico di una variabile.

Gli ingressi/uscite o variabili che sono utilizzate da unità mappate direttamente (moduli I/O fisici connessi al PLC, unità remote in rete EtherCat con mappatura al bit, ecc) con denominazioni tipo ECAT://node#.... 

Puoi anche assegnare te un indirizzo fisico alla tua variabile globale, mettendo in tale campo un indirizzo fisico tipico Omron (D, W, H, ecc) preceduto da %.

Quindi con quel %D100 imponi che il software assegni alla memoria D100 la variabile (o le variabili). E' come nel C.

Questo è utilissimo anche quando hai necessità di collegarci un display che funziona con i vari Cx di Omron, che hanno mappature fisse, per poter accedere alle variabili.

Le Union (derivate dal C) servono a definire due modi diversi di accedere a una variabile, nel nostro caso come singolo bit o come byte.

Le strutture invece sono insiemi eterogenei di tipi di dati (contrariamente agli array), ma alla variabile si può essere accedere solo in un modo, definito nella Struct.

Poi devi stare anche attento all'allineamento dei dati nella struttura. Se alla tua struttura dai come tipo di offset NJ, mi pare che ogni variabile occupa almeno 32bit (4byte), e se metti tipo di offset CJ, occupa almeno 16bit (2byte), il che rende inutilizzabile la tua struttura perché i bytes ricevuti sono contigui e quindi il tuo Byte2_I punterà non al secondo byte ma al terzo o al quinto di quelli ricevuti.

Non bastasse, non puoi assegnare una struttura o un suo elemento definito array of bool a una variabile SINT...

Per me l'unico sistema è quello delle Union. 

 

 

Link al commento
Condividi su altri siti

Ok mi sembra di aver capito che l'unica soluzione è quella della Union..Quindi se ho capito bene %D100 è un area di memoria della Cpu in cui i dati che vengono dal nodo Ethercat ci vengono scritti e questo lo fa il sistema nel momento in cui io imposto che l'Ethercat (poi in seguito cercherò di capire come fare) utilizza l'array Scambio1, e nello stesso momento creo un area di memoria, array scambio2, che punta sulla stessa posizione ed io vado a trattare come Union e quindi mi permette di scegliere se accedere come Byte o come Bit al singolo valore dell'Array sul programma.......

Nell'esempio che tu hai fatto nelle variabili globali hai messo un array di 0...32 of USINT, ma visto che io sul nodo ho 32 byte di ingressi e 32 byte di uscite a qual punto presuppongo se ho capito bene che diventi così che devo scrivere:

scambio1  ARRAY[0..63] OF USINT  %D100

scambio2  ARRAY[0..63] OF Pippo   %D100

scusami se ti faccio perdere un pò di tempo ma non vorrei trovarmi nella condizione di aver scritto un intero programma e dover ricominciare da capo...!!

Grazie ancora.

Link al commento
Condividi su altri siti

Scusami Andrea sempre in riferimento all'esempio che mi hai fatto tu, scrivendo così vado a leggere lo stato del Byte:

Valore del byte 6

asd := scambio2[6].W

E se invece dovessi leggere il bit 3 all'interno del Byte 6 come dovrei scrivere?

Ciao e grazie ancora.

 

Link al commento
Condividi su altri siti

Per non correre rischi sul funzionamento, prova passo passo le soluzioni. Usa il simulatore o meglio il PLC anche solo per vedere se il compilatore fa quel che tu vuoi ottenere.

Il fatto di usare array di USINT dipende da come son gestite le variabili in scambio con il robot. Potrebbe essere che non puoi usare un array ma 32 (64) variabili globali separate.

Non è facile da spiegare, bisogna provare...

Per la seconda domanda, scriverai

bit_letto := scambio2[5].b[3]

Perché ho scritto [5] e non [6]? Perché il byte 6 in ingresso è il byte 5 dell'array, dato che questi iniziano sempre con l'elemento [0]...

Stesso discorso per i bit. Se invece del bit 3 intendevi il terzo bit, allora dovrà essere .b[2]

Link al commento
Condividi su altri siti

Scusa ma se deve leggere un bit di un byte di un array che gli invia il robot....avrà configurato nella I/O ma le aree di scambio.

 

Io faccio così, dove READ_CMM è appunto un array di byte dove voglio leggere il bit zero del byte zero

 

SCON_ENABLE := TestABit(READ_CMM[0],USINT#0) ;

Link al commento
Condividi su altri siti

Vero, ma siccome la deformazione alla mia veneranda età è impressionante, mi viene naturale associare funzionalità del C, da cui le Union...

A parer mio viene un codice più elegante (e anche più compatto).

Poi ovviamente esistono parecchi sistemi diversi per ottenere i vari risultati. Io ho solo illustrato il mio, e son contento che anche altri (te) abbiano risposto proponendo altre soluzioni.

Link al commento
Condividi su altri siti

Veneranda età?   mi sa che son più vecchio io :superlol:

 

Se invece di dover leggere un bit di uno dei bytes di stato si volesse scrivere un bit di un byte dei bytes di comando?

 

Ammettendo che il bit si chiamasse CCON_ENABLE  e che volessi scrivere il bit zero di WRITE_CMM[0] io farei così:

 

OutABit(WRITE_CMM[0],USINT#0,CCON_ENABLE); 

 

Questo a mio avviso  è il metodo più semplice perchè

non dichiaro nessuna union

sfrutto quello che ho

 

Comunque....una complicazione assurda per leggere o scrivere un bit di un byte di un array :thumbdown:

 

Come sarebbe bello se fosse così:

 

SCON_ENABLE := READ_CMM[0].BIT 0 ;

WRITE_CMM[0].BIT 0:=CCON_ENABLE;

 

ma così non è :senzasperanza:

 

 

 

 

 

 

 

 

 

 

 

Link al commento
Condividi su altri siti

Non mi rimane che dedicarmici un po' e fare delle prove come ha detto Andrea!!

In ogni caso rispondendo a Cicala il robot da 32 USINT in ingresso e 32 in uscita ma non sono messi in un array quindi non so se tale funzione sia poi valida....

Premesso che avendo anche il robot e collegandomi sarebbe la soluzione migliore, il simulatore Sysmac mi permetterebbe di alzare simulandoli i singoli bit dei vari dati USINT?

Link al commento
Condividi su altri siti

Caro Stefano, sono d'accordissimo sulla complicazione.

Hanno voluto fare una specie di gestione dati simile al C ma non troppo, per cui si sono incartati.

Poi il fatto di non avere il casting dei dati in automatico (vedi C) mi fa incavolare a bestia.

Non amo molto il sysmac studio, ma ci si deve adattare... 

Link al commento
Condividi su altri siti

eh già....dover ricorrere ad artifici come questo

 

USINT_TO_BYTE

 

è deprimente

 

 

Si potrebbe scrivere il Bestiario di Sysmac Studio :toobad:

 

 

Link al commento
Condividi su altri siti

//**************************************************
// Nr							USINT
// VarBOOL				BOOL
// VarUSINT				USINT
// VarBYTE				BYTE
//**************************************************

Nr:=USINT#0; 

VarBOOL:=TestABit((USINT_TO_BYTE(VarUSINT)),Nr) ; // Read bit specified by Nr

VarBYTE:=(USINT_TO_BYTE(VarUSINT));

OutABit(VarBYTE,Nr,VarBOOL); // Write bit specified by Nr with VarBOOL value

:roflmao:

Link al commento
Condividi su altri siti

Certo visti i commenti non si può sire che ho fatto la scelta giusta nel lavorare con questa postazione,tutto pensavo meno che fosse così contorto solo leggere e scrivere lo stato dei segnali di una periferica....Probabilmente ero abituato a programmi troppo facili,chr a loro volta non ti obbligano  ragionare troppo!!

Link al commento
Condividi su altri siti

Il linguaggio strutturato aiuta molto in queste cose,ma certo che dover convertire un USINT in byte per andare a leggere il singolo bit non è il massimo....Anche perché per non farlo per ogni singolo dato USINT pensavo di farlo con un ciclo For ed appoggiare ogni singolo dato USINT su un componente di un array di byte,sempre che sia possibile!!

Così con un ciclo For avrei convertiti tutti i dati USINT dell' interfaccia!!

Link al commento
Condividi su altri siti

Curiosità: ma che linguaggio usi di solito?

Il linguaggio strutturato è normalizzato, per cui tutte le implementazioni hanno una base uguale, indipendente dalla marca e dal PLC.

Link al commento
Condividi su altri siti

Di solito programmo Siemens,per le cose più semplici uso il Ladder,qualcosa ho scritto in AWL,mentre in SCL che è pressoché identico all'ST della Omron ho scritto veramente dieci righe di conto!!

Ma gestisce le variabili in maniera completamente diversa e non ho mai avuto questi problemi. In questo caso dovevo implementare una visione Omron ed ho pensato che fare tutto con la piattaforma sysmax mi avrebbe semplificato la vita,ma direi che non è proprio così!!

Link al commento
Condividi su altri siti

Programmi facili o meno, io trovo patetico dover convertire un dato ad 8 bit in un altro a 8 bit per poterlo leggere.

Sysmac studio fa veramente pena.

 

In ogni caso, più sopra hai l'esempio di come leggere e scrivere. L'indice è appunto appoggiato ad una variabile, da lì al ciclo di for il passo è breve.

 

VarBOOL ora è un array di bool

 

FOR Nr:=0 TO 7 DO

VarBOOL[Nr]:=TestABit((USINT_TO_BYTE(VarUSINT)),Nr) ; // Actuator Enabled

END_FOR;

 

 

Scl sembra identico, ma quello che fai con scl su Siemens, su questo catenaccio puoi solo sognarlo....se poi si fa il confronto solo con simatic manager e wincc ormai obsoleti...safety distribuited, profisafe ecc ecc........omron deve correre almeno per altri 15 anni.

Link al commento
Condividi su altri siti

Non volevo essere drastico e dare giudizi affrettati visto che lo conosco poco,ma più ci lavoro e più concordo con il fatto che il Sysmac non è un granché....comunque,andiamo avanti!!

Grazie a tutti per i vostri pareri!!

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