Water Inserito: 22 febbraio Segnala Share Inserito: 22 febbraio Buongiorno, ho inserito in quadro elettrico un misuratore di energia interfacciabile via Modbus RTU, le variabili restituite sono tante ma a me ne servono solo tre o quattro, il dispositivo funziona e da display i valori sono corretti ma via Modbus diventano per me incomprensibili, ho scoperto che i dati restituiti si appoggiano su due word ma è in formato Real (Float) e con i bit invertiti (endianness), non mi sono mai trovato in questa situazione ma che probabilmente è uno standard per questi dispositi, grazie a chiunque mi dia qualche idea Link al commento Condividi su altri siti More sharing options...
drn5 Inserita: 22 febbraio Segnala Share Inserita: 22 febbraio Se sei certo di questa cosa direi di trattali a byte e girali nell'ordine in cui ti servono dopodichè li leggi normalmente. Link al commento Condividi su altri siti More sharing options...
Lucky67 Inserita: 22 febbraio Segnala Share Inserita: 22 febbraio Anche io ho avuto la stessa situazione e weintek ha la possibilità di convertire il dato in floating point girando byte o word....Penso che anche shneider non abbia problemi a farlo.. Link al commento Condividi su altri siti More sharing options...
Water Inserita: 23 febbraio Autore Segnala Share Inserita: 23 febbraio sicuramente c'è qualcosa di semplce che mi sfugge .. come al solito! attualmente ho provato cosi: - prendo i due registri Modbus in arrivo e li assemblo tramite il blocco WORD_AS_DWORD (Toolkit) - inverto i bit tramite il blocco ROL (n=31) - trasformo il dato in REAL ma anche invertentendo gli ingressi del blocco WORD_AS_DWORD il risultato non è corretto, sto provando a leggere semplicemente la tensione che è un dato certo: 230 o 400V Link al commento Condividi su altri siti More sharing options...
84paolo Inserita: 23 febbraio Segnala Share Inserita: 23 febbraio secondo me non devi invertire i bit, ma devi scambiare i byte a due a due e se necessario alla fine scambi anche le word ottenute Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 23 febbraio Segnala Share Inserita: 23 febbraio 14 minuti fa, Water ha scritto: - prendo i due registri Modbus in arrivo e li assemblo tramite il blocco WORD_AS_DWORD (Toolkit) - inverto i bit tramite il blocco ROL (n=31) - trasformo il dato in REAL ma anche invertentendo gli ingressi del blocco WORD_AS_DWORD il risultato non è corretto, Il tuo problema è probabilmente legato al fatto che hai da 'girare' anche l'ordine dei byte ... Il modbus ragiona in registri a 16 bits (WORD) quindi a seconda del endianness puoi ricevere byte alto/byte basso oppure il contrario. Quando hai a che fare con variabili che sono composte da registri doppi (caso tipo il DINT oppure il REAL) puoi avere anche in questo caso l'inversione del registro altro con quello basso (oltre ovviamente all'inversione del byte alto con quello basso). Link al commento Condividi su altri siti More sharing options...
NoNickName Inserita: 23 febbraio Segnala Share Inserita: 23 febbraio Può anche essere, come dice max, che non vadano invertiti i byte (se normalmente i registri a 16 bit li decodifichi correttamente), ma le word. Dunque i byte 1234 vanno interpretati 3412 Link al commento Condividi su altri siti More sharing options...
Water Inserita: 23 febbraio Autore Segnala Share Inserita: 23 febbraio grazie degli input! come detto avevo già provato ad invertire le word e poi i bit della dword generata ma niente, non ho provato però ad invertire prima i bit delle word per poi assemblarle in una dword "invertita", mah .. proverò anche questa, se trovo la sopluzione la posto! grazie Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 23 febbraio Segnala Share Inserita: 23 febbraio 1 ora fa, Water ha scritto: non ho provato però ad invertire prima i bit delle word ... Non i bit (anche se tecnicamente lo sono) ma i bytes (quello basso con quello alto). P.S. Ogni manuale che sia decentemente scritto oltre ad indicare il significato dei registri indica anche come questi vengono trasmessi (al peggio indicano se si tratta di CPU Motorola o Intel). In generale, posto che i bytes di 2 registri (WORD) consecutivi che debbano essere interpretati come DINT o come REAL siano indicati come A,B,C,D puoi avere le seguenti combinazioni : - A,B,C,D - B,A,D,C - C,D,A,B - D,C,B,A Esempio di Word (composta da A - Byte meno significativo, B - Byte più significativo, ricevuti come B,A) to Byte : ByteH= Word AND 16#FF00 #Mascheratura del byte meno significativo ByteH=RSH(ByteL,8) #Shift di 8 bit a destra ByteL = Word AND 16#00FF #Mascheratura del byte più significato Swap della Word : NewWord = LSH(ByteL) OR ByteH # Potrebbe/Dovrebbe essere necessario trasformare i Byte in WORD prima di ricostruire la Word Forse esiste già una funzione che fa il mestiere di inversione dei bytes all'interno di una word (e se esistesse potrebbe chiamarsi SWAP_qualcosa) : verifica nell'. del PLC che stai usando .... Link al commento Condividi su altri siti More sharing options...
Water Inserita: 24 febbraio Autore Segnala Share Inserita: 24 febbraio grazie Max della esauriente risposta! hai ragiorne e lo avevi detto anche nel precedente post ma chissà perchè mi sono interstardito con i bit 😬 so di certo che il dato è in formato REAL usando due registri con endness invertito, il manuale non lo dice o comunque non ne ho trovato traccia (Eastron SDM630MCT) , in Codesys non c'è il blocco SWAP e puoi girare solo i bit con il blocco ROL, ma so che c'è qualcosa nelle librerie di OSCAT, in ogni caso ti ringrazio e ci provo! Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 24 febbraio Segnala Share Inserita: 24 febbraio 1 ora fa, Water ha scritto: in Codesys non c'è il blocco SWAP e puoi girare solo i bit con il blocco ROL, ma so che c'è qualcosa nelle librerie di OSCAT, Scusa la 'tignoseria' ma continui ad insistere che devi girare i bit (e il pensare di utilizzare la funzione ROL lo dimostra) : tu devi girare i bytes (prendi spunto dallo 'pseudo codice' che ti ho scritto, che salvo errori di sintassi è quello che utilizzo su M340). Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 24 febbraio Segnala Share Inserita: 24 febbraio 1 ora fa, Water ha scritto: in Codesys non c'è il blocco SWAP ... Non uso codesys, qundi non posso confermare la validità del risultato, ma cercando 'codesys swap word' ottengo : VAR Test1:WORD; Test2:Word; END_VAR Test2:=MEM.ReverseBYTEsInWORD(Test1); Altra soluzione (credo utilizzando oscat) in questo caso per fare lo swap di 2 word all'interno di una dword : FUNCTION SWAP_WORD : DWORD VAR_INPUT IN : DWORD; END_VAR SWAP_WORD := ROL(IN, 16); Probabilmente, in codesys (forse tramite oscat), lo swap dei bytes all'interno di una word si ottiene semplicemente con ROL(IN,8) ... Ciao Link al commento Condividi su altri siti More sharing options...
Lucky67 Inserita: 24 febbraio Segnala Share Inserita: 24 febbraio 4 ore fa, Water ha scritto: (Eastron SDM630MCT Proprio quel contatore. Devi convertire, come ha giustamente detto max.riservo, ABCD con CDAB. Se il tuo pannello non lo fa in automatico come lo fa Weintek, devi farti uno script per farglielo fare. Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 24 febbraio Segnala Share Inserita: 24 febbraio 5 ore fa, max.riservo ha scritto: ... tu devi girare i bytes (prendi spunto dallo 'pseudo codice' che ti ho scritto, che salvo errori di sintassi è quello che utilizzo su M340). Alla fine direi che posso evolvere anche io evitando quello che faccio da 35 anni ... Per fare lo swap dei bytes di una word basta semplicemente un ROL(word,8) oppure un ROR(word,8). Link al commento Condividi su altri siti More sharing options...
Water Inserita: 24 febbraio Autore Segnala Share Inserita: 24 febbraio 6 ore fa, max.riservo ha scritto: Scusa la 'tignoseria' ma continui ad insistere che devi girare i bit (e il pensare di utilizzare la funzione ROL lo dimostra) : tu devi girare i bytes (prendi spunto dallo 'pseudo codice' che ti ho scritto, che salvo errori di sintassi è quello che utilizzo su M340). hai ragione ma mi ero espresso male .. perchè intendevo mi ero erroneamente interstardito con i bit! 😀 ma soprattutto grazie anche a quello che hai postato successivamente 👍👍👍 2 ore fa, Lucky67 ha scritto: Proprio quel contatore. Devi convertire, come ha giustamente detto max.riservo, ABCD con CDAB. Se il tuo pannello non lo fa in automatico come lo fa Weintek, devi farti uno script per farglielo fare. vedo che lo conosci .. grazie della conferma Lucky!! Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 24 febbraio Segnala Share Inserita: 24 febbraio 2 minuti fa, Water ha scritto: ma soprattutto grazie anche a quello che hai postato successivamente 👍👍👍 Di nulla. Quindi hai risolto con un semplice ROL(word,8) ? Link al commento Condividi su altri siti More sharing options...
Water Inserita: 25 febbraio Autore Segnala Share Inserita: 25 febbraio 13 ore fa, max.riservo ha scritto: Di nulla. Quindi hai risolto con un semplice ROL(word,8) ? no Max non ancora perchè devo testarla sul campo con i valori che vengono dal misuratore, ma sicuramente ora ho la chiave per farlo e appena riesco posterò la soluzione, interessante la tua semplificazione tramite ROL di traslare solo 8 bit della word, 👍 Link al commento Condividi su altri siti More sharing options...
Lucky67 Inserita: 25 febbraio Segnala Share Inserita: 25 febbraio Il 24/2/2024 alle 17:23 , max.riservo ha scritto: Alla fine direi che posso evolvere anche io evitando quello che faccio da 35 anni ... Per fare lo swap dei bytes di una word basta semplicemente un ROL(word,8) oppure un ROR(word,8). Essendo un numero in virgola mobile non sono così sicuro che shiftando i bit si abbia un dato congruo....così a naso è... Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 26 febbraio Segnala Share Inserita: 26 febbraio 11 ore fa, Lucky67 ha scritto: Essendo un numero in virgola mobile non sono così sicuro che shiftando i bit si abbia un dato congruo....così a naso è... L'interpretazione dei 2 registri modbus come numero REAL è subordinata al corretto ordinamento dei byte che compongono i registri stessi ... e in questo caso stiamo invertendo byte alto con byte basso (e magari anche word alta con word bassa) per ricostruire in arrivo lo stesso dato che c'è in partenza. Link al commento Condividi su altri siti More sharing options...
Water Inserita: 26 febbraio Autore Segnala Share Inserita: 26 febbraio (modificato) .. ho testato velocemente con più opzioni ma senza nessun risultato, per il momento devo abbandonare la cosa x mancanza di tempo, però la cosa mi innervosisce molto e sicuramente appena possibile ci riprovo, 🥵 grazie comunque a tutti per il supporto Modificato: 26 febbraio da Water Link al commento Condividi su altri siti More sharing options...
max.riservo Inserita: 26 febbraio Segnala Share Inserita: 26 febbraio Se sei in zona Torino, puoi passare da me in ditta (magari con il contatore di energia) e vedi che sistemiamo il problema ... Link al commento Condividi su altri siti More sharing options...
NoNickName Inserita: 26 febbraio Segnala Share Inserita: 26 febbraio Oppure posti qui i 4 byte grezzi e il valore che ti attendi. Link al commento Condividi su altri siti More sharing options...
Water Inserita: 26 febbraio Autore Segnala Share Inserita: 26 febbraio 2 ore fa, max.riservo ha scritto: Se sei in zona Torino, puoi passare da me in ditta (magari con il contatore di energia) e vedi che sistemiamo il problema ... grazie Max sei molto gentile e ci verrei molto volentieri ..almeno per pagarti una birra! 😁 purtroppo non siamo così vicini, sono della provincia di Milano e molto raramente sono a Torino 😥 comunque a breve ci riprovo .. è garantito! 😁 Link al commento Condividi su altri siti More sharing options...
Water Inserita: 26 febbraio Autore Segnala Share Inserita: 26 febbraio 1 ora fa, NoNickName ha scritto: Oppure posti qui i 4 byte grezzi e il valore che ti attendi. ciao, questo sono i valori dei primi 10 registri Modbus, da dataSheet i primi tre registri partendo dall'uno danno la tensione Fase-Neutro delle tre fasi (circa 228/230V), Link al commento Condividi su altri siti More sharing options...
NoNickName Inserita: 26 febbraio Segnala Share Inserita: 26 febbraio (modificato) ti faccio il primo 17251 54936 = 0x4363 0xD698 La tua dword è 0x4363d698 4 3 6 3 D 6 9 8 0 1 0 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 0 0 10000110 11000111101011010011000 Il primo bit è il segno, quindi positivo. i successivi otto bit sono l'esponente Il resto è la mantissa L'esponente è a complemento 127. 10000110 = 134 - 127 = 7 La mantissa è 1.11000111101011010011000 binario, cioè 1.7799863815307617 decimale Il risultato è 2^7 * 1.7799863815307617 = 227,838 che è la tua tensione della fase 1 Analogamente per le altre. IEEE 754 floating point standard. La seconda è 0x43653e10 e la tensione è 229.242 La terza è 0x4365c270 e la tensione è 229.76 Modificato: 26 febbraio da NoNickName Link al commento Condividi su altri siti More sharing options...
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