Modbus TCP
Des registres et des bits Modbus sur TCP/IP, avec un adressage typé, la maîtrise de l'ordre des octets et un balayage réseau borné.
Le pilote Modbus TCP lit et écrit des registres et des bits Modbus sur TCP/IP : automates, compteurs, passerelles et tout serveur qui parle Modbus/TCP. L'adressage est entièrement typé : vous choisissez une classe de registre et un numéro de registre à partir de 0, et l'application assemble la requête du bus; il n'y a aucune adresse en texte libre à manquer.
Équipement
| Champ | Sens | Par défaut |
|---|---|---|
| Hôte | Le nom DNS, l'adresse IPv4 ou IPv6 du serveur ou de la passerelle Modbus. | localhost quand il est laissé vide |
| Port | Le port TCP. | 502 (un 0 configuré retombe sur 502) |
| Identifiant d'unité | L'identifiant d'unité (esclave) Modbus porté par chaque requête, ce qu'une passerelle emploie pour router vers l'équipement derrière elle. De 0 à 255. | 1 |
| Intervalle minimal entre transactions (ms) | Une cadence de compatibilité : le silence minimal après la fin d'une transaction avant que la suivante ne commence, de 0 à 1000. Zéro n'ajoute aucun délai artificiel. | 0 |
| Intervalle de scrutation (ms) | La cadence de scrutation par défaut des tags qui ne la remplacent pas. | 1000 |
L'URI de base montrée dans l'en-tête du volet est
modbus+tcp://host:port/unitID, plus ?minimumTransactionIntervalMs=n quand
l'intervalle est posé.
Les équipements qui partagent un hôte et un port partagent aussi une seule porte de transaction : les requêtes vers le même point de terminaison ne se chevauchent jamais, et c'est le plus grand intervalle minimal entre transactions configuré parmi les équipements activés de ce point de terminaison qui les cadence tous. Le volet le dit quand un autre équipement relève l'intervalle effectif au-dessus de celui qui est configuré ici. L'intervalle ne gouverne que le trafic que cette application émet : c'est une aide à la compatibilité avec un serveur ou une passerelle lents, pas une réparation des défauts du réseau.
La connexion attend 5 secondes au plus; une réponse est attendue 10 secondes au plus; il n'y a aucune reprise au niveau du protocole. La boucle de reprise en arrière-plan possède la reconnexion, si bien qu'un équipement éteint ne coûte rien de plus qu'une lecture de mauvaise qualité.
Adressage d'un tag
| Champ | Sens | Par défaut |
|---|---|---|
| Classe de registre | Quelle entité Modbus le tag adresse : HoldingRegister, InputRegister, Coil ou DiscreteInput. |
Déduite du type et de l'accès : les tags booléens reçoivent DiscreteInput (lecture seule) ou Coil (inscriptible); tout autre type reçoit InputRegister (lecture seule) ou HoldingRegister (inscriptible). |
| Numéro de registre (à partir de 0) | L'adresse brute du protocole. C'est l'adresse à partir de 0 sur le bus, non la notation classique 4xxxx : le registre de maintien « 40001 » est le numéro de registre 0. Le registre voyage sur le bus comme un nombre de 16 bits : le champ prend donc de 0 à 65535 et refuse plus large là où il est saisi. | 0 |
| Quantité (registres, vide = automatique) | Combien de registres de 16 bits la valeur occupe. La zone n'est dessinée que sur les tags de texte : tout autre type a une largeur fixe, il n'y a donc rien à remplacer. | Par type : booléen 1, Int32 et Float 2, texte 4 |
| Octet de poids fort en premier | Quel octet de chaque registre de 16 bits passe en premier sur le bus. Tags numériques seulement. | activé (ce que la spécification Modbus demande) |
| Mot de poids fort en premier | Quel registre d'une valeur sur deux registres porte la moitié haute. Tags numériques seulement. | activé |
La carte Source montre l'adresse de bus assemblée (par exemple 100?quantity=2)
en aperçu de lecture seule, si bien que ce que le volet montre est exactement ce que la requête
porte.
Types de valeur et quantités
Quatre types de valeur sont offerts, et la largeur de chacun sur le protocole est fixe :
| Type de donnée | Registres | Forme sur le bus |
|---|---|---|
| Booléen | 1 | Sur une classe de registre : tout registre non nul se lit vrai, et une écriture envoie 1 ou 0. Sur Coil ou DiscreteInput : le bit lui-même. |
| Int32 | 2 | Un entier signé de 32 bits sur une paire de registres. |
| Float | 2 | Une simple précision IEEE 754 sur une paire de registres. |
| Texte | 1 ou plus (4 par défaut) | Des octets UTF-8 empaquetés deux par registre. Une lecture s'arrête au premier octet nul; une écriture doit tenir dans la quantité déclarée (2 octets par registre) et est complétée par des zéros. |
Un tag de texte est lu et écrit dans l'ordre où l'équipement détient les octets, et une écriture envoie toujours de l'UTF-8. Des octets qui ne sont pas de l'UTF-8 valide, ce à quoi ressemble une plage que l'équipement n'a jamais initialisée ou du texte écrit dans un autre codage, se lisent comme le caractère de remplacement Unicode plutôt que d'échouer : le tag montre quelque chose de visiblement fautif, et chaque autre tag de cet équipement continue de lire.
La quantité n'est demandée que sur les tags de texte. Les largeurs des booléens, des Int32 et des Float sont fixes : la zone n'est donc dessinée sur aucun de ces points, ni dans le volet du tag, ni dans la grille des tags; le remplacement existe pour dimensionner les tags de texte.
Ordre des octets et des mots
Les deux zones d'ordre sont dessinées sur les tags numériques. Ce sont deux questions
indépendantes : quel octet mène à l'intérieur de chaque registre, et quel registre mène dans une
paire. Modbus n'en définit aucune pour le texte : un tag de texte ne se les voit donc pas
offrir, et ses octets voyagent dans l'ordre où l'équipement les détient. Pour la valeur
0x01020304, A étant l'octet de poids le plus fort, les quatre dispositions sont :
| Octet de poids fort en premier | Mot de poids fort en premier | Octets sur le bus |
|---|---|---|
| activé | activé | AB CD (la valeur par défaut de la spécification) |
| activé | désactivé | CD AB (l'échange de mots classique) |
| désactivé | activé | BA DC |
| désactivé | désactivé | DC BA |
Les lectures et les écritures appliquent les deux mêmes réponses dans le même ordre : une écriture dépose donc exactement les octets qu'une lecture aurait repris.
Codes de fonction
| Classe de registre | Lecture | Écriture |
|---|---|---|
| HoldingRegister | fonction 3 (Read Holding Registers) | fonction 6 (registre unique) ou 16 (registres multiples) |
| InputRegister | fonction 4 (Read Input Registers) | lecture seule; une écriture est refusée |
| Coil | fonction 1 (Read Coils) | fonction 5 (Force Single Coil) |
| DiscreteInput | fonction 2 (Read Discrete Inputs) | lecture seule; une écriture est refusée |
Une écriture ne rapporte un succès que lorsque la réponse de protocole du serveur en confirme l'acceptation; la valeur en cache n'avance qu'à ce moment.
Découverte
Le balayage est explicite et borné : l'application ne déduit ni ne parcourt jamais votre sous-réseau local. Le formulaire de portée prend :
| Champ | Sens | Par défaut |
|---|---|---|
| Hôte IPv4 ou CIDR | Une adresse (192.168.1.10) ou un sous-réseau pas plus large que /24 (192.168.1.0/24). Les adresses de réseau et de diffusion sont sautées. |
obligatoire |
| Port | Le port à sonder. | 502 |
| Identifiants d'unité | Des valeurs, des listes séparées par des virgules ou des plages croissantes : 1, 1,5,9, 1, 3, 8-16 (de 0 à 255). |
1 |
| Intervalle minimal entre transactions (ms) | La cadence entre deux sondages terminés sur le même hôte, de 0 à 1000. | 0 |
Un balayage peut envoyer 256 sondages au plus (hôtes × identifiants d'unité); un plan plus grand est refusé avant l'ouverture du moindre socket. La seule requête envoyée est Read Basic Device Identification (fonction 43/14) : la découverte ne lit jamais de registre et ne devine jamais un plan de registres. Une réponse d'exception Modbus entièrement valide prouve qu'une unité est présente sans en revendiquer l'identité; la joignabilité TCP, les délais dépassés et les trames malformées ne le prouvent pas. Quatre hôtes au plus sont balayés en parallèle, séquentiellement à l'intérieur de chaque hôte, avec des délais de 750 ms à la connexion et au sondage.
Les résultats portent le point de terminaison complet et un nom suggéré, bâti à partir du fournisseur et du code produit quand l'équipement les rapporte. Les candidats n'ont aucun tag : les registres se configurent après Ajouter. Une unité déjà configurée est marquée comme telle et propose Ouvrir au lieu de créer un doublon.
Des limites bonnes à connaître
- Les types entiers larges (Int64, largeurs non signées) et Double ne sont pas offerts : le codec du bus fait l'aller-retour exact des quatre types ci-dessus.
- Une seule requête est en cours par point de terminaison à la fois; de nombreux équipements derrière une même passerelle partagent cette sérialisation, et c'est voulu.
- Les écritures adressent un bit ou une suite de registres à la fois; il n'existe pas d'écriture multi-bits.