Jump to content
PLC Forum


TomCastagna

Modbus TCP/IP tipologia di dati

Recommended Posts

TomCastagna

Buongiorno a tutti,

 

da qualche giorno mi sto scontrando con una comunicazione Modbus TCP verso la macchina di una cliente. Ho una CPU 1513-1AL01 FW2.6

 

Devo leggere dei registri secondo specifiche del costruttore della macchina. Per fare un test, ho provato a leggere un registro descritto nel manuale del costruttore come segue:

ADDRESS RANGE

DESCRIPTION

ACCESS

COUNT

DATA TYPE

REGISTER TYPE

40049-40064

Product

Read only

16

String * 32

Input register

 

Dunque quello che ho fatto è stato crearmi il mio MB_CLIENT:

- parametro Connect come in foto allegata (IP del Modbus Server 192.168.33.15);

- MB_Mode su 0 (quindi abilitato in lettura);

- MB_data_LEN su 16, considerato che il produttore indicato 16 sotto la voce count;

- MB_data_PTR: mi ha fatto sorgere parecchi dubbi.... Ho provato ad inserire Byte dato che il produttore sul manuale scrive così:

Product

name of the product that is being analyzed

String * 32

32 bytes

 

creando quindi un array di byte vedo che vengono in qualche modo scritti, ma tutti con valori a 0! 

 

- leggendo sul manuale di Siemens ho letto che si può anche impostare MODE 104 per leggere le parole di ingresso. Facendo una prova, ho creato un array di word dove questa volta vengono scritti dei valori, che, convertendoli, però non somigliano minimamente a quello che dovrei leggere, cioè il nome del prodotto.

 

Il tecnico della macchina, che era accanto a me, ha provato a stabilire una connessione con un software client interrogando quel registro, riuscendo però a leggere il nome del prodotto (allego foto dello screen).

Premettendo che non ricevo errori, nè codici diversi da 7004-7005-7006, come mai dal mio PLC non ci riesco? Sbaglio il tipo di dato nell'array? Sbaglio il tipo di MODE?

Grazie a tutti per l'ascolto!

Config.JPG

Screen_MODBUS_DYLOG.JPG

Share this post


Link to post
Share on other sites

pigroplc

prova a vedere questa discussione e scarica il mio PDF

 

Share this post


Link to post
Share on other sites
TomCastagna
4 ore fa, pigroplc ha scritto:

prova a vedere questa discussione e scarica il mio PDF

 

Ciao Pigro PLC,

grazie, questa discussione l'ho letta ieri prima di scrivere questo post. Con Modbus poll ho già fatto dei test prima di andare dal cliente e riuscivo a comunicare scambiando (in lettura e scrittura) byte senza alcun problema. Per questo motivo non capisco, perché non riesco a ricevere la stringa pur creando un array di stringhe, char oppure word? Perché in un array in byte ricevo solo degli 0 e non riesco a ricevere altro che quello, mentre invece il software MiniHMI funziona? Cosa ha di differente la mia impostazione rispetto a quella del MiniHMI?

Sono confuso.... Sono sicuro che c'è un errore, ma non riesco a capire :(

Share this post


Link to post
Share on other sites
pigroplc

TomCastagna,

 

Vediamo se ho capito: un dispositivo x deve comunicare via Modbus col PLC. Quello che io farei per cercare di uscire dall'impasse è questo: 

proverei la comunicazione fra il dispositivo x e il simulatore e ne verifico la funzionalità. Con lo stesso simulatore (una volta impostato come client e l'altra come server ovviamente) proverei la comunicazione con il PLC. 

Se la comunicazione avviene in entrambi i casi sopra elencati mi aspetto che sia uguale anche fra il dispositivo x e il PLC.

 

Tu hai fatto così?

 

 

 

Share this post


Link to post
Share on other sites
Yiogo

non devi puntare a 40049 !

 

4 è la classe del registro, nello specifico un holding, per cui ci accedi con la function 3

ne consegue che devi eseguire la function 3, che implicitamente punta a registri di classe 4 ed interrogare il registro 49

 

attenzione che questa è la modalità canonica immaginando che ambedue i device comincino a contare da 1 ma taluni interpretano scorrettamente le specifiche per cui è possibile che dabba fare un offset di 1

 

questa è la spiegazione canonica del protocollo modbus che conosco bene, non chiedermi eventuali specificità o stranezze dei due vendor

peraltro esistono ulteriori eccezioni, per esempio situazioni non canoniche dove è corretto usare l'offset 40000

Share this post


Link to post
Share on other sites
TomCastagna
15 ore fa, pigroplc ha scritto:

TomCastagna,

 

Vediamo se ho capito: un dispositivo x deve comunicare via Modbus col PLC. Quello che io farei per cercare di uscire dall'impasse è questo: 

proverei la comunicazione fra il dispositivo x e il simulatore e ne verifico la funzionalità. Con lo stesso simulatore (una volta impostato come client e l'altra come server ovviamente) proverei la comunicazione con il PLC. 

Se la comunicazione avviene in entrambi i casi sopra elencati mi aspetto che sia uguale anche fra il dispositivo x e il PLC.

 

Tu hai fatto così?

 

 

 

Buongiorno,

il simulatore MiniHMI non funziona anche da server, quindi le mie prove le ho fatte solo con Modbus Poll da e verso PLC (connessione funzionante). Volevo provare la stessa cosa verso la macchina, ma.... Licenza da comprare e ci vogliono 129 dollari, che se non trovo altra soluzione, sicuramente dovrò sborsare!

 

 

Share this post


Link to post
Share on other sites
TomCastagna
16 ore fa, Yiogo ha scritto:

non devi puntare a 40049 !

 

4 è la classe del registro, nello specifico un holding, per cui ci accedi con la function 3

ne consegue che devi eseguire la function 3, che implicitamente punta a registri di classe 4 ed interrogare il registro 49

 

attenzione che questa è la modalità canonica immaginando che ambedue i device comincino a contare da 1 ma taluni interpretano scorrettamente le specifiche per cui è possibile che dabba fare un offset di 1

 

questa è la spiegazione canonica del protocollo modbus che conosco bene, non chiedermi eventuali specificità o stranezze dei due vendor

peraltro esistono ulteriori eccezioni, per esempio situazioni non canoniche dove è corretto usare l'offset 40000

 

ok, quindi sostanzialmente mi stai dicendo di impostare MB_DATA_ADDR = 49 e la funzione numero 3 per MB_MODE.

 

Leggendo il manuale tra le prime righe, vedo che per definire la funzione Modbus è necessario stabilire una combinazione tra

mi sembra di aver capito che per le funzioni 01, 02 e 03 bisogna impostare MB_MODE = 0 (allego screen). Però.... se io imposto invece MB_MODE = 103 dovrei essere in grado di leggere i registri di mantenimento tra 0 e 65.535 con funzione 03, giusto?

Nella pratica:

 

MB_MODE = 103

MB_DATA_ADDRESS= 49

MB_DATA_LEN = 16 (indico che voglio 16 bit per comporre la stringa desiderata)

MB_DATA_PR = array of 50 byte

 

Dico bene?

 

 
 

funzione 3.JPG

funzione 3 MBMODE 103.JPG

Share this post


Link to post
Share on other sites
pigroplc
2 ore fa, TomCastagna ha scritto:

Licenza da comprare e ci vogliono 129 dollari, che se non trovo altra soluzione, sicuramente dovrò sborsare!

Nel mio documento faccio riferimento ad un software gratuito per i primi 30 giorni se non erro, quindi senza spendere e in piena legalità puoi provare; e se non ce la fai in 30 giorni vuol dire che hai preso un lavoro in perdita secca.....

https://www.modbustools.com/download.html

 

Share this post


Link to post
Share on other sites
TomCastagna
1 ora fa, pigroplc ha scritto:

Nel mio documento faccio riferimento ad un software gratuito per i primi 30 giorni se non erro, quindi senza spendere e in piena legalità puoi provare; e se non ce la fai in 30 giorni vuol dire che hai preso un lavoro in perdita secca.....

https://www.modbustools.com/download.html

 

 

Come già ti scrivevo prima, le prove secondo il tuo documento, le avevo già fatte prima di andare dal cliente e funzionava tutto. Ora, per scrupolo, ho installato su un altro computer il Modbuslave per eseguire un'altra prova: anche questa ha avuto esito positivo.
I 30 giorni passano in fretta se le prove le ho fatto in ufficio prima di Natale ed il macchinario è stato installato in questi giorni...

Share this post


Link to post
Share on other sites
TomCastagna

Sono andato avanti con ulteriori test in ufficio.

 

Ho creato con il software ModbusSlave il server

ModbusSlaveTab.PNG.bbfbf68cddc7663a85cceafdb542842a.PNG

dal quale i due client CPU 1500 e MiniHMI Software su altro computer vanno a scambiare dei dati.

Come si vede dagli screen che allego, la comunicazione con il PLC è funzionante con le impostazioni date.

559038604_BloccoMB_Client.thumb.JPG.a359b2457ea6417c0e5f3546350683cc.JPG1280483711_DBData.thumb.JPG.207af8d38b5d44c11a2460da22c1a254.JPG

 

Funziona anche se il client da MiniHMI stabilisce una comunicazione con il Modbus Slave.....

 

Però!

 

Se metto a confronto lo screen della comunicazione che sto provando adesso in ufficio

MiniHMI.thumb.JPG.4a696d1cefa91816911d68ff23e3d685.JPG

 

Con quella fatta dal tecnico della macchina l'altro giorno

Screen_MODBUS_DYLOG.thumb.JPG.aa226773f5e4b443088b4cdbc4a8134b.JPG

 

Si vede come il software MiniHmi sia stato impostato differentemente da come l'ho impostato io in questo momento!

 

Le differenze:

Memory Type

Output (holding)  VS   Input

Data Format 

Integer VS String (e questo ci può stare, perché la macchina fornisce una stringa di caratteri)

Address Type

Modicon 5-digit  VS  Absolute (0 Based)

 

Se consideriamo giusto quanto riportato sui range Modbus che allego:

ModbusAddDescr.JPG.2319a24c5b5d76ffb4e7d3ceb8358ee9.JPG

 

E quanto descritto dal manuale Modbus della macchina del cliente:

 

MacchinaModbus.thumb.JPG.4d1fac48a079cfcd7ffe4c01d0baf0c9.JPG

 

Devo quindi impostare il mio MB_Client con Funzione 2 perché sono degli input register? Dunque il parametro MB_MODE dovrebbe essere 257 oppure 0 e comunque 

 

mettere MB_DATA_ADDR su 400049 per leggere quella stringa?

 

1449295758_funzione2-257.thumb.JPG.eb362db5b852a08d28c55716493d917b.JPG

 

Grazie per l'ascolto! :)

 

 

Edited by TomCastagna

Share this post


Link to post
Share on other sites
TomCastagna

Ho fatto ulteriori test (poi per oggi chiudo qui, promesso :) )

Ho provato a ragionare inversamente.

Ho quindi modificato le impostazioni del ModbusSlave per creare degli Input Register

 

SlaveConfigInpuntReg.PNG.9e568c8d763d7c4ab9fb8e125cb60828.PNG

 

Ho quindi creato la tabella del Modbus Slave come segue:

ModbusSlaveInputRegTab.thumb.PNG.0654d12b84c034840ecd4d777ad1e7f2.PNG

 

Successivamente, sono andato a fare un test con MiniHMI impostandolo come ha fatto il tecnico della macchina, ed il risultato è positivo!

MiniHMIInputReg.thumb.JPG.e5f8f7a13a513a6df8352f9f44cff39a.JPG

 

Dunque sono passato al lato PLC ed ho impostato il mio blocco così con MB_MODE a 104 per svolgere la comunicazione in funzione 04!

MB_Client_inputReg_config.thumb.JPG.b46acdb1c47e68634d4c96bdf31977cd.JPG

 

Di fatti trasferisce tutti i dati sull'array di word che ho creato:

 

DB_DATA_InputConfig.JPG.7071922f8df25fe85c163776ee8bddef.JPG

 

Questa possiamo dire che è la modalità per leggere gli Input Register dal Server?

Share this post


Link to post
Share on other sites
Yiogo

c'è qualcosa che non quadra in quello che dici

se fossero input register, cioè registri di classe 3, li dovresti leggere con function 4, non con 2

 

io ho software modbus ma preferisco provare le comunicazioni usando come master il plc, così risolvo alla radice le variante legate ai vendor

la stessa ragione per cui non ho mai usato simulatori

Edited by Yiogo

Share this post


Link to post
Share on other sites
walterword

nel Modbus il prefisso 4 indica una certa area, cioè gli holding registers. Se vuoi leggerli lo specifichi nel pacchetto modbus nel campo del codice funzione che è 0x06 se non ricordo male.

L'offset parte sempre da 0 per cui nello start byte devi specificare l'offset senza 4

Share this post


Link to post
Share on other sites
Giuseppe Signorella
Quote

nel Modbus il prefisso 4 indica una certa area

Per la precisione il prefisso 4 indica il codice funzione del modbus

Share this post


Link to post
Share on other sites
Yiogo

state confondendo la classe dei registi con la function modbus, quello che chiami "prefisso" non è la function

ma ancora peggio state elucubrando sulle variazioni che taluni vendor hanno costruito

il modbus è quello definito dalle specifiche modbus IDA, che oltretutto sono pubbliche

i registri modbus di classe 4 sono gli holding reg. che si leggono con la function 3 potendolo fare in maniera multipla e si scrivono singolarmente con la function 6 o se ne scrivono un certo numero con la function 16 [16#0010 per la precisione]

secondo la specifica originale la classe la si omette ma qualche vendor la richiede, per esempio National Instruments definisce il registro precisando in maniera esplicita la classe

 

 

Share this post


Link to post
Share on other sites
TomCastagna

Buongiorno a tutti,

purtroppo non sono riuscito ancora a tornare nel sito d'installazione per fare ulteriori test, ma vorrei ugualmente ragionare ancora con voi sull'argomento, se non è un problema :)

Il 19/1/2020 alle 12:43 , Yiogo ha scritto:

c'è qualcosa che non quadra in quello che dici

se fossero input register, cioè registri di classe 3, li dovresti leggere con function 4, non con 2

 

Sì, esattamente è quello che ho fatto impostando la funzione MB_MODE su 104, dunque funzione 4.

 

Il 20/1/2020 alle 14:20 , walterword ha scritto:

nel Modbus il prefisso 4 indica una certa area, cioè gli holding registers. Se vuoi leggerli lo specifichi nel pacchetto modbus nel campo del codice funzione che è 0x06 se non ricordo male.

L'offset parte sempre da 0 per cui nello start byte devi specificare l'offset senza 4

 

Concordo con quello che però ha scritto Yiogo che gli Holding Registers si leggono in Funzione 3.

Il 21/1/2020 alle 23:50 , Yiogo ha scritto:

i registri modbus di classe 4 sono gli holding reg. che si leggono con la function 3 potendolo fare in maniera multipla e si scrivono singolarmente con la function 6 o se ne scrivono un certo numero con la function 16 [16#0010 per la precisione]

Concordo in pieno, in tutte le documentazioni c'è scritto questo:
703301465_Listafunzioni.thumb.JPG.30acdb475d7f07a5bf0ce01a18d94eac.JPG

Da quello che ho capito, imposto Funtion 4 con MB_MODE 104 e poi imposto come MB_DATA_ADDRESS 40049 con un DATA_LEN 16 (16 Byte di Count come indicato dal Vendor)

Farò un tentativo, poi, ovviamente, vi aggiornerò sugli esiti.

 

Grazie ancora della disponibilità di tutti.

Share this post


Link to post
Share on other sites
Yiogo

NO !

function 4 (read INPUT register) legge i registri di classe 3, cioè le immagini degli ingressi analogici (che per ovvie ragioni sono solo in lettura), nello specifico esempio leggeresti gli ingressi analogici da 49 a 64

rimane sempre da considerare la diversa impostazione degli specifici vendor, i taluni casi punterai a 30049 in sistemi canonici a 49

 

se vuoi leggere i registri di sitema da 49 a 64 DEVI usare la function 3 puntando sempre a 49 (in eccezione a 40049)

 

MA L'AVEVO GIA' DETTO, è il caso che PRIMA ti leggi le specifiche originali E DOPO rileggi questa discussione

 

il forum può essere un valido aiuto in caso di specificissssimi dubbi, NON può sostituire lo studio accurato delle specifiche originali

 

Il 20/1/2020 alle 14:20 , walterword ha scritto:

L'offset parte sempre da 0 per cui nello start byte devi specificare l'offset senza 4

non sempre, anzi fare molta attenzione alle due possibilità

Share this post


Link to post
Share on other sites
max.riservo

Aggiungo a quanto detto da Yiogo :

- "l'unità" di misura del modbus è la Word -> quindi 16 bits. Un registro modbus è una word

- un registro modbus è composto da 2 bytes : occorre prestare attenzione all'ordine (endianness) dei bytes (L/H oppure H/L) -> vedere littel endian / big endian

- quando l'informazione da trasmettere è una doppia word (doppio intero / real) entra in gioco anche l'ordine delle words (Word L/H oppure Word H/L)

- l'indirizzo di partenza degli holding registers può essere 0 oppure 1

 

Tornando al punto : cerca di comunicare facendoti restituire una word (quindi 2 bytes che corrispondono a 2 caratteri), quando l'avrai ricevuta cerca di capire l'ordine dei bytes. Quando avrai finalmente ottenuto la word aumenta l'area di lettura (8 words -> 16 bytes -> 16 caratteri).

Nel remoto caso che venga trasmesso SOLO 1 carattere per word (nel byte basso o in quello alto oppure venga utilizzata una codifica che richiede più di 7/8 bit per carattere) dovrai richiedere 16 words.

Share this post


Link to post
Share on other sites
Yiogo

ottime precisazioni, avevo dimenticato l'aspetto dell'order che max ha spegato ottimamente

anzi a questo punto evidenzio utleriormente che modbus ragiona nativamente sempre e solo in word

se ci servono dati in BYTE, in DWORD, in REAL o in LREAL dobbiamo comunque riportare la lunghezza della coda letta sempre a WORD standard di 16 BIT e su quelle dimensionare la coda letta o scritta

 

aneddoto stranissimo per far capire quanto è flessibile la comunicazione

il protocollo potrebbe andare a leggere o scrivere sullo slave i dati  interpretandoli in qualsiasi modo, anche il più strano, figuratevi che in un caso mi trovai a leggere attraverso word su uno strano oggetto degli pseudo REAL che erano epressi a 16 BIT, nello specifico leggevo il dato come se fosse una WORD ed eseguivo nel master la conversone come da specifica  del produttore riportando poi il dato in un REAL canonico a 32 BIT

 

 - - - - - - - - - - - - - - - - - - - - - -

 

esisteva nel passato un protocollo che probabilemente (perlomeno secondo la mia opinione) fu quello che ispiro Gould alla progettazione del modbus, il DCP550 di Honeywell, che si basava sugli stessi principi ma la sua struttura non era basata su WORD (16 BIT) ma su BYTE (8 BIT) ma aveva la stessa logica strutturale e lo stesso concetto di calcolo del CRC

del resto non è un caso che si chiami ModBUS che non è altro che la contrazione commerciale di Modicon BUS, Modicon fu il primo PLC vero concepito come ora noi lo intendiamo e fu appunto progettato da Gould, Gould ebbe già allora l'intelligenza (rarissima in quei tempi) di tenere per sè la progettazione del PLC ma rendere pubblico e libero l'uso di questo protocollo, è per questa ragione che negli anni è divenuto il vero e [quasi] unico protocollo vendor indipendente

 

Share this post


Link to post
Share on other sites
batta
1 ora fa, max.riservo ha scritto:

vedere littel endian / big endian

Adesso vado fuori tema, ma quando sento parlare di little endian e big endian, non riesco a fare a meno di pensare a come sono nate quelle diciture.

Chi già non ne conosce l'origine, credo rimarrà sorpreso nell'apprendere che lo spunto arriva dalle Avventure di Gulliver e, più precisamente, dall'isola di Lilliput.

Sull'isola di Lilliput, come in tutto il resto del mondo, per bere un uovo, tutti lo rompevano dalla punta, ovvero dalla parte più piccola. Un giorno però, il re, rompendo un uovo dalla punta, col guscio si tagliò un dito. Emanò allora una legge che obbligava tutta la popolazione a rompere le uova solo dalla parte grossa. Tra il popolo, ci fu chi si adeguò (che mi cambia, in fondo, ad aprire un uovo da una parte o dall'altra?) e chi, invece, rivendicò il proprio diritto di aprire le uova dalla parte che meglio crede. Si scatenò così una sanguinosa guerra, e chi non si adeguò al volere del re fu cacciato sull'isola vicina a Lilliput (della quale non ricordo il nome).

Ma, tutta questa storia, in realtà, era solo una metafora: rappresentava l'insulsa guerra tra francesi ed inglesi, ovvero tra cattolici e protestanti, che aveva come pretesto le differenze tra queste due religioni.

Share this post


Link to post
Share on other sites
Yiogo

non sei affatto andato fuori tema

per usare le cose bisogna conoscere tutto, anche aspetti che sembrano collaterali

altrimenti diventi un mero esecutore, una sorta di prete

 

Share this post


Link to post
Share on other sites
TomCastagna
Il 27/1/2020 alle 20:55 , Yiogo ha scritto:

NO !

function 4 (read INPUT register) legge i registri di classe 3, cioè le immagini degli ingressi analogici (che per ovvie ragioni sono solo in lettura), nello specifico esempio leggeresti gli ingressi analogici da 49 a 64

rimane sempre da considerare la diversa impostazione degli specifici vendor, i taluni casi punterai a 30049 in sistemi canonici a 49

 

Ho impostato

MB_MODE 104

MB_DATA_ADDRESS 40049

DATA_LEN 16

 

Ho ottenuto delle DWORD come segue

16#4255_4641
16#4C41_5F32
16#3530_4752


Che convertite in ASCII sono esattamente:

BUFALA_250GR

 

Questo spiegato dal fatto che il produttore della macchina, nelle sue specifiche, indica di andare a leggere degli "Input Registers". Per ottenere le parole in ingresso da degli Input Registers con il blocco MB_CLIENT, il manuale indica di impostare MB_MODE su 104 che permette di "puntare" a registri da 0 a 65.535 (che quindi comprende anche il mio 40049, richiesto dal produttore della macchina). Così facendo il sistema viene impostato su Funzione 4 che rispetta in pieno le specifiche di Read input registers (FC 4) riportate a pag.11 nel documento "Open Modbus TCP Standards" scaricabili dal sito Modbus.org.

Le parole ottenute da questo tipo di sistema devono subire una conversione da dato espresso in HEX verso ASCII, in quanto "composte" secondo le specifiche 984 ASCII riportate a pag.24 dello stesso documento "Open Modbus TCP Standards".

 

Il sistema così composto funziona perfettamente

 

Il 27/1/2020 alle 20:55 , Yiogo ha scritto:

MA L'AVEVO GIA' DETTO, è il caso che PRIMA ti leggi le specifiche originali E DOPO rileggi questa discussione

 

il forum può essere un valido aiuto in caso di specificissssimi dubbi, NON può sostituire lo studio accurato delle specifiche originali

 

Riporto a questa risposta il link dove ricavare il documento delle specifiche Modbus TCP che ho letto, studiato, e che, soprattutto, mi hanno aiutato a risolvere il mio problema, di modo tale che tutti ne possano far uso e rendere il forum un ambiente di crescita e di supporto per coloro che realmente amano questa professione

http://www.modbus.org/specs.php

 

Auguro una buona serata a tutti

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