Dans les années 1980 et 1990, un thème récurrent dans les magazines informatiques était de savoir si l'interface série ou l'interface parallèle était plus appropriée pour la transmission externe de données. L'interface sérielle ou RS232 (UART= Universal Asynchronous Receiver Transmitter) sur le PC était surtout utilisée pour la télétransmission de données avec des modems (au début sur le réseau télégraphique), l'interface parallèle Centronics fournissait des données à l'imprimante.
Vous connaissez le résultat de la course à la vitesse : En interne au processeur et sur la carte mère, la largeur des bus de données n'a cessé d'augmenter, en externe, l'interface parallèle a été supplantée par l'USB (=Universal Serial Bus) et les réseaux. Mais l'interface RS-232 a elle aussi largement disparu, car elle présentait quelques faiblesses importantes : portée limitée et connexion uniquement entre deux appareils exactement.
En tant qu'étape intermédiaire vers les réseaux actuels, l'interface série RS-232 a fait l'objet de développements qui sont encore utilisés aujourd'hui : Entre autres, l'interface RS-485 (la mise à jour des normes sous le nom actuel d'EIA-485 prouve son actualité) couvre de grandes distances jusqu'à 1000 m grâce à la structure symétrique des signaux sur les deux lignes et permet le raccordement en série de 32 appareils au maximum, tant que les derniers appareils possèdent une résistance de terminaison. Comme c'est souvent le cas, Wikipedia contient des pages très informatives sur UART, RS-232 et EIA-485 pour ceux qui veulent en savoir plus.
Pour utiliser l'interface RS-485, qui n'existe pas sur les ordinateurs actuels du point de vue matériel, j'ai acheté un adaptateur USB-RS-485 bon marché pour le PC.
Pour les microcontrôleurs de type Arduino Uno ou compatibles ainsi que les D1 R1 (avec ESP8266) et D1 R32 (avec ESP32) de construction similaire, il existe un shield correspondant, pour le Raspberry Pi un HAT (Hardware Attached on Top).
Pour me familiariser avec ce domaine nouveau pour moi, j'ai commencé par rassembler des informations, par exemple sur le site Internet de notre fournisseur pour le Shield ou le HAT : Fa. zihatec.
C'est de là que j'ai téléchargé la fiche technique, la note d'application et les exemples de sketches. Mais comme je n'ai pas réussi à faire marcher l'exemple au début, j'aimerais adopter une autre façon de l'expliquer :
Tout d'abord, quel est l'objectif à atteindre ?
Ce post d'introduction porte sur la réalisation d'un MODBUS Slave, car MODBUS est l'une des principales applications de la RS-485 ; il s'agit d'un protocole ouvert et il est devenu un standard-de-facto pour les automates programmables industriels (API) dans l'industrie.
Un système MODBUS nécessite toujours un master et au moins un slave. Le shield permet de réaliser aussi bien un master que des slaves. Cependant, en utilisant un microcontrôleur avec Atmel 328, il n'est pas possible de réaliser un Master de manière judicieuse, car la mémoire RAM est très limitée. C'est pourquoi, dans l'exemple, un MODBUS Slave est réalisé et un PC est utilisé comme Master.
Concrètement, le Master serait par exemple un API ou un ordinateur de commande central auquel différentes machines ou appareils avec interface RS485 sont connectés en tant que slaves. Le Master peut alors interroger et commander séquentiellement tous les appareils raccordés au RS485 BUS via le protocole MODBUS. Pour ce faire, les appareils ont tous des adresses de bus différentes.
Le sketch d'exemple envoie six signaux analogiques et le signal numérique d'un bouton-poussoir au PC via la connexion RS-485 et reçoit de là l'information indiquant si une LED doit être allumée ou éteinte.
Pour cela, j'ai branché le shield sur le microcontrôleur ainsi que le circuit suivant avec six potentiomètres sur les entrées analogiques A0 à A5, une LED avec une résistance en série sur la broche numérique 12 et un bouton (button) avec une résistance pulldown sur la broche 7.
Il faut encore procéder à quelques réglages sur le shield. Cela se fait d'une part à l'aide de connecteurs de court-circuit (Jumper) et d'autre part à l'aide de petits interrupteurs (DIP switches, "claviers de souris"). Les inscriptions sur le circuit imprimé sont très utiles à cet égard.
Pour notre microcontrôleur avec Atmega 328, on place le seul jumper J1 sur 5V, dans la rangée à côté des broches 0 à 7, on place la connexion de la ligne RX sur le port 0 et la ligne TX sur le port 1, le troisième jumper n'est pas nécessaire lors de la commutation automatique RX/TX.
Attention : pour cet essai, on utilise les mêmes broches que pour la connexion USB à l'IDE Arduino. Il faut donc retirer soit l'ensemble du shield, soit ces deux pins pour la durée de la programmation du microcontrôleur (le chargement du sketch). Le moniteur sériel dans l'IDE ne peut pas être utilisé.
Veuillez régler les interrupteurs DIP comme sur l'image suivante :
Le micro-commutateur le plus important est le premier sur SW 3 : il permet d'activer la résistance de terminaison (terminating resistor).
J'ai modifié le sketch de Hartmut Wendt de manière minimale, à savoir pour la vitesse de transmission 9600 et dans la fonction void setup() avec un bref test de la LED : (Télécharger le dossier du sketch avec 3 fichiers):
/*
* Test program for Arduino RS422/RS485 Shield
* Version 1.0
* Copyright (C) 2018 Hartmut Wendt www.zihatec.de
*
* (based on sources of https://github.com/angeloc/simplemodbusng)
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// led
// push button
// Using the enum instruction allows for an easy method for adding and
// removing registers. Doing it this way saves you #defining the size
// of your slaves register array each time you want to add more registers
// and at a glimpse informs you of your slaves register layout.
//////////////// registers of your slave ///////////////////
enum
{
// just add or remove registers and your good to go...
// The first register starts at address 0
ADC0,
ADC1,
ADC2,
ADC3,
ADC4,
ADC5,
LED_STATE,
BUTTON_STATE,
TOTAL_ERRORS,
// leave this one
TOTAL_REGS_SIZE
// total number of registers for function 3 and 16 share the same register array
};
unsigned int holdingRegs[TOTAL_REGS_SIZE]; // function 3 and 16 register array
////////////////////////////////////////////////////////////
void setup()
{
modbus_configure(9600, 1, 6, TOTAL_REGS_SIZE, 0); // 115200
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
//added as a first test
digitalWrite(ledPin,HIGH);
delay(1000);
digitalWrite(ledPin,LOW);
}
void loop()
{
// modbus_update() is the only method used in loop(). It returns the total error
// count since the slave started. You don't have to use it but it's useful
// for fault finding by the modbus master.
holdingRegs[TOTAL_ERRORS] = modbus_update(holdingRegs);
for (byte i = 0; i < 6; i++)
{
holdingRegs[i] = analogRead(i);
delayMicroseconds(50);
}
byte buttonState = digitalRead(buttonPin); // read button states
// assign the buttonState value to the holding register
holdingRegs[BUTTON_STATE] = buttonState;
// read the LED_STATE register value and set the onboard LED high or low with function 16
byte ledState = holdingRegs[LED_STATE];
if (ledState) // set led
{
digitalWrite(ledPin, HIGH);
}
else if (ledState == 0) // reset led
{
digitalWrite(ledPin, LOW);
holdingRegs[LED_STATE] = 0;
}
}
Côté PC, j'ai branché l'adaptateur USB-RS-485 sur un port USB et installé le programme ModbusTester.
La connexion sérielle est très simple : deux câbles relient les ports A-A et B-B respectifs. Pour les lignes longues, les câbles doivent être torsadés et la formule empirique suivante s'applique : la longueur du câble multipliée par le taux de transmission ne doit pas dépasser 100 millions, par exemple 50m et 2Mbit/s maximum.
Avec le programme Modbus Tester, il est important de régler le même débit en bauds. Le port COM virtuel utilisé est affiché sous Paramètres Windows et doit être sélectionné dans le menu déroulant.
Sortie de valeurs ; Sur cette copie d'écran, après avoir cliqué sur Read (en bas à droite), les valeurs que j'ai réglées sur les potentiomètres sont affichées dans les registres 1 à 6, ainsi que l'état du bouton-poussoir dans le registre 8.
Entrée de commandes : Write permet d'envoyer la valeur du registre 7 (ici 1) au microcontrôleur pour allumer la LED. Pour l'éteindre, présélectionner 0 et appuyer sur Write.
Ceci ne constitue bien entendu qu'un premier test des appareils utilisés. Vous trouverez des applications sérieuses, comme par exemple l'intégration d'appareils sur des bateaux selon NMEA-0183 (GPS, etc.), sur le site de zihatec. Dans une deuxième partie, j'aimerais me tourner vers la technique d'éclairage avec DMX. Pour cela aussi, j'utilise le RS-485 Shield.