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...
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
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
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):
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
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 ?