Modbus RTU vers MQTT : correspondance des registres, ordre des octets et mise à l’échelle

Une intégration fiable de Modbus RTU vers MQTT exige un contrat explicite entre la table des registres d’un appareil et l’application qui exploite ses mesures. Une réponse série réussie prouve que les octets sont arrivés. La mise en service doit également établir ce que ces octets signifient et si la valeur obtenue est encore actuelle.

Ce guide porte sur la télémétrie en lecture seule : conversion d’adresses, codes de fonction, valeurs signées, mise à l’échelle, ordre des registres pour les valeurs multiregistres et fraîcheur des données MQTT. Toutes les affectations de registres, valeurs et charges utiles ci-dessous sont des exemples illustratifs ; il ne s’agit ni de spécifications de produits Obeita ni de mesures sur le terrain.

Commencez par une lecture RTU validée

Rassemblez le modèle de l’appareil, la version du micrologiciel, la révision de la table des registres, les paramètres série, l’adresse de la station et une valeur de référence connue. Vérifiez le câblage RS-485, la terminaison et la polarisation à l’aide de la documentation d’installation. Assurez-vous que seul le maître prévu contrôle le bus. Résolvez les dépassements de délai et les erreurs de CRC avant de tenter de corriger les valeurs par une mise à l’échelle.

Le guide Modbus sur liaison série définit le format des trames RTU, les contraintes temporelles et le contrôle des erreurs. Un système d’interrogation en production doit respecter ces exigences ainsi que les limites de réponse de l’appareil. Commencez par un point documenté ; n’élargissez l’ensemble des points interrogés qu’une fois sa réponse brute et sa valeur décodée concordantes.

Déterminez ensemble l’adresse du registre et le code de fonction

La spécification du protocole d’application Modbus utilise des adresses PDU à base zéro. Le code de fonction 03 lit les registres de maintien ; le code de fonction 04 lit les registres d’entrée. Ce sont des tables logiques distinctes. Un même décalage numérique ne permet pas de conclure que les deux fonctions renvoient la même mesure.

Dans la notation conventionnelle des documentations, 40001 désigne le premier registre de maintien et 30001 le premier registre d’entrée. Le premier chiffre identifie la table ; il ne fait pas partie de l’adresse PDU transmise. Consultez les explications de la Modbus Organization sur l’adressage.

Entrée illustrative du manuel Fonction Adresse PDU de départ
Registre de maintien 40011 03 10 en décimal, 0x000A
Registre d’entrée 30011 04 10 en décimal, 0x000A

Avec cette convention, 40011 − 40001 = 10. Les manuels peuvent toutefois fournir directement des décalages à base zéro, des numéros de registre à base un ou des adresses hexadécimales. Les interfaces des passerelles peuvent appliquer leur propre conversion. Consignez à la fois la notation du manuel et le décalage PDU réel ; ne soustrayez jamais un automatiquement. Ne remplacez pas FC03 par FC04 pour obtenir un nombre plausible, sauf si la documentation de l’appareil prévoit explicitement cette correspondance.

Pour le premier exemple, le PDU de requête est 03 00 0A 00 01 : fonction 03, adresse de départ 10, quantité un. Il s’agit uniquement du PDU, et non d’une trame RTU complète ; l’adresse de la station et le CRC sont omis.

Décodez les valeurs signées avant d’appliquer la mise à l’échelle

Créez une définition de point contenant l’adresse de la station, la fonction, le décalage PDU, le nombre de registres, le type de données, l’ordre des mots, le facteur d’échelle, le décalage de valeur, l’unité, les règles de valeurs invalides et la limite de fraîcheur. Conservez les mots bruts des registres dans les journaux de mise en service afin qu’un autre ingénieur puisse reproduire la conversion.

Supposons que le point illustratif représente une température signée sur 16 bits, avec un facteur d’échelle de 0.1 °C et un décalage nul. Un mot de réponse 0xFF9C vaut 65436 lorsqu’il est lu comme une valeur non signée. Son interprétation signée en complément à deux est 65436 − 65536 = −100. Appliquez la mise à l’échelle après le décodage :

engineering_value = decoded_value × scale + offset
                  = -100 × 0.1 + 0
                  = -10.0 °C

Un décodeur non signé publierait à la place 6543.6 °C. Modifier le facteur d’échelle pour masquer ce résultat laisserait intacte l’erreur de type sous-jacente. Testez les valeurs positives, négatives et limites. Vérifiez les codes invalides définis par le fabricant avant la mise à l’échelle ; une valeur sentinelle ne doit pas devenir une mesure apparemment crédible.

Illustrative Modbus mapping from holding register 40011 to FC03 offset 10, signed word FF9C and an MQTT temperature value of minus 10.0 degrees Celsius.
Figure 1. Gardez la convention d’adressage, le décodage signé et l’échelle en unités physiques explicites tout au long de la correspondance.

Distinguez l’ordre des octets sur 16 bits de l’ordre des mots sur plusieurs registres

Dans un registre Modbus standard de 16 bits, l’octet de poids fort est transmis en premier. Ainsi, 0x4148 apparaît sous la forme 41 48. Le CRC RTU est un champ distinct dont l’octet de poids faible est envoyé en premier ; son ordre ne constitue pas une règle de décodage des registres.

Une valeur applicative de 32 bits occupe deux registres, mais l’agencement des mots dépend de l’appareil. L’exemple de Schneider Electric sur les flottants à mots permutés montre pourquoi il faut parfois réordonner les mots de poids fort et de poids faible.

Pour la valeur illustrative exacte 12.5 au format IEEE 754 float32, la représentation binaire est 0x41480000. Une table plaçant le mot de poids fort en premier renvoie 0x4148, 0x0000 ; une table plaçant le mot de poids faible en premier renvoie 0x0000, 0x4148. Réordonnez les mots selon le manuel, puis réinterprétez les bits assemblés comme un float32. Convertir numériquement l’entier assemblé en un nombre à virgule flottante est une opération différente.

Two illustrative register layouts for IEEE 754 float32 12.5, showing high-word-first and low-word-first mappings while each register retains high-byte-first transmission.
Figure 2. Les deux agencements représentent 12.5 lorsque le décodeur utilise l’ordre des mots documenté.

Une option de passerelle nommée « little endian » peut être ambiguë. Documentez précisément la permutation des mots et des octets qu’elle applique. Certaines tables de fabricants définissent également des permutations d’octets au niveau applicatif ; vérifiez-les explicitement. Lisez les mots associés dans une seule requête lorsque cela est pris en charge, et vérifiez si l’appareil garantit un instantané cohérent pendant les mises à jour.

Publiez la fraîcheur et la qualité avec la valeur MQTT

Attribuez à chaque mesure un nom de point stable, une unité, un état de qualité et un horodatage dont la signification est précisée. Si l’appareil ne fournit pas d’horodatage d’acquisition, indiquez clairement qu’il s’agit de l’heure de lecture réussie par la passerelle. Une heure de publication ultérieure ne doit pas masquer l’ancienneté d’un échantillon.

Cette charge utile applicative illustrative utilise l’heure de fin de lecture par la passerelle et une séquence limitée à chaque démarrage :

{
  "schema_version": 1,
  "device_id": "example-device-07",
  "point": "temperature",
  "value": -10.0,
  "unit": "degC",
  "quality": "good",
  "read_completed_at": "2026-10-03T12:00:00Z",
  "time_source": "gateway_read",
  "boot_id": "example-boot-01",
  "sequence": 1042
}

Définissez ce qui se passe après une interrogation manquée : par exemple, conserver l’horodatage de la dernière mesure valide tout en signalant une qualité périmée, ou publier une valeur explicitement indisponible. Précisez un seuil de péremption adapté au procédé, les exigences de synchronisation des horloges et les limites des files d’attente. Lors de la retransmission d’échantillons mis en mémoire tampon, conservez leurs heures de lecture d’origine.

Les messages MQTT conservés peuvent aider un nouvel abonné à obtenir le dernier état publié, mais leur conservation n’en garantit pas la fraîcheur. La fonction Message Expiry de MQTT 5 peut limiter la durée de vie des messages en file d’attente ; les applications consommatrices doivent toujours vérifier leur ancienneté au niveau applicatif. Consultez les sections 3.3 et 4.3 de MQTT 5.0.

Choisissez le QoS sans promettre un traitement exactement une fois de bout en bout

MQTT QoS 0 assure une livraison au plus une fois, QoS 1 une livraison au moins une fois et QoS 2 une livraison exactement une fois dans le cadre de son échange protocolaire. La spécification limite cette livraison à un seul émetteur et un seul récepteur ; la livraison du broker à l’abonné constitue un échange distinct. QoS 2 ne peut pas, à lui seul, garantir une unique acquisition de capteur ou mise à jour de base de données dans l’ensemble du système.

Concevez les écritures de l’application consommatrice pour qu’elles soient idempotentes lorsque les doublons ont de l’importance. Une clé applicative combinant l’appareil, l’identifiant de démarrage et la séquence peut permettre la déduplication si ses règles d’unicité et de persistance sont définies. Testez les reconnexions et les nouvelles tentatives en aval avec la configuration réelle du broker, du client et du stockage.

Liste de contrôle de mise en service

  • Comparez le PDU de requête à la table d’adressage approuvée, en vérifiant notamment le choix entre FC03 et FC04.
  • Vérifiez les mots bruts à l’aide d’une indication connue de l’appareil avant d’activer les calculs dans le cloud.
  • Testez les valeurs négatives, les codes invalides, les changements d’ordre des mots et les interrogations partiellement échouées.
  • Déconnectez séparément l’appareil série et le broker ; vérifiez que les données périmées restent identifiables.
  • Redémarrez la passerelle et l’application consommatrice ; vérifiez l’ancienneté des données retransmises, la gestion des doublons et le comportement de la séquence.
  • Consignez le micrologiciel testé, la révision de la table, le schéma de charge utile et les résultats de réception.

Préparez une revue des exigences pour Modbus RTU vers MQTT

Pour discuter d’une intégration avec Obeita, préparez les pages pertinentes du manuel de l’appareil, un exemple de trame de requête/réponse, les valeurs attendues en unités physiques, le nombre de points, l’intervalle d’interrogation, les exigences relatives au broker et le comportement en cas d’interruption. Masquez les mots de passe, les clés, les identifiants clients, les détails de réseaux privés et les données propriétaires que vous n’êtes pas autorisé à partager. Ces éléments permettent de définir et de tester la correspondance avant de s’engager sur une configuration de passerelle.

Découvrez le service de connexion des équipements existants d’Obeita et le projet réalisé d’acquisition de données sur STM32 et d’intégration MQTT (en anglais) pour situer les prestations d’ingénierie associées. Pour discuter de vos propres besoins de correspondance des registres, contactez Obeita.

Sources primaires

  1. Spécification du protocole d’application Modbus V1.1b3. Sections pertinentes : 4.2, 4.3, 4.4, 6.3, 6.4.
  2. Introduction à Modbus – Modbus Organization. Sections pertinentes : adressage des données Modbus et fonction 03.
  3. Modbus sur liaison série : spécification et guide de mise en œuvre V1.02. Sections pertinentes : 2.2, 2.5.1, 3.
  4. Schneider Electric – Lire des valeurs à virgule flottante à mots permutés dans Modbus. Section pertinente : résolution.
  5. MQTT version 5.0 – Norme OASIS. Sections pertinentes : 3.3.1.3, 3.3.2.3.3, 4.3.

Publications similaires