Modbus TCP
Registri e coil Modbus su TCP/IP, con indirizzamento tipizzato, controllo dell'ordine dei byte e una scansione di rete limitata.
Il driver Modbus TCP legge e scrive registri e coil Modbus su TCP/IP: PLC, contatori, gateway e qualunque server che parli Modbus/TCP. L'indirizzamento è interamente tipizzato: si sceglie una classe di registro e un numero di registro in base 0, e l'applicazione compone la richiesta sul bus; non c'è alcun indirizzo a testo libero da sbagliare.
Dispositivo
| Campo | Significato | Predefinito |
|---|---|---|
| Indirizzo host | Nome DNS, indirizzo IPv4 o IPv6 del server o del gateway Modbus. | vuoto: il dispositivo non viene collegato finché non se ne inserisce uno |
| Porta | La porta TCP, da 1 a 65535. Un campo vuoto mostra 502 in grigio e il dispositivo viene chiamato su di essa; un dispositivo salvato con 0 si legge allo stesso modo. | 502 |
| ID unità | L'id di unità (slave) Modbus portato in ogni richiesta: quello che un gateway usa per instradare verso il dispositivo che ha dietro. Da 0 a 255. | 1 |
| Formato della trama | Come viaggia ogni richiesta sulla connessione: MBAP, l'intestazione Modbus TCP davanti a ogni richiesta, oppure RTU, la trama RTU con il suo CRC inviata così com'è, per un convertitore seriale-Ethernet in modalità trasparente (vedi RTU su TCP). Host, porta, ID unità e tag sono gli stessi in entrambi i casi. | MBAP |
| Intervallo minimo tra transazioni (ms) | Cadenza di compatibilità: il silenzio minimo dopo il completamento di una transazione prima che parta la successiva, da 0 a 1000. Zero non aggiunge alcun ritardo artificiale. | 0 |
| Intervallo di interrogazione (ms) | La cadenza di interrogazione predefinita per i tag che non la ridefiniscono. | 1000 |
L'URI di base mostrato nell'intestazione del pannello è
modbus+tcp://host:port/unitID, più ?minimumTransactionIntervalMs=n quando
l'intervallo è impostato.
I dispositivi che condividono host e porta condividono anche un'unica porta di transazione: le richieste verso lo stesso endpoint non si sovrappongono mai, e a cadenzarle tutte è l'intervallo minimo tra transazioni più grande configurato tra i dispositivi abilitati su quell'endpoint. Il pannello dice quando un altro dispositivo alza l'intervallo effettivo sopra quello configurato qui. L'intervallo governa solo il traffico che questa applicazione emette: è un aiuto di compatibilità per un server o un gateway lento, non un rimedio per i guasti di rete.
La connessione attende al massimo 5 secondi; una risposta viene attesa al massimo 10 secondi; non ci sono ritentativi a livello di protocollo. La riconnessione appartiene al ciclo di ritentativi in secondo piano, quindi un dispositivo spento non costa altro che una lettura di cattiva qualità.
RTU su TCP
Un convertitore seriale-Ethernet in modalità trasparente non parla Modbus TCP per conto suo: ciò che arriva sul suo socket esce così com'è sul suo bus seriale, e ciò che il bus risponde torna indietro. Un dispositivo dietro un convertitore è un dispositivo Modbus TCP con il Formato della trama su RTU: la stazione invia la trama RTU (l'ID unità, la richiesta e il suo CRC) senza intestazione MBAP, e accetta una risposta solo se il suo CRC torna. Il Base URI porta allora framing=rtu nella sua query, per esempio modbus+tcp://192.168.0.20:502/1?framing=rtu; un dispositivo su MBAP mantiene l'indirizzo che ha sempre avuto. Tutto il resto di questa pagina vale senza cambiamenti: le classi di registro, i codici funzione, la coda delle scritture, i timeout e l'intervallo tra transazioni.
- L'ID unità è l'indirizzo del dispositivo sul bus seriale dietro il convertitore, da 1 a 247.
- I dispositivi dietro un convertitore ne condividono host e porta, e con essi la barriera delle transazioni: una richiesta alla volta, che è anche tutto ciò che un bus seriale porta. Se il convertitore ha bisogno di una pausa tra le trame, aumentare l'Intervallo minimo tra transazioni (ms).
- Le impostazioni seriali del convertitore stesso (velocità in baud, formato) si configurano sul convertitore; la stazione non le vede mai.
- Una trama RTU non porta un numero di transazione, quindi prima di ogni richiesta la stazione scarta ciò che il convertitore ha già inviato: una risposta che arriva dopo il timeout della sua richiesta non viene mai presa per quella della successiva.
Indirizzamento dei tag
| Campo | Significato | Predefinito |
|---|---|---|
| Classe di registro | Quale entità Modbus il tag indirizza: Bobina (0xxxx), Ingresso discreto (1xxxx), Registro di ingresso (3xxxx) oppure Registro di mantenimento (4xxxx). Ognuna porta la prima cifra che l'indirizzo del manuale ha per lei, quindi un manuale che stampa solo 30001 indica i registri di ingresso. | Ricavata dal tipo e dall'accesso: i tag Boolean prendono un ingresso discreto (sola lettura) oppure una bobina (scrivibile); ogni altro tipo prende un registro di ingresso (sola lettura) oppure un registro di mantenimento (scrivibile). |
| Numero di registro (base 0) | L'indirizzo grezzo di protocollo. È l'indirizzo in base 0 sul bus, non la notazione del manuale: il registro holding 40001 è il numero di registro 0. Scrivere 30001 qui non sceglie la classe, perché alcuni dispositivi hanno davvero registri oltre 30000: la classe si sceglie sopra. Il registro viaggia sul bus come un numero a 16 bit, quindi il campo accetta da 0 a 65535 e rifiuta qualunque cosa più larga dove viene scritta. | 0 |
| Quantità (registri, vuoto = automatico) | Quanti registri a 16 bit occupa il valore. La casella viene disegnata solo sui tag String: ogni altro tipo ha una larghezza fissa, quindi non c'è nulla da ridefinire. | Per tipo: Boolean, Int16 e UInt16 1, Int32 e Float 2, String 4 |
| Byte più significativo per primo (MSB first, big-endian) | Quale byte di ogni registro a 16 bit viene per primo sul bus; le parole tra parentesi sono quelle che stampano i manuali. Per i tag numerici e per un tag Boolean tenuto in un registro di mantenimento o di ingresso; un Boolean in una bobina o in un ingresso discreto è un solo bit senza byte da ordinare, quindi lì la casella non viene disegnata. | attivo (quello che la specifica Modbus chiede) |
| Parola più significativa per prima (parola alta per prima) | Quale registro di un valore a due registri porta la metà alta. Solo per i tag Int32 e Float: un valore a un solo registro (Boolean, Int16, UInt16) non ha un secondo registro, quindi lì la casella non viene disegnata. Sotto le due caselle, Ordine dei byte del valore nomina la disposizione che formano con le lettere di un manuale (Ordine dei byte e delle parole). | attivo |
La scheda Sorgente termina con Indirizzo nel manuale, dove si trova il tag nella notazione che stampa il manuale del dispositivo: la prima cifra della classe, poi il registro contato da 1. Il registro di ingresso 0 si legge 30001, un Float al registro di mantenimento 100 si legge da 40101 a 40102, e un registro oltre 9998 passa a sei cifre (il registro di mantenimento 9999 si legge 410000), così il pannello si confronta riga per riga con il manuale.
Tipi di valore e quantità
Vengono offerti sei tipi di valore, e la larghezza di protocollo di ciascuno è fissa:
| Tipo di dato | Registri | Forma sul bus |
|---|---|---|
| Boolean | 1 | Su una classe di registro: qualunque registro diverso da zero legge true, e una scrittura invia 1 oppure 0. Su Coil/DiscreteInput: il bit stesso. |
| Int16 | 1 | Intero con segno a 16 bit in un solo registro, da -32768 a 32767. |
| UInt16 | 1 | Intero senza segno a 16 bit in un solo registro, da 0 a 65535. Lo stesso registro si legge 65535 come UInt16 e -1 come Int16: il segno lo dà il tipo di dato scelto, non il registro. |
| Int32 | 2 | Intero con segno a 32 bit su una coppia di registri. |
| Float | 2 | IEEE 754 a precisione singola su una coppia di registri. |
| String | 1 o più (predefinito 4) | Byte UTF-8 impacchettati due per registro. Una lettura si ferma al primo byte NUL; una scrittura deve stare nella quantità dichiarata (2 byte per registro) e viene riempita di zeri. |
Un tag String viene letto e scritto nell'ordine in cui il dispositivo tiene i byte, e una scrittura invia sempre UTF-8. I byte che non sono UTF-8 valido, che è l'aspetto di un intervallo che il dispositivo non ha mai inizializzato o di un testo scritto in un'altra codifica, si leggono come il carattere Unicode di sostituzione invece di far fallire la lettura: il tag mostra qualcosa di visibilmente sbagliato, e ogni altro tag di quel dispositivo continua a leggere.
La Quantità (registri, vuoto = automatico) viene chiesta solo sui tag String. Le larghezze di Boolean, Int16, UInt16, Int32 e Float sono fisse, quindi su quei punti la casella non viene disegnata, né nel pannello del tag né nella griglia dei tag; la ridefinizione esiste per dimensionare i tag String.
Ordine dei byte e delle parole
La casella dell'ordine dei byte viene disegnata sui tag numerici e su un Boolean tenuto in un registro, quella dell'ordine delle parole solo su quelli a due registri (Int32, Float). Sono due domande
indipendenti: quale byte guida dentro ogni registro, e quale registro guida lungo una
coppia. Modbus non definisce nessuna delle due per il testo, quindi a un tag String
non vengono offerte: i suoi byte viaggiano nell'ordine in cui il dispositivo li tiene.
Per il valore 0x01020304, con A come byte più significativo, le quattro
disposizioni sono:
| Byte più significativo per primo | Parola più significativa per prima | Byte sul bus |
|---|---|---|
| attivo | attivo | AB CD (il valore predefinito della specifica) |
| attivo | disattivo | CD AB (il classico scambio di parole) |
| disattivo | attivo | BA DC |
| disattivo | disattivo | DC BA |
Le letture e le scritture applicano le stesse due risposte nello stesso ordine, quindi una scrittura depone esattamente i byte che una lettura avrebbe riportato. Ordine dei byte del valore, sotto le caselle, dice la disposizione in una parola (ABCD, CDAB, BADC o DCBA), come la nomina un manuale.
Un valore Int16 o UInt16 è un solo registro, quindi gli si applica solo l'ordine dei
byte: per 0x1234, con il byte più significativo per primo si invia 12 34 e con la
casella disattiva 34 12. Non c'è un secondo registro da collocare, quindi la casella dell'ordine
delle parole non viene disegnata.
Codici di funzione
| Classe di registro | Lettura | Scrittura |
|---|---|---|
| Registro di mantenimento (4xxxx) | 3 (Read Holding Registers) | 6 (registro singolo) oppure 16 (più registri) |
| Registro di ingresso (3xxxx) | 4 (Read Input Registers) | sola lettura; una scrittura viene rifiutata |
| Bobina (0xxxx) | 1 (Read Coils) | 5 (Force Single Coil, un solo coil) |
| Ingresso discreto (1xxxx) | 2 (Read Discrete Inputs) | sola lettura; una scrittura viene rifiutata |
Una scrittura riesce solo quando la risposta di protocollo del server ne conferma l'accettazione; solo allora il valore in cache avanza.
Rilevamento
La scansione è esplicita e limitata: l'applicazione non deduce né spazza mai la sottorete locale. Il modulo dell'ambito prende:
| Campo | Significato | Predefinito |
|---|---|---|
| Host IPv4 o CIDR | Un indirizzo (192.168.1.10) oppure una sottorete non più ampia di /24 (192.168.1.0/24). Gli indirizzi di rete e di trasmissione vengono saltati. |
obbligatorio |
| Porta | La porta da sondare. | 502 |
| ID unità | Valori, elenchi separati da virgola o intervalli crescenti: 1, 1,5,9, 1, 3, 8-16 (da 0 a 255). |
1 |
| Formato della trama | La trama in cui viene inviato ogni sondaggio. Un convertitore in modalità trasparente risponde solo a trame RTU, quindi va scansionato in RTU. | MBAP |
| Intervallo minimo tra transazioni (ms) | La cadenza tra sondaggi completati sullo stesso host, da 0 a 1000. | 0 |
Il rilevamento invia ogni sondaggio nel Formato della trama scelto. Su RTU ogni sondaggio è la trama RTU nuda, e una risposta conta solo se il suo ID unità corrisponde e il suo CRC torna, così le unità dietro un convertitore in modalità trasparente vengono trovate come tutte le altre. Un'unità trovata mantiene il formato della trama della scansione quando viene aggiunta.
Una singola scansione può inviare al massimo 256 sondaggi (host × ID unità); un piano più grande viene rifiutato prima che si apra un socket. L'unica richiesta inviata è Read Basic Device Identification (funzione 43/14): il rilevamento non legge mai registri e non indovina mai una mappa di registri. Una risposta di eccezione Modbus perfettamente valida prova che un'unità è presente senza dichiararne l'identità; la raggiungibilità TCP, i timeout e le trame malformate no. Vengono scansionati fino a quattro host in parallelo, in sequenza dentro ciascun host, con timeout di connessione e di sondaggio di 750 ms.
I risultati portano l'endpoint completo e un nome suggerito, costruito dal fornitore e dal codice di prodotto quando il dispositivo li riferisce. I candidati hanno zero tag: i registri si configurano dopo Aggiungi. Un'unità già configurata viene marcata come tale e offre Apri invece di creare un duplicato.
Limiti da conoscere
- Le altre larghezze intere (SByte, Byte, UInt32, Int64, UInt64) e Double non vengono offerti: il codificatore del bus percorre esattamente i sei tipi qui sopra in entrambe le direzioni.
- Su ogni endpoint c'è una sola richiesta in sospeso per volta; molti dispositivi dietro un unico gateway condividono quella serializzazione per costruzione.
- Le scritture indirizzano un coil o una sequenza di registri per volta; non esiste la scrittura su più coil.