Vai al contenuto
PLC Forum


GATHER_BLK e swap di byte


Cesare Nicola

Messaggi consigliati

Cesare Nicola

Ho scoperto, casualmente, un comportamento che non capisco dell’istruzione GATHER_BLK (o di non so cos'altro). Questa è la parte di programma "incriminata".
image.thumb.png.e106b5b7eeb5f7cb39fd771d4369ef91.png

 

"DB_LINE_Alarms".Alarm è un array di 160 BOOL e ogni elemento è un allarme. GATHER_BLK  copia il contenuto dell’array di BOOL in un array temporaneo di 10 WORD (sezione TEMP nell'interfaccia del blocco). Per poi trasferire gli allarmi all’HMI, sono previste 10 word di appoggio "DB_LINE_Alarms".Alarm_word_HMI_xx. Come vedete, viene usato un MOVE dall’array di word temporaneo alle word di appoggio per HMI. Normalmente, o qui nel blocco o in HMI, servirebbe swappare i byte, invece in questo caso non sono swappati e tutto funziona correttamente. Cioè, se va ad 1 il primo elemento dell'array di BOOL (allarme 1), su HMI vedo allarme 1, che corrisponde al bit 0 della prima word di appoggio, e via di seguito.

image.thumb.png.002acb9877138ef3ba8c1e65b1d7c4e4.png


La DB_LINE_Alarms è ottimizzata e a numerazione automatica ed è questa la differenza rispetto a come faccio di solito, senza GATHER_BLK. Con DB non ottimizzata e numerata manualmente, di solito faccio così, swappo i byte prima di inviarli all'HMI:

 

image.png.a47026f2ee516c34b34e79b44000f5c2.png

 

Non capisco, mi sfugge qualcosa. Se funziona sempre correttamente ciò che ho scoperto, è un sistema che preferisco perché tengo la DB ottimizzata e a numerazione manuale, che sono le impostazioni di default e mi dimentico dello swap, sia nel PLC sia in HMI. Il dubbio è che, con la DB è ottimizzata, la CPU faccia qualcosa che non so, non sempre ripetitivo, ai byte delle word di appoggio per HMI: non credo, ma non so.
 

Link al commento
Condividi su altri siti


ifachsoftware

Ciao , ha dato un'occhiata alla mia risposta in questa discussione ? Discussione

Probabilmente con l'uso di db non ottimizzate prende i dati nella sequenza di bit già corretta.

Ci darò un'occhiata per vedere se anche con la mia soluzione potro' fare a meno di fare lo swap dei bytes

Considera che la mia soluzione è molto più semplice rispetto a questa

Modificato: da ifachsoftware
Link al commento
Condividi su altri siti

Cesare Nicola
12 minuti fa, ifachsoftware ha scritto:

ha dato un'occhiata alla mia risposta in questa discussione

Sì, l'avevo vista ma non avevo mai avuto tempo di approfondire, scusa se non ti ho mai risposto. Sembra interessante in effetti. Se riesco, visto che sono a casa a guardare i bambini che non vanno a scuola causa virus, ci do' un'occhiata subito. 😄 Perché poi tra un'ora torno al lavoro e... fine del tempo per esperimenti!😄

Link al commento
Condividi su altri siti

ifachsoftware

Figurati , ora non ho tempo di provarla neppure io , pero' mi hai messo la pulce nell'orecchio per semplificarla ulteriormente (se posso evitare lo swap sarebbe una bella semplificazione anche per ridurre il tempo di esecuzione).

La mia soluzione l'ho già testata e funziona perfettamente.

Rispetto alla tua si ha il vantaggio di avere i nomi dei bit parlanti , e questo non è poco per migliorare la leggibilità del codice.

 

Link al commento
Condividi su altri siti

Cesare Nicola
1 minuto fa, ifachsoftware ha scritto:

Rispetto alla tua si ha il vantaggio di avere i nomi dei bit parlanti , e questo non è poco per migliorare la leggibilità del codice.

Più o meno anche la mia ha bit parlanti. L'array di BOOL si chiama Allarme, quindi gli elementi saranno Allarme[1], Allarme[2], ecc. Nel programma, poi, ogni segmento è dedicato ad un allarme ed il titolo del segmento è il testo dell'allarme che scriverò in HMI (a volte magari un po' abbreviato, ma poco). 

image.png.4f0abc529aa123f208db0c64be124dd0.png

 

Quindi in HMI l'allarme 1 corrisponderà al bit Allarme[1] nel PLC e via di seguito. Preferisco così perché non devo compilare l'UDT coi nomi parlanti, ad ogni software: mi porto dietro la mia DB allarmi così com'è ed è già a posto. Questione di gusti. 🙂

Link al commento
Condividi su altri siti

2 ore fa, Cesare Nicola ha scritto:

Il dubbio è che, con la DB è ottimizzata, la CPU faccia qualcosa che non so

Per quanto riguarda l'ordinamento dei byte non c'è nessuna differenza tra DB ottimizzata e non ottimizzata.

Tutto sta, semplicemente, in come operano le istruzioni Gather e Scatter.
Per esempio, per poter accedere ad una variabile sia al singolo bit che all'intera variabile, si possono usare le istruzioni Gather e Scatter, oppure la sovrapposizione con AT.

Le due soluzioni danno risultato con byte scambiati, indipendentemente dal fatto che si operi con variabili ottimizzate o non ottimizzate.

Link al commento
Condividi su altri siti

Cesare Nicola
1 ora fa, batta ha scritto:

Le due soluzioni danno risultato con byte scambiati,

Quindi mi stai confermando che GATHER_BLK scambia i byte già di suo?

Link al commento
Condividi su altri siti

ifachsoftware

Con le DB ottimizzate sembra prendere l'ordine nella sequnza con cui sono inserite.

Nel tuo esempio , l'allarme si chiama DB_LINE_Alarms.Alars[2] , non dubito che nella gestine dell'allarme sia commentata , peccato che se devo utilizzata in giro per il programma non vedrei subito il nome dell'allarme , ma dovrei guardare il commento (se lo ho inserito).

Naturalmente nel mio caso devo compilare un'UDT ....

 

Modificato: da ifachsoftware
Link al commento
Condividi su altri siti

Cesare Nicola
6 minuti fa, ifachsoftware ha scritto:

peccato che se devo utilizzata in giro per il programma non vedrei subito il nome dell'allarme

Sì, è vero. Io non uso il bit Allarme[x] in giro per il programma, è solo in quel segmento: è vero però che in giro nel programma uso il bit che ha scatenato quell'allarme e in quel caso lo rendo "parlante", cioè si chiama, che ne so, "Allarme_max_pressione". Tanto vale usare il bit di allarme parlante, dirai tu, allora: certo, hai ragione, questione di gusti, dicevo.

9 minuti fa, ifachsoftware ha scritto:

ma dovrei guardare il commento (se lo ho inserito).

Qui non c'è alternativa: il commento DEVI  averlo inserito, pena fustigazione sulla piazza pubblica!😄 

Link al commento
Condividi su altri siti

ifachsoftware
Quote

Tanto vale usare il bit di allarme parlante, dirai tu, allora: certo, hai ragione, questione di gusti, dicevo.

 

Il bit dell'allarme in genere è ritentivo , e permette di eseguire delle azioni solo se è stato resettato l'allarme.

Link al commento
Condividi su altri siti

2 ore fa, Cesare Nicola ha scritto:

Quindi mi stai confermando che GATHER_BLK scambia i byte già di suo?

Non è che scambi i byte, semplicemente, con Gather e Scatter, il primo bit della struttura (o dell'array) viene messo nel bit a destra della variabile.
Se, invece, usi la sovrapposizione con AT, o indirizzamenti "vecchia maniera", si devono fare i conti con lo standard usato da Siemens, con i byte ordinati da sinistra verso destra.

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