Petite introduction à RS485 et MODBUS

Petite introduction à RS485 et MODBUS

En discutant avec nos clients sur la meilleure manière d'interfacer des contrôleurs industriels, nous nous sommes rendu compte que de nos jours, les petits secrets permettant d'utiliser une interface RS485 étaient parfois méconnus des ingénieurs mettant en place les solutions d'automatisation basées PC ou internet. Voici donc un cours de rattrapage accéléré...


Qu'est-ce que RS485 ?


RS485 est un standard de transmission série, un peu comme RS232, mais qui utilise d'autres signaux électriques. Un avantage important de RS485 est que l'on peut mettre plusieurs appareils RS485 sur le même bus. Il n'est donc pas nécessaire de multiplier les interfaces RS485 sur l'hôte pour interroger plusieurs appareils. Par contre, il y a une petite subtilité pour permettre cela: à chaque extrémité du bus, il faut mettre un terminateur de bus. Parfois cela revient à visser une petite résistance sur un bornier, ou simplement à positionner un switch dans la position adéquate.

Un bus RS485 se résume souvent à deux fils et une résistance aux bouts...
Un bus RS485 se résume souvent à deux fils et une résistance aux bouts...


RS485 et RS232 ne sont pas directement compatibles: il faut utiliser le bon type d'interface, sinon les signaux ne passent pas. Il existe bien des passerelles RS232 vers RS485, mais elles ne présentent aucun intérêt de nos jours: autant utiliser directement une interface RS485 vers USB, vers Ethernet ou vers GSM, cela revient moins cher et ça évite de rajouter un composant dans le système.

La principale particularité dans l'utilisation de RS485 réside dans le format des données échangées. Alors qu'avec RS232 de nombreux appareils utilisent simplement des échanges en texte (ASCII), avec RS485 la plupart des appareils utilisent le protocole MODBUS. Il faut donc généralement connaître un minimum MODBUS pour interfacer un appareil RS485.

Qu'est-ce que MODBUS ?


MODBUS est un protocole entre un hôte (le maître) et des appareils (les esclaves) pour accéder à la configuration des appareils et lire les mesures. Les messages MODBUS correspondent à des opérations relativement simples de lecture et écriture de mots de 16 bits et de registres binaires (souvent appelés "coils"). Il s'agit systématiquement d'un échange initié par l'hôte, et auquel l'appareil "esclave" répond. L'esclave n'envoie aucun message avant d'être sollicité par l'hôte.

Comme il peut y avoir plusieurs appareils branchés en parallèle sur le bus RS485, chaque appareil esclave doit utiliser un identifiant MODBUS unique sur le bus (Slave ID). Chaque requête MODBUS commence par le Slave ID de l'appareil à qui il est destiné, et chaque réponse commence par le Slave ID de l'esclave qui l'a envoyée. Donc pour que la communication MODBUS fonctionne, il faut vérifier dans la configuration de l'appareil quelle est son Slave ID, et le changer si nécessaire. Au passage, il faut aussi vérifier la vitesse de communication et la parité (même principe que RS232).

Les messages MODBUS ne peuvent pas facilement être composés "à la main", comme on peut le faire avec les protocoles ASCII utilisés sur RS232: chaque message se termine par un code checksum, calculé d'après le contenu complet du message. Pour échanger des messages MODBUS, il faut donc utiliser:

  • soit un programme spécifique fourni par le vendeur de l'appareil, avec une interface compatible;
  • soit une interface RS485 tout bête avec une librairie de programmation qui construit et décode les messages MODBUS;
  • soit une interface RS485 intelligente capable d'encoder et de décoder elle-même les messages MODBUS, comme le Yocto-RS485.


Notez encore qu'il existe deux variantes de MODBUS: le mode MODBUS ASCII, où les messages sont échangés sous forme de lignes de codes hexadécimaux, et le mode MODBUS RTU, où les messages sont échangés directement sous forme de trames binaires. Pour dialoguer avec un équipement MODBUS, vous devez impérativement utiliser le même mode que configuré dans l'équipement. Tous les appareils conformes au standard sont censés supporter le mode MODBUS RTU. En pratique, c'est toujours ce mode qui est utilisé: le MODBUS ASCII n'a aucun avantage puisque les messages sont dans tous les cas difficiles à forger à la main.

Un petit contrôleur de température PID, fuzzy logic, etc avec interface MODBUS sur RS485
Un petit contrôleur de température PID, fuzzy logic, etc avec interface MODBUS sur RS485


Accéder aux registres MODBUS


Une fois que l'on a compris comment théoriquement échanger des informations, il reste à savoir quel registre demander à l'appareil pour obtenir les mesures, et quel registre modifier pour changer sa configuration. A ce niveau, les adresses des registres changent d'un appareil à l'autre, mais il y a des conventions MODBUS utiles à connaître pour savoir décoder les manuels techniques, dont la clarté laisse souvent à désirer.

Il existe 4 types de registres MODBUS:

  • Les coils, qui correspondent à des sorties binaires on/off, comme des relais.
  • Les input bits, qui correspondent à des entrées binaires (lecture seule).
  • Les input registers, qui correspondent à des entrées analogiques (lecture seule).
  • Les holding registers, qui correspondent à des paramètres analogiques modifiables.


Le manuel technique d'un appareil MODBUS contient normalement une liste de tous les registres disponibles, listés par type. A chaque type de registre correspond une plage de numéro de registre, selon la convention suivante:

  • Les coils sont numérotés à partir de 00001
  • Les input bits sont numérotés à partir de 10001
  • Les input registers sont numérotés à partir de 30001
  • Les holding registers sont numérotés à partir de 40001

Attention, notez que lorsqu'on utilise cette convention, le premier registre de chaque catégorie fini toujours par le chiffre 1 (le zéro n'est pas utilisé).

Parfois, plutôt que d'indiquer le numéro de registre unique, le vendeur indique le type de registre au moyen de l'identifiant de la fonction MODBUS qui permet de les lire:

  • 01h pour les coils
  • 02h pour les input bits
  • 04h pour les input registers
  • 03h pour les holding registers

Dans ce cas c'est souvent la position relative du registre dans son groupe qui est indiquée, avec la position 0 pour le premier élément. Ainsi, le registre 0 de la fonction 04h correspond au premier input register, qu'on peut aussi appeler le registre 30001. Prenez garde à ne pas vous faire piéger par l'incohérence entre les plages de registres qui ne correspondent pas aux identifiants de fonctions MODBUS, et l'incohérence des positions relatives qui commencent à 0 alors que les positions absolues commencent par 1...

Une fois que l'on sait quel registre accéder, il faut encore savoir comment l'interpréter. Comme les registres analogiques sont codés sur 16 bits, on trouve en général deux conventions. La première consiste à utiliser une plage de valeur définie dans la configuration de l'appareil, et faire correspondre linéairement la valeur 0-65535 du registre à cette plage de valeur. La deuxième consiste à stocker directement une valeur en virgule fixe décimale, en engineering unit: par exemple 2345 pour représenter 23.45 degrés C. Certains fabricants offrent simultanément les valeurs dans les deux formats: par exemple on utilise le registre 30001 pour la version proportionnelle à la plage définie, et le registre 31001 si l'on veut la version décimale.

Un exemple concret


Voyons concrètement comment on peut accéder à la mesure de température et la consigne d'un contrôleur de température Schneider Electric Zelio REG48. Voici un extrait du manuel technique

Extrait de la table de registres du contrôleur Zelio REG48
Extrait de la table de registres du contrôleur Zelio REG48


Si vous avez bien suivi, vous aurez compris qu'il s'agit d'input registers. Le registre de base est au format proportionnel, et celui à l'offset 1000 est en unité décimale. Si vous utilisez un Yocto-RS485 vous pourrez donc y accéder à l'aide de la fonction modbusReadRegisters(). Attention, comme précisé dans la documentation, cette fonction utilise la position relative du registre (indexée à partir de zéro):

// Récupération de l'interface RS485
var serial = YSerialPort.FindSerialPort("RS485-REG48");
// Lecture de registres en unité décimale
var slaveID = 1;
var firstRegs = serial.modbusReadInputRegisters(slaveID, 1000, 2);
// Decodage des valeurs en virgule fixe décimale
var processVal = firstRegs[0] / 10;
var setpointVal = firstRegs[1] / 10;


Autre possibilité d'utilisation avec le Yocto-RS485: vous pouvez le configurer avec l'interface web pour qu'il effectue une lecture automatique de ces registres, sans nécessiter d'interaction avec un PC pour déclencher les mesures.

Job pour lire périodiquement un registre
Job pour lire périodiquement un registre


Grâce à cela, le Yocto-RS485 peut faire office de data logger pour enregistrer les mesures reçues via l'interface RS485 sur sa mémoire flash (jusqu'à 500'000 mesures).

On peut même aller encore plus loin: si vous branchez le Yocto-RS485 sur un YoctoHub-Ethernet et que vous y chargez une page web avec un peu de JavaScript, vous pouvez transformer ce simple contrôleur de température RS485 basé sur des technologies des années 1970 en un produit connecté à la mode de l'Internet des Objets. On peut se connecter directement depuis le navigateur web de n'importe quelle tablette sur l'interface, et interagir avec le contrôleur de température:

  


Cool, non ?

Commenter 8 commentaires Retour au blog



1 - Abderrahim EL MARJANE Jeudi 27 juin 2019 11H34

merci pour ces infos, ces intéressant. y'a t'il des infos sur le choix des protocole de communication?

2 - mvuilleu (Yocto-Team)Jeudi 27 juin 2019 12H01

@Abderrahim: A quel choix faites-vous référence, au choix supportés dans l'interface du Yocto-RS485 ou au choix d'un protocole en général ?

3 - Abderrahim EL MARJANE Mercredi 28 août 2019 15H44

@ mvuilleu:
d’abord merci de votre intérêt et désoler pour le retard de ma réponse.
je parle sur les protocole de manière général comment faire le choix? et comment le configurer? car je veut faire l'installation d'une appareil de solar log qui indiqué dans le manuel que la communication avec un capteur de météo de marque lufft nécessite le protocole UMB-binaire.

4 - mvuilleu (Yocto-Team)Jeudi 29 août 2019 7H48

@Abderrahim: The wizard that helps creating custom scripts only knows MODBUS as message protocol, but you can support almost any protocol using the job features described here: https://www.yoctopuce.com/EN/article/how-to-handle-a-serial-protocol-automatically

We already had customers working with UMB binary protocol using RS-485, and it was not difficult to create a custom job with a single Expect command to decode all measures into genericSensor1..9. Contact support@yoctopuce.com if you need help.

5 - souleymane Lundi 04 mai 2020 7H43

Bonjour je suis stagiaire dans une société qui programme des API.

Je voudrais savoir comment gérer un MODBUS 485 en le programmant de telle sorte à utiliser un Maître et plusieurs esclaves (afin d'avoir plus de connectivité sans autant jouer sur la vitesse et le temps de réponses)

Merci de m'aider car je n'arrive pas à trouver quelles réponses apportées

6 - mvuilleu (Yocto-Team)Mardi 05 mai 2020 8H41

@souleymane: je ne suis pas sur que ce soit le bon endroit pour poser cette question. Si il s'agit d'une question générale sur RS485 sans rapport avec les produits Yoctopuce, vous devriez chercher un forum sur RS485. Par contre, si vous aimeriez décharger un ordinateur maître de la communication RS485 en utilisant un module Yoctopuce qui gère lui-même la communications avec les esclaves, c'est probablement possible en utilisant un Yocto-RS485. Mais je vous conseille de contacter le support Yoctopuce par mail plutôt que d'échanger via ces commentaires.

7 - pierrot Lundi 20 juillet 2020 20H06

Bonjour,
la manip est sympa, est-ce que le code de la petite appli web (et la liste exacte du matériel utile) est disponible en ligne?
Merci!
Pierre

8 - mvuilleu (Yocto-Team)Mercredi 22 juillet 2020 6H13

@pierrot Après une petite fouille archéologique, il semble que nous n'avons pas gardé le code source de ce petit exemple. Si je me souviens bien, il était écrit avec l'ancienne librairie Javascript qui est maintenant remplacé par la librairie EcmaScript. Mais le principe était très simple, il s'agot simplement d'une page HTML avec
- un callback de changement de valeur qui affiche la valeur courante (en utilisant une police TrueType qui ressemble à un affichage 7-segment)
- un callback javascript sur les boutons qui appelle modbusWriteRegister pour changer la consigne
Il n'y a pas d'autre matériel que le contrôleur Zelio REG48 décrit dans l'article, un Yocto-RS485 (ou Yocto-RS485-V2) branché à un YoctoHub-Ethernet (+ boîtiers et câbles USB), et le téléphone pour visualiser l'interface.

N'hésitez pas à contacter le support Yoctopuce pour plus de détails

Yoctopuce, get your stuff connected.