Serveur Modbus
Le serveur Modbus TCP propre à la station : sa ligne dans la colonne Communications, sa mise en marche et son arrêt, son port et les clients connectés, la table des registres qui sert des tags, des variables Logic et des états d'alarme, ce qu'un client lit et écrit, un exemple complet et ce qu'il ne fait pas.
Le Serveur Modbus permet à un automate, à une IHM ou à un système de gestion technique du bâtiment qui ne parle que Modbus TCP de lire les tags, les variables Logic et les états d'alarme de la station, et d'écrire les tags et variables que vous autorisez. C'est le second chemin par lequel les données quittent la station, à côté du serveur OPC UA intégré, et ce n'est pas un pilote : un pilote lit des équipements, alors que le serveur Modbus est lu par des équipements; il attend qu'un automate se connecte et ne se connecte jamais à rien. Son volet le dit sous le titre : « Répond aux automates, IHM et systèmes de gestion technique du bâtiment qui lisent et écrivent en Modbus TCP. Il reçoit les connexions et n'en ouvre jamais. »
Modbus ne porte ni nom d'utilisateur ni mot de passe : qui atteint le port lit chaque registre que la table sert. C'est pourquoi le serveur démarre arrêté, chaque ligne de sa table démarre en lecture seule, et l'écriture s'autorise ligne par ligne, par quelqu'un qui l'a choisi. Voir Connector lit la page; Configurer Connector la modifie.
La ligne dans la colonne
La ligne Serveur Modbus se trouve sous le dossier Serveurs de l'arborescence de la colonne Communications, sous la ligne du serveur OPC UA, avec une icône de serveur là où les pilotes montrent une prise. Elle est toujours là : une station en a exactement une, et elle n'est jamais créée ni supprimée. La zone de recherche la trouve par son nom, et les puces d'état la rangent selon son état : Arrêt tant que le serveur est arrêté, Anomalies tant que son port est occupé ou qu'il n'a pas pu écouter, Sains sinon. À côté du nom, elle dit ce que fait le serveur, et un point le résume :
| La ligne dit | Point | Quand |
|---|---|---|
| « Arrêté » | gris | Le serveur est arrêté, ce qui est l'état de départ de toute station. |
| « À l'écoute sur le port 502 », puis combien de clients sont connectés : « Aucun client connecté », « 1 client connecté », « 3 clients connectés » | vert | Le serveur est en marche et le runtime roule : le port est ouvert. |
| « Le port 502 est occupé » | rouge | Le serveur est en marche, mais un autre programme retient le port. |
| « Impossible d'écouter sur le port 502 » | rouge | Le serveur est en marche, mais Windows a refusé d'ouvrir le port pour une autre raison. |
| « Runtime arrêté » | gris | Le serveur est en marche et le runtime est arrêté : le port reste fermé jusqu'à ce que le runtime roule de nouveau. |
Le point n'appartient qu'au serveur : il n'entre ni dans le cumul du dossier Pilotes ni dans la barre d'état, qui parlent des équipements que la station lit. Sélectionner la ligne ouvre le volet du serveur; son en-tête répète l'état à côté du même point. Les commandes sont sur la barre de commandes; la ligne n'a pas de menu à elle.
Le mettre en marche et l'arrêter
| Commande | Ce qu'elle fait | Grisée quand (situation) | Non dessinée quand (rôle) |
|---|---|---|---|
| Activer | Met le serveur en marche, comme le dit son infobulle : « Mettre le serveur en marche : il écoute sur le port 502 tant que le runtime tourne. » Le port s'ouvre aussitôt si le runtime roule, et le journal des actions dit « Serveur Modbus mis en marche. » | Le serveur est déjà en marche (« Le serveur est déjà en marche. »), un essai retient la station, ou le runtime est arrêté; l'infobulle donne la raison. | Sans Configurer Connector. |
| Désactiver | Arrête le serveur : « Arrêter le serveur : il ferme son port et déconnecte tous les clients. » Le journal des actions dit « Serveur Modbus arrêté. » | Le serveur est déjà arrêté (« Le serveur est déjà arrêté. »), un essai retient la station, ou le runtime est arrêté. | Sans Configurer Connector. |
Être en marche est un réglage que la station conserve, et l'écoute suit le runtime :
| Moment | Ce que fait le serveur |
|---|---|
| La station démarre | Un serveur laissé en marche ouvre son port dès que le runtime est prêt et que les essais qu'il reprend sont revenus; un serveur laissé arrêté reste arrêté. |
| Le port ne peut pas s'ouvrir | La ligne dit « Le port 502 est occupé » ou « Impossible d'écouter sur le port 502 », et la carte Port et clients le dit sous le champ du port : « Le port 502 est occupé sur cette machine. Fermez ce qui le retient, ou choisissez un autre port. », ou le même échec suivi de la raison donnée par Windows. La station continue de rouler sans lui. Le serveur ne réessaie pas tout seul : une fois le port libre, arrêtez-le et remettez-le en marche, ou déplacez-le sur un autre port. |
| Le runtime est arrêté | Le port se ferme et tous les clients sont déconnectés; une écriture qui attendait encore sa réponse cesse d'attendre. La ligne dit « Runtime arrêté », et le redémarrage du runtime rouvre le port. |
| L'application se ferme | Le port se ferme avec tout le reste. |
La carte Port et clients
La première carte du volet est Port et clients.
| Champ | Ce qu'il fait | Valeurs et défaut |
|---|---|---|
| Port TCP | Le port sur lequel le serveur écoute, sur chaque adresse de cet ordinateur, IPv4 et IPv6. Le changer pendant que le serveur écoute ferme l'ancien port et ouvre le nouveau, ce qui déconnecte tous les clients; le journal des actions dit « Serveur Modbus déplacé sur le port 5020. » | De 1 à 65535. Par défaut 502, le standard de Modbus. |
| Clients connectés | Combien de clients sont connectés en ce moment : « Aucun client connecté », « 1 client connecté », « 3 clients connectés ». Tant que quelqu'un est connecté, un tableau liste chacun avec Adresse du client (son adresse IP et son port, par exemple 192.168.0.20:51234) et Connecté depuis (la date et l'heure, au format de la station). |
Lecture seule. |
Un port sur lequel le serveur ne peut pas passer est refusé avant que rien ne soit enregistré : la raison s'affiche sous le champ, le champ revient au port en vigueur et le serveur reste où il était. Six saisies sont refusées : un nombre hors de la plage (« Le port doit être compris entre 1 et 65535. »); le port du serveur web, réglé sur Accès à distance (« Le port N est déjà celui du serveur web. Choisissez un autre port, ou déplacez d'abord le serveur web. »); le port de l'accès agent réglé sur la page Agent, que l'accès agent soit actif ou non (« Le port N est déjà celui de l'accès agent. Choisissez un autre port, ou déplacez d'abord l'accès agent. »); le port du serveur OPC UA sur Paramétrage, en marche ou arrêté (« Le port N est déjà celui du serveur OPC UA. Choisissez un autre port, ou déplacez d'abord le serveur. »); le port du broker MQTT sur la page Connector, en marche ou arrêté (« Le port N est déjà celui du broker MQTT. Choisissez un autre port, ou déplacez d'abord le broker MQTT. »); et un port qu'autre chose retient en ce moment sur cette machine (« Le port N est occupé sur cette machine. Fermez ce qui le retient, ou choisissez un autre port. »). Les quatre autres champs de port refusent à leur tour le port de ce serveur. La raison reste sous le champ jusqu'au prochain port que le champ accepte, ou jusqu'à ce que la ligne soit de nouveau sélectionnée.
Sous la carte, une note dit : « Répond à tout ID d'unité. Les autres machines n'atteignent ce serveur que si le pare-feu Windows laisse entrer le port TCP 502 : l'autoriser vous appartient, et cette station ne le fait jamais d'elle-même. »
Le serveur accepte au plus 16 clients à la fois : une dix-septième connexion est fermée dès qu'elle s'ouvre, et le journal technique le note. Un client qui disparaît sans fermer sa connexion (un automate éteint, un câble arraché) est détecté par le keep-alive TCP, et sa place se libère en une minute et demie environ.
Pare-feu Windows
Sous la note, un point et une phrase disent si la règle entrante propre à la station laisse entrer ce port, comme la carte Accès des clients le dit pour le port OPC UA, avec une seule action quand ce n'est pas le cas.
| État | Texte |
|---|---|
| Autorisé (vert) | « Les connexions Modbus entrantes sont autorisées sur le port N pour les réseaux privés et de domaine. » |
| Non configuré (ambre) | « Les clients du réseau sont peut-être bloqués, car aucune règle propre à l'application n'autorise le port N. » Le bouton Autoriser le réseau local est dessiné. |
| Non pris en charge (gris) | « Ce mode de lancement ne peut pas gérer le pare-feu Windows. Configurez l'accès entrant dans le système d'exploitation si nécessaire. » Un lancement de développement, portable ou de démonstration, ou toute exécution qui n'est pas l'application installée. |
| Inconnu (gris) | « L'état du pare-feu Windows n'a pas pu être déterminé. » |
| Commande | Ce qu'elle fait | Grisée quand (situation) | Non dessinée quand (rôle) |
|---|---|---|---|
| Autoriser le réseau local | Démarre l'assistant propre à l'application avec élévation, de sorte que Windows demande l'accord d'un administrateur, et ajoute la règle pour ce port, bornée aux profils Privé et Domaine, au sous-réseau local et à ce programme. Affiche « Application en cours… » pendant ce temps; le journal des actions dit « Demande d'accès au pare-feu Windows pour le port Modbus N… », puis « Le pare-feu Windows autorise désormais les connexions Modbus sur le port N. » ou le texte d'état comme erreur. Une invite d'accord annulée laisse l'état Non configuré. | Dans un navigateur sur un autre appareil (« La règle de pare-feu ne peut être appliquée que depuis l'application de bureau de la station. »), tant qu'un essai retient la station ou que le runtime est arrêté, et pendant que la règle s'applique (« La règle de pare-feu est en cours d'application. »). | Sans Configurer Connector. |
L'état est lu à l'ouverture de la carte et relu quand le port change; un nouveau port montre donc Non configuré tant que vous ne l'avez pas autorisé. La station n'ajoute jamais la règle d'elle-même.
La table des registres
La seconde carte, Table des registres, est ce que sert le serveur : chaque ligne place un tag, une variable Logic ou un état d'alarme à un registre, ou à une bobine, qu'un client adresse. Un registre qu'aucune ligne ne couvre n'existe pas pour un client. La carte dit : « Chaque ligne sert un tag, une variable Logic ou un état d'alarme à un registre. Une ligne reste en lecture seule tant que vous n'autorisez pas l'écriture, et une ligne qui sert une alarme l'est toujours. L'écriture d'un client suit alors le même chemin que toute autre et est consignée au journal technique avec l'adresse du client. »
Le tableau
| Colonne | Ce qu'elle montre |
|---|---|
| Classe de registre | Registre de maintien (4xxxx), Registre d'entrée (3xxxx), Bobine (0xxxx) ou Entrée discrète (1xxxx), chacune avec le premier chiffre que l'adresse du manuel porte pour elle. |
| Registres | Le registre où commence la ligne, compté à partir de 0, et le dernier qu'elle occupe : 0 pour une ligne d'un registre, 0-1 pour un Float. |
| Dans le manuel | Le même endroit dans la notation que le manuel ou l'outil de l'automate du client écrit : le premier chiffre de la classe puis le registre compté à partir de 1. 40001 pour le registre de maintien 0, de 40001 à 40002 pour un Float à cet endroit, six chiffres au-delà de 9999 (410000 pour le registre de maintien 9999). |
| Type de donnée | Boolean, Int16, UInt16, Int32, Float ou String. |
| Accès | Lecture seule, ou Lecture et écriture. |
| Source servie | La source, telle que le sélecteur la nomme. |
| Valeur actuelle | Ce qu'un client y lit en ce moment, ou un tiret quand un client qui lit la ligne reçoit l'exception 04. |
Les lignes sont classées par classe (registres de maintien, registres d'entrée, bobines, entrées discrètes), puis par registre. Sans aucune : « Aucun registre n'est encore servi. Ajoutez-en un avec Nouvelle ligne. » Cliquer sur une ligne la sélectionne et ouvre ses champs sous le tableau; la ligne sélectionnée appartient à la fenêtre où vous êtes.
Ce qui fait grandir le tableau et ce qui supprime une ligne se trouvent à droite du titre de la carte :
| Commande | Ce qu'elle fait | Grisée quand (situation) | Non dessinée quand (rôle) |
|---|---|---|---|
| Nouvelle ligne | Ajoute une ligne au premier registre de maintien qu'aucune ligne n'occupe : Float, les deux cases d'ordre cochées, lecture seule, encore sans source. La ligne est sélectionnée et le journal des actions dit « Ligne ajoutée en Registre de maintien (4xxxx) de 40001 à 40002. » Quand il ne reste aucun registre de maintien : « Aucun registre de maintien n'est libre pour une nouvelle ligne. » | Un essai retient la station, ou le runtime est arrêté. | Sans Configurer Connector. |
| Supprimer la ligne (encre de danger) | Supprime la ligne que le tableau a sélectionnée, aussitôt et sans question; son infobulle la nomme (« Supprimer la ligne en Registre de maintien (4xxxx) de 40001 à 40002 ») et le journal des actions dit « Ligne en Registre de maintien (4xxxx) de 40001 à 40002 supprimée. » Le tag ou la variable qu'elle servait n'est pas touché. Un client qui lit ces registres reçoit l'exception 02 à partir de ce moment. | Aucune ligne sélectionnée (« Sélectionnez une ligne de la table des registres pour la supprimer. »), un essai retient la station, ou le runtime est arrêté. | Sans Configurer Connector. |
Les champs d'une ligne
Une ligne a exactement les champs et les règles d'un tag Modbus : un point accepté à un bout du fil est accepté à l'autre. Chaque champ est enregistré au moment où il change (un nombre quand vous quittez le champ ou appuyez sur Entrée, un choix quand vous choisissez, une case quand vous la cochez), et un client reçoit la nouvelle ligne dès sa requête suivante, sans être déconnecté.
| Champ | Ce qu'il fait | Valeurs et défaut |
|---|---|---|
| Classe de registre | Dans quelle table Modbus la ligne répond. Choisir une bobine ou une entrée discrète fait passer le type à Boolean; choisir un registre d'entrée ou une entrée discrète met la ligne en lecture seule. | Registre de maintien (4xxxx), Registre d'entrée (3xxxx), Bobine (0xxxx), Entrée discrète (1xxxx). Registre de maintien pour une nouvelle ligne. |
| Numéro de registre (base 0) | Où commence la ligne, le numéro tel qu'il voyage dans la requête : le registre de maintien 0 est celui que la notation classique appelle 40001. À côté, Adresse dans le manuel lit la ligne dans cette notation, comme la colonne Dans le manuel. | De 0 à 65535. Le premier registre de maintien libre pour une nouvelle ligne. |
| Type de donnée | Comment la valeur est disposée, comme un tag Modbus la dispose (Types de valeur et quantités) : Boolean dans un registre (1 ou 0) ou comme un bit, Int16 et UInt16 dans un registre, Int32 et Float dans deux, String en UTF-8 à deux octets par registre. Une bobine et une entrée discrète ne portent qu'un Boolean. Choisir Boolean sur une ligne de registre la déplace vers une entrée discrète (lecture seule) ou une bobine (lecture et écriture); choisir un nombre sur une bobine ou une entrée discrète la déplace vers un registre d'entrée ou un registre de maintien, comme le fait le volet d'un tag Modbus. | Boolean, Int16, UInt16, Int32, Float, String. Float pour une nouvelle ligne. |
| Longueur (registres) | Dessiné pour un String seulement : combien de registres le texte occupe. | Vide signifie 4. De 1 à 65535. |
| Octet de poids fort en premier (MSB first, gros-boutiste) | Quel octet de chaque registre voyage en premier; les mots entre parenthèses sont ceux que les manuels impriment. Non dessiné pour un String, ni pour une bobine ou une entrée discrète. | Cochée. |
| Mot de poids fort en premier (mot haut en premier) | Quel registre de la paire porte la moitié haute. Dessiné pour Int32 et Float seulement. Les deux cases cochées, un Float voyage en AB CD, l'ordre de la spécification (Ordre des octets et des mots); Ordre des octets de la valeur, sous les cases, nomme la disposition qu'elles forment (ABCD, CDAB, BADC ou DCBA). |
Cochée. |
| Accès | Si un client peut écrire la ligne. Sur un registre d'entrée ou une entrée discrète, Lecture et écriture reste dans la liste, grisé, avec l'infobulle « Seuls un registre de maintien ou une bobine acceptent une écriture. » Sur une ligne qui sert une alarme, il est grisé aussi : « Une ligne qui sert une alarme est en lecture seule. » | Lecture seule ou Lecture et écriture. Lecture seule pour une nouvelle ligne. |
| Source servie | Ce que sert la ligne. La liste s'ouvre sur « (aucun) », puis chaque tag activé d'un équipement activé, nommé d'après son pilote, son équipement et lui-même (« Tag Connector · Simulated · Oven · Temperature »), puis chaque variable Logic qui porte une valeur (Booléen, Entier, Décimal, Texte ou Date et heure) par son nom (« Variable Logic · Setpoint ») ou, rangée dans un dossier, par ses dossiers et son nom (« Variable Logic · Oven / Setpoint »), de sorte que deux variables du même nom se distinguent. Puis chaque alarme, nommée de la même façon (« Alarme Logic · Oven / High temperature »); une ligne qui sert une alarme est toujours en lecture seule, et sert l'état que désigne État de l'alarme servi. La ligne tient sa source par son identité : renommer le tag ou la variable, ou ranger son équipement dans un dossier, laisse la ligne sur le même point. Une source que la liste n'offre plus reste sélectionnée et nommée : un tag désactivé comme « Tag Connector · Simulated · Oven · Temperature (désactivé) », un tag d'un équipement désactivé comme « Tag Connector · Simulated · Oven · Temperature (équipement désactivé) », et seule une source qui n'existe plus est nommée Tag Connector manquant ou Variable Logic manquante avec son identité. La carte Utilisé par d'un tag liste les lignes qui le servent, et son Tout remplacer les déplace vers le tag choisi. | « (aucun) » pour une nouvelle ligne. |
| État de l'alarme servi | Affiché pour une ligne qui sert une alarme : lequel de ses états un client lit. Active (booléen) vaut 1 tant que la condition est vraie, Acquittée (booléen) vaut 1 tant que rien n'attend d'acquittement, et État (nombre) est l'état en nombre. | Active (Boolean) pour une nouvelle ligne d'alarme. |
Sous les champs, trois lignes relisent la ligne : où elle se trouve (« Occupe le registre 0. » ou « Occupe les registres 0 à 1. »), ce qu'un client peut en faire (« Un client peut lire cette ligne mais pas l'écrire. » ou « Un client peut lire et écrire cette ligne : chaque écriture est consignée au journal technique avec son adresse. », ou « Un client lit cet état de l'alarme et ne l'écrit jamais. En nombre, 0 est normale, 1 active non acquittée, 2 active acquittée, 3 retombée non acquittée. » pour une ligne qui sert une alarme), et ce qu'un client y lit en ce moment (« Valeur actuelle : 21.5 »). Quand un client qui lit la ligne ne recevrait aucune valeur, la raison suit :
| Le volet dit | Quand |
|---|---|
| « Cette ligne ne sert encore rien : choisissez sa source. » | Aucune source n'est choisie. |
| « La source de cette ligne n'existe plus. Un client qui la lit reçoit l'exception 04. » | Le tag ou la variable a été supprimé. |
| « La source n'a pas de valeur valide en ce moment. Un client qui lit cette ligne reçoit l'exception 04 jusqu'à ce qu'elle en ait une. » | Le tag n'a pas de valeur valide (son équipement ne répond pas et le tag ne présente pas de valeur de remplacement, le tag ou son équipement est désactivé, un défaut de limite a rendu sa qualité mauvaise), ou la variable est un vide. |
| « La valeur de la source ne tient pas dans le type de cette ligne. Un client qui la lit reçoit l'exception 04. » | Une valeur qu'aucune ligne de ce type ne peut porter : un NaN dans une ligne entière, ou un texte plus long que les registres de la ligne. |
Ce qu'une ligne refuse
Une modification que les règles du serveur refusent n'est pas enregistrée : la raison s'affiche en rouge au-dessus des champs de la ligne, la modification reste à l'écran pour que vous la corrigiez, et la ligne continue de servir ce qu'elle servait jusqu'à ce qu'une modification soit acceptée. Les autres lignes ne sont pas touchées.
| Le volet dit | Quand |
|---|---|
| « Le numéro de registre doit être compris entre 0 et 65535. » | Un registre hors de la plage du protocole. |
| « Un point Modbus porte Boolean, Int16, UInt16, Int32, Float, String. » | Un type hors de ces six, que seul un agent peut demander. |
| « Une bobine ou une entrée discrète porte un Boolean. » | Un nombre dans une bobine ou une entrée discrète, que seul un agent peut demander. |
| « Un texte occupe de 1 à 65535 registres. » | Une longueur de String hors de la plage. |
| « Les registres 65535 à 65536 dépassent le registre 65535. » | Une ligne qui finirait après le dernier registre : ici un Float en 65535. |
| « Les registres 40001 à 40002 chevauchent la ligne en Registre de maintien (4xxxx) 40002. » | Deux lignes de la même classe qui partagent un registre. |
| « Un registre d'entrée ou une entrée discrète est en lecture seule pour un client : seuls un registre de maintien ou une bobine acceptent une écriture. » | L'écriture autorisée sur une classe d'entrée, que seul un agent peut demander. |
| « Une ligne qui accepte des écritures a besoin du tag ou de la variable qui les reçoit. » | Lecture et écriture choisi avant une source, ou la source remise à « (aucun) » sur une ligne qui autorise l'écriture. Choisissez d'abord la source. |
| « La source ne peut pas être écrite : choisissez un tag accessible en écriture ou une variable mémoire, ou laissez la ligne en lecture seule. » | L'écriture autorisée sur une ligne dont la source est un tag en lecture seule, un tag d'un pilote qui n'écrit jamais, une variable expression ou une source qui n'existe plus. |
| « La source contient un texte ou une date, que seule une ligne String porte. » | Un tag de texte ou de date, ou une variable Texte ou Date et heure, dans une ligne de tout autre type. |
| « Une ligne qui sert une alarme est en lecture seule : un client lit l'état de l'alarme et ne l'écrit jamais. » | Lecture et écriture demandée sur une ligne qui sert une alarme, ce que seul un agent peut demander. |
| « Cette ligne de la table des registres n'existe plus. Rechargez et réessayez. » | La ligne a été supprimée ailleurs, dans une autre fenêtre ou par un agent, pendant que vous la modifiiez. |
Tant qu'un essai retient la station ou que le runtime est arrêté, une modification est refusée comme toute modification de la page, avec la raison dans le journal des actions (« La configuration est verrouillée tant qu'une unité est en cours. », « Runtime arrêté »), et rien n'est enregistré.
Ce qu'un client lit et écrit
Le serveur répond à tout ID d'unité, et répond avec l'ID d'unité avec lequel on l'a interrogé : en TCP, une station s'adresse par son adresse IP. Les numéros de registre voyagent comptés à partir de 0. Un outil d'automate qui compte à partir de 1, ou qui écrit la notation classique, ajoute lui-même le décalage :
| Classe de registre | Lire avec la fonction | Écrire avec la fonction | Registre 0 dans la notation classique |
|---|---|---|---|
| Registre de maintien (4xxxx) | 3 | 6 (un registre) ou 16 (plusieurs) | 40001 |
| Registre d'entrée (3xxxx) | 4 | aucune : lecture seule | 30001 |
| Bobine (0xxxx) | 1 | 5 (une bobine) ou 15 (plusieurs) | 00001 |
| Entrée discrète (1xxxx) | 2 | aucune : lecture seule | 10001 |
Tout autre code de fonction reçoit l'exception 01. Une requête lit au plus 125 registres ou 2000 bobines ou entrées, et écrit au plus 123 registres ou 1968 bobines.
Une lecture reçoit une réponse entière ou aucune. Chaque valeur est lue dans l'état courant de la station, jamais évaluée pour le client : un tag sert sa valeur physique, celle que la station montre après la chaîne de conversion, une variable sert sa valeur, et une alarme l'état que sa ligne désigne. La valeur est convertie dans le type de la ligne par la conversion unique de la station : un réel est arrondi à l'entier le plus proche pour une ligne entière (les moitiés loin de zéro) et tenu aux bornes du type, si bien qu'une ligne Int16 sert 32767 pour 40000. Une lecture peut demander une partie d'une ligne de deux registres : elle reçoit les registres demandés, tels que la valeur encodée les porte. Une ligne dont la source n'a pas de valeur valide ne reçoit jamais une dernière valeur que le serveur aurait gardée : un registre ne porte pas de qualité, et un automate qui lirait un ancien nombre agirait sur une valeur que la station sait périmée. Le client reçoit l'exception 04 à la place, et son propre traitement des défauts de communication décide; le prix est qu'une ligne sans valeur fait échouer une lecture en bloc qui la couvre, et la colonne Valeur actuelle de la table montre laquelle. Un tag qui présente sa propre valeur de remplacement (la dernière valeur valide maintenue, ou un nombre déclaré, réglé dans son étape Lecture non valide) garde une valeur valide, et la valeur de remplacement est servie comme n'importe quelle valeur.
L'écriture d'un client passe par le même canal d'écriture unique que toute autre (voir Logic) : un tag par la file de livraison de son équipement, sa valeur physique ramenée par la conversion du tag, et une variable mémoire par la file de Logic. Les verrous de source s'appliquent : une source que retient une recette ou un verrouillage Process en cours est refusée. Le canal d'écriture consigne au journal technique chaque valeur, de l'ancienne à la nouvelle, sous la source Modbus client 192.168.0.20:51234, et la réponse attend l'accusé de chaque valeur, qui pour un tag est la réponse de l'équipement lui-même.
- Une écriture couvre des lignes entières : écrire un seul registre d'une ligne Float est refusé, si bien qu'un Float s'écrit avec la fonction 16 et un nombre de 2.
- Chaque ligne que l'écriture atteint est vérifiée contre la table avant qu'aucune valeur ne parte : un registre hors de toute ligne, ou une ligne en lecture seule, refuse la requête entière, et rien n'est écrit.
- Les valeurs partent ensuite vers leurs sources dans l'ordre des registres. Un refus que le canal d'écriture oppose à l'une d'elles est la réponse que reçoit le client, bien que les autres lignes de la même requête aient aussi été transmises.
| Exception | Quand |
|---|---|
| 01 (fonction illégale) | Un code de fonction autre que 1, 2, 3, 4, 5, 6, 15 et 16. |
| 02 (adresse de donnée illégale) | Un registre hors de toute ligne; une écriture sur une ligne en lecture seule ou sur une partie de ligne; une plage qui dépasse 65535; une source que le canal d'écriture déclare impossible à écrire. |
| 03 (valeur de donnée illégale) | Un nombre hors de la plage ou une requête mal formée; une bobine écrite avec autre chose que marche ou arrêt; une valeur que la source ne peut pas prendre. |
| 04 (défaillance de l'équipement serveur) | Une source sans valeur valide, une source qui n'existe plus, ou une valeur que la ligne ne peut pas porter; une écriture que l'équipement a refusée ou à laquelle il n'a pas répondu, ou un équipement qui n'est pas connecté. |
| 06 (équipement serveur occupé) | Une source que retient un Process en cours, ou le runtime en train de s'arrêter. |
Un exemple complet
Un automate lit dans la station la température d'un four et le contact de sa porte, et écrit la consigne du four, une variable mémoire Variables.Oven.Setpoint. Dans le volet :
- Sélectionnez la ligne Serveur Modbus et appuyez sur Nouvelle ligne. Réglez Classe de registre sur Registre d'entrée (3xxxx) (le registre reste à 0) et Source servie sur « Tag Connector · Simulated · Oven · Temperature ». La ligne dit « Occupe les registres 0 à 1. », Adresse dans le manuel affiche de 30001 à 30002, et la colonne Valeur actuelle montre la température.
- Appuyez de nouveau sur Nouvelle ligne, réglez Classe de registre sur Entrée discrète (1xxxx) (le type devient Boolean et le registre reste à 0) et choisissez le contact de la porte, « Tag Connector · Simulated · Oven · DoorOpen ».
- Appuyez une troisième fois sur Nouvelle ligne. Elle arrive au registre de maintien 0, en Float. Choisissez d'abord « Variable Logic · Oven / Setpoint », puis réglez Accès sur Lecture et écriture : la ligne dit « Un client peut lire et écrire cette ligne : chaque écriture est consignée au journal technique avec son adresse. »
- Appuyez sur Activer dans la barre de commandes : la ligne dit « À l'écoute sur le port 502 ». Pour un automate d'une autre machine, appuyez ensuite sur Autoriser le réseau local dans la carte Port et clients.
Ce que l'automate demande, les deux cases d'ordre cochées (un Float voyage en gros-boutiste, mot de poids fort en premier, ABCD) :
| Valeur | Fonction | Adresse | Nombre | Notation classique |
|---|---|---|---|---|
| Température (lecture) | 4 | 0 | 2 | 30001-30002 |
| Contact de porte (lecture) | 2 | 0 | 1 | 10001 |
| Consigne (écriture) | 16 | 0 | 2 | 40001-40002 |
| Consigne (relecture) | 3 | 0 | 2 | 40001-40002 |
La même chose avec un agent, par les quatre outils des domaines du Connector :
modbus_map_upsert(source: "Connector.Simulated.Oven.Temperature", registerClass: "InputRegister", register: 0, type: "Float")
modbus_map_upsert(source: "Connector.Simulated.Oven.DoorOpen", registerClass: "DiscreteInput", register: 0)
modbus_map_upsert(source: "Variables.Oven.Setpoint", registerClass: "HoldingRegister", register: 0, type: "Float", access: "ReadAndWrite")
modbus_server_configure(enabled: true)
Une ligne créée par un agent est en lecture seule sauf si access dit autre chose, et une bobine ou une entrée discrète est Boolean quand aucun type n'est donné. modbus_server_status relit tout le serveur : son état, ses clients et chaque ligne avec ce qu'un client y lit en ce moment. Les outils sont décrits dans Les outils, domaine par domaine.
Permissions et verrous
| Permission | Ce qu'elle ouvre ici |
|---|---|
| Voir Connector | La ligne, le volet et la table des registres, en lecture seule. Les cartes sont tenues inertes sous la note « Modifier le Connector demande la permission « Configurer Connector ». », et aucun verbe n'est dessiné : ni Activer, ni Désactiver, ni Nouvelle ligne, ni Supprimer la ligne. |
| Configurer Connector | Tout ce qui est sur la page : mettre le serveur en marche et l'arrêter, son port et chaque ligne de la table. |
Tant qu'un essai retient la station ou que le runtime est arrêté, les verbes restent dessinés et grisés avec la raison, et toute modification est refusée, comme partout sur la page Connector. La lecture du volet, et celle du serveur par les clients, continuent. Un agent ne modifie le serveur que par le domaine de configuration du Connector de l'accès agent, et chaque modification qu'il fait est consignée comme la sienne.
Le journal technique
Le serveur écrit sur la Console des Événements sous le domaine Server, composant Modbus server : quand il commence et cesse d'écouter, un port qu'il n'a pas pu ouvrir, une connexion qu'il a fermée parce qu'il servait déjà 16 clients, et chaque requête qu'il a refusée, avec son code d'exception. Un refus qui se répète, comme celui d'un automate qui interroge à chaque cycle un registre absent de la table, est écrit la première fois, résumé toutes les quelques minutes tant qu'il dure, et clos par une ligne quand le client est de nouveau servi. Les connexions et déconnexions sont du détail, gardé pour la capture détaillée. Chaque modification des réglages du serveur ou de sa table est aussi consignée, qu'elle vienne de la page ou d'un agent. Ce qu'a fait l'écriture d'un client est la ligne du canal d'écriture lui-même, sous la source Modbus client <address>:<port>.
Ce que le serveur ne fait pas
- Il ne sert que Modbus TCP, avec l'en-tête MBAP. Il n'y a pas de serveur Modbus RTU ou ASCII sur une ligne série, ni de trames RTU sur TCP.
- Il n'ouvre jamais le pare-feu Windows de lui-même (seul Autoriser le réseau local le fait, quand vous appuyez dessus), et il ne peut pas écouter sur une seule carte réseau : il écoute sur chaque adresse de l'ordinateur, sur un port.
- Il répond à tout ID d'unité avec la même table unique : il ne peut pas héberger plusieurs unités avec des tables différentes.
- Il n'a ni utilisateur, ni mot de passe, ni chiffrement, parce que Modbus n'en a pas : qui atteint le port lit chaque ligne et écrit chaque ligne qui autorise l'écriture. Laissez les lignes en lecture seule sauf si un client doit les écrire, et gardez le port fermé aux réseaux qui n'ont rien à y faire.
- Il ne se connecte jamais à rien. Pour lire un équipement Modbus, ajoutez-le sous le pilote Modbus TCP ou Modbus RTU.
- Il ne garde aucun registre à lui : un registre qu'aucune ligne ne couvre n'existe pas, et tout ce qu'un client écrit aboutit dans un tag ou une variable.
- Il ne garde jamais de valeur à lui pour la servir à la place d'une valeur absente, et il n'exécute aucun des autres codes de fonction (Read/Write Multiple Registers, Mask Write Register, identification de l'équipement) : ils reçoivent l'exception 01.
- La table n'a ni import ni export à elle : elle voyage avec la configuration de la station dans les sauvegardes.