Jump to content
PLC Forum


Recommended Posts

Cancer777

Ciao a tutti,

 

qualcuno ha già utilizzato la funzione Swap con Schneider? ( In dettaglio con ambiente di sviluppo E.S.M.E o SoMachine Motion)

purtroppo l'. schneider su questa funzione non è molto chiara se non per dire quasi assente…!

 

Nello specifico il mio problema è il seguente:

 

Leggo dei valori derivanti da un convertitore Modbus/EthIP esterno sottoforma di BYTE, devo elaborare questo BYTE andando a riordinarlo dal bit meno significativo a quello più significativo.

 

Spero di aver esposto il mio problema nel modo più chiaro possibile

 

Vi ringrazio anticipatamente per l'aiuto che potrete darmi

Share this post


Link to post
Share on other sites

Mattia Musu

Ciao,

 

Se non sbaglio SoMachine Motion dovrebbe essere su piattaforma codesys; per cui potresti semplicemente usare le istruzioni SHL e SHR. 

Sostanzialmente è una funzione a cui gli passi una variabile in ingresso e gli indichi quanti bit shiftare a destra (SHR) o sinistra (SHL).

Ti allego un immagine presa dalla documentazione relativa al tuo ambiente.

 

image.thumb.png.99d9daf38b4c9708d946e81f9c333579.png

 

Spero di essere stato utile. 

Share this post


Link to post
Share on other sites
batta

Scusate se mi intrometto, pur non conoscendo Schneider, ma mi pare impossibile che non ci sia un'istruzione swap.

In ogni caso, lo shift non va bene, perché i bit spostati a sinistra oltre il 16° bit, e quelli spostati a destra oltre il 1° bit vengono persi.

Casomai, servirebbe un'istruzione di rotazione.

Con una rotazione di 8 bit, in una variabile da 16 bit, di fatto vengono scambiati i due byte.
Nel caso di una variabile a 32 bit però non andrebbe più bene, perché si dovrebbero scambiare tra loro il byte 0 con il byte 3, e il byte 1 con il byte 2.
Si potrebbe fare una cosa simile:

#myDWord_out.%B0 := #myDWord_in.%B3;
#myDWord_out.%B1 := #myDWord_in.%B2;
#myDWord_out.%B2 := #myDWord_in.%B1;
#myDWord_out.%B3 := #myDWord_in.%B0;

Però, ripeto: mi risulta difficile credere che non ci sia l'istruzione SWAP.

Share this post


Link to post
Share on other sites
Mattia Musu

Buongiorno Batta, 

E' vero la rotazione è anche una soluzione valida, ma come hai detto tu per dati oltre i 16 bit non può andare bene.

Questo mondo è bello anche perché si possono trovare molteplici soluzioni a un problema. 

 

Lo shift può andare bene se usato con intelligenza, ad esempio:

 

DATA TYPE - WORD

Trasformiamo il dato in un array in DataInputWord[0..1] of BYTE,

 

poi shiftiamo i singoli byte

 

_TmpWord := SHL(DataInputWord[0],8) OR DataInputWord[1];

 

questo ti permette di swappare i due byte della word. 

 

DATA TYPE - DWORD 

 

Trasformiamo il dato in un array in DataInputDWord[0..3] of BYTE,

 

poi shiftiamo i singoli byte

 

_TmpDword := SHL(SHL(SHL(DataInputDWord[0],8) OR DataInputDWord[1],8) OR DataInputDWord[2],8) OR DataInputDWord[3];

 

Questo workaround lo uso spesso e lo trovo molto comodo. Ad ognuno il suo metodo! 🙂

 

 

Ad ogni modo le funzioni di swap, almeno su codesys, esistono ma serve scaricare delle librerie da importare nel progetto.

 

Ciao!

 

Share this post


Link to post
Share on other sites
batta
10 ore fa, Mattia Musu ha scritto:

Lo shift può andare bene se usato con intelligenza, ad esempio:

Non è più semplice così?

#myDWord_out.%B0 := #myDWord_in.%B1;
#myDWord_out.%B1 := #myDWord_in.%B0;

E comunque insisto sul fatto che credo che in codesys la funzione swap ci sia.

Share this post


Link to post
Share on other sites
Mattia Musu

Dichiarando una variabile di tipo WORD non hai l'accesso ai singoli BYTE ma solo ai singoli bit, in codesys.

 

image.png.fffb6a43e467c4f33603df20bae89781.png

 

Perciò bisogna comunque convertire la word in un array di byte e poi, come giustamente suggerisci tu, swappare i byte nella mappatura dati di uscita. 

Come ho detto ci sono molteplici modi per farlo. Per chiarezza di codice all'interno di una funzione che mi restituisce un dato pulito, io preferisco usare il metodo suggerito in precedenza.

 

Ad ogni modo, ho anche detto che, all'interno del repository librerie, si può importare sicuramente una libreria che esegue tali conversioni di dati. Ho appena fatto una ricerca e forse nel  caso di Cancer777 potrebbe andare bene la seguente: 

 

image.thumb.png.34b343ce1cb3d506304159245e1e1d49.png

 

la quale contiene alcune function Block per lo swap delle word e dword.

Di seguito il link della documentazione relativa: https://www.overdigit.com/data/Products/Target-CoDeSys-Reference-Manual_EN.pdf

 

Buon weekend! 🙂

 

 

Share this post


Link to post
Share on other sites
batta
54 minuti fa, Mattia Musu ha scritto:

Dichiarando una variabile di tipo WORD non hai l'accesso ai singoli BYTE ma solo ai singoli bit, in codesys.

Io non conosco codesys. Rimango un po' basito nell'apprendere che non permette di accedere al byte di una word, e che non ha un'istruzione swap, se non importando librerie.
Certo, ci vuole poco per crearsi una funzione ma, per me, l'istruzione SWAP, in operazioni a parole, è come un AND o un OR. Come può mancare?
Ma come, codesys viene spesso spacciato per il non plus ultra per la programmazione dei plc, e non permette operazioni così elementari?
Persino con il testo strutturato di Siemens (spesso accusata di essere scarna di istruzioni e funzioni) l'accesso al byte è consentito, ed esiste l'istruzione swap.

 

Chiedo scusa, io sono nella sezione sbagliata, e la mia non vuole essere una critica a codesys o a SoMachine, o un'entrata a gamba tesa, ma apprendere quanto sopra mi ha sorpreso non poco.

Edited by batta

Share this post


Link to post
Share on other sites
zanellatofabio

Ciao a tutti,

le cose dette da Batta sono sostanzialmente tutte giuste al 100%. Purtroppo in codesys non si può scrivere miaWord.%B0 in quanto accetta solo di "puntare a bit" e si scrive senza il %.

Usando un ROL di 8 posizioni si scambiano i byte di una word.

Per una dword bisogna usare altre soluzioni.

 

Ma restando al primo post l'utente chiedeva

Il 16/3/2020 alle 08:57 , Cancer777 ha scritto:

devo elaborare questo BYTE andando a riordinarlo dal bit meno significativo a quello più significativo.

Io così capisco che voleva scambiare i bit all'interno del byte anche se mi sembra molto strano.

Siccome parla di modbus allora si leggono i registri che sono word quindi sarebbe utile che spiegasse da dove saltano fuori i byte.

Sarebbe poi utile che indicasse anche il modello del plc che usa.

Purtroppo codesys varia da target a target e poi meglio non chiamare in causa le librerie di altri target perche non sono utilizzabili per altri.

Il 21/3/2020 alle 15:39 , Mattia Musu ha scritto:

a quale contiene alcune function Block per lo swap delle word e dword.

Di seguito il link della documentazione relativa: https://www.overdigit.com/data/Products/Target-CoDeSys-Reference-Manual_EN.pdf

Overdigit mi sembra poi che sia codesys 2.3 mentre per schneider parliamo di codesys 3.5 e i due ambienti hanno ben poco da spartire.

Edited by zanellatofabio

Share this post


Link to post
Share on other sites
zanellatofabio

Per completezza elenco anche la libreria CAA_memory ( standard dentro a codesys 3.5 ) per lo swap

libreria.png.e5f40782e8801acfbb598aa0ec14dc0e.png

 

swap di byte in una word

swapbyte.thumb.png.9f74e88325e9cba31bc08005e0ef1dd7.png

 

swap di byte in una dword

swapdw.thumb.png.1a0b37291b34866c12884f7485317570.png

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...