Acquisition données via RS485

Hello Coders!

Je découvre l'Arduino pour lequel je n'ai qu'une très petite expérience et je vais bientôt recevoir des équipements de mesure dont les données relevées sont transmises selon le protocole RS485. Le projet consiste à acquérir ces données avec des Arduino pour ensuite pouvoir les exploiter.

Le fabricant du capteur me donne les informations suivantes:

  • Connection filaire: RS485(A+):RS485 communication interface A+ / RS485(B-):RS485 communication interface B-
  • Protocole de communication:
    Interrogation du capteur : 00 03 00 00 00 01 85 DB
    Réponse du capteur : 00 03 02 02 AE 05 58

Comme vous devez vous y attendre, ma question est comment interroger le capteur et comment recevoir sa réponse avec un Arduino et un module RS485.

Pour certains d'entre vous cela doit être facile mais moi j'aurais du mal sans quelques explications (mode de connexion du module au capteur et à l'Arduino, quelles librairies, exemples de sketch pour l'interrogation du capteur et pour recevoir la réponse...).

J'attends votre aide. Merci par avance.

Salut TEDDOL,

Regarde ceci cela devrais déjà t'aider :wink:

https://arduino-info.wikispaces.com/SoftwareSerialRS485Example

Pur le code c'est comme une communication RS232 donc toute la doc est sur le forum :wink:

Voila deja une bonne piste pour toi je pense.

OK, ce tuto semble simple mais... Dans mon cas, le master serait l'Arduino et le Remote mon capteur ? oui ou non ?

Pour l'arduino Master, je note une déclaration des variables:
int byteReceived;
int byteSend;

Puis la commande: RS485Serial.write(byteReceived); // Send byte to Remote Arduino

La variable byteSend n'est pas utilisée dans le sketch. Quelle donnée le Master envoie-t-il, byteReceived ou byteSend?

Oui c'est bien sa :wink:

je n'ai pas regarder le code je regarde regarde deja ces lien cela devrait aider :wink:

Ok j'ai regarder le code et le lien que je t'ai transmis.

Je te disait oui a propos de master et slave en réalité c'est oui et non l'arduino via le module rs485 n'est qu'une interface qui te permet de communiquer avec ton module!

On peut dire que c'est le master mais ce n'est pas vraiment le bon terme.

Le programme a pour but de lire et de t'aficher ce que chacun des 2 arduino ecrit.

Si dans la console du premier arduino tu écrit 123456 tu pourra lire dans la console de l'autre 123456 et vice versa !

Et enfin ceci aussi a de l'importance a être lu. :wink:

Donc cela voudrait dire que l'Arduino envoie la commande RS485Serial.write(00030000000185DB); au capteur ?
Ou bien faut il le faire byte par byte ? Si oui qu'elle serait la commande alors ?

Et pour la réponse, l'Arduino doit il attendre une chaine entière du type "00030202AE0558" ou devrais-je attendre byte par byte (00 puis 03 puis 02...) ?

Je vais sans aucun doute faire le ch***r qui coupe les cheveux en quatre mais la RS485 n'incorpore aucun protocole.
La RS485 défini uniquement un moyen de transmission électrique (paire différentielle, niveau, impédance).

Je pense que vous voulez parler du protocole incorporé dans la RS232 dite "liaison série" bien que toutes les liaisons actuelles sont des liaisons série (USB, I2C, SPI, etc ).
Souvant avec la RS485 on utilise le protocole défini dans la RS232 mais ce n'est pas une obligation.

Les auteurs de la RS232 avaient fait l'erreur de définir dans une même norme le protocole et les signaux électriques .
Depuis ces deux notions sont heureusement séparées.

enfaite la RS485, il existe un protocole, le protocole modbus

en mode RTU:

Il fonctionne sur le mode maître-esclave. Seul le maître est actif, les esclaves sont complètement passifs.

en mode TCP:

Il fonctionne sur le mode client-serveur. Seul le client est actif, les serveurs sont complètement passifs.

Toi, c'est en mode RTU, soit en mode maitre/exclave

Enfaite, c'est un protocol basée sur des IDs, ce qui permet de connecter plusieurs produits sur le meme bus... jusqu'a 255 produits.

Par exemple, ton produit a un ID,
si tu n'as pas la table d'echange RS485, tu ne peux pas savoir ce que tu recois..
par exemple, a la lecture de l'adresse 1, tu as une température,
adresse 2, une lecture d'une tension
adresse 3, lecture d'un courant....
adresse 4, tu recois une donnée: 40, mais c'est quoi? une temperature, une tension? une alarme? des petit choux?
adresse 5, tu recois 4,
jusqu'a
en faite, ton produit, il a un ID,des adresses,

Interrogation du capteur : 00 03 00 00 00 01 85 DB

00: ID du recepteur
03: The Function Code 3 (read Analog Output Holding Registers): lecture des données
00 00: les données du premier registre
00 01: le nombre total de registre interrogé
85 DB: le CRC pour la vérification des erreurs

Réponse du capteur : 00 03 02 02 AE 05 58
00: ID du recepteur
03: The Function Code 3 (read Analog Output Holding Registers) : Lecture des données
02 02 : les données du premier registre
AE 05: nombre total de registre interrogé ?
58: CRC?

il manque quelque chose, car le modbus est sur 8 bits, et tu en as 7...

ah moin qu'il te repond en mode ASCII( 7bits) et tu lui envois une trame en mode RTU( 8bits)
pour lire un registre, il y a fc03
et pour ecrire quelque chose au recepteur, il y a le fc16

Wow ça ce complique mais je vais quand même essayer de comprendre, donc d'apprendre... :wink:

Voici en pièce jointe une copie du datasheet du capteur si ça peut vous aider.

En effet, RS485 est un mode liaison fait pour un protocole modbus.
J'ai trouvé cette doc. http://www.polier.fr/medias/files/parametrage-modbus-et-exemple-polier-1.pdf
Le format de la réponse selon cette doc est bien sur 7 octets et celui de la requête sous 8 !?

Ceci dit, au delà de la compréhension du protocole modbus en lui même, je dois pouvoir l'appliquer sur de l'Arduino. Donc comment j'envoie ma requete ? Octet par octet pour une chaîne de 8 octets: RS485Serial.write(00030000000185DB); ?

On ne va pas se battre pour ce qui est malgré tout secondaire mais je pense plutôt que c'est Modbus qui utilise la RS485 (EIA-485) et non l'inverse.

Portée de la norme
La norme RS-485 ne spécifie que les caractéristiques électriques de l'émetteur et du récepteur (couche physique). Il ne précise et ne recommande aucun protocole de communication. Pour les directives d'applications, il est recommandé de se référer au Telecommunications Systems Bulletin Le BST-89, qui comprend les taux de transfert de données par rapport à la longueur du câble, les dérivations de bus, et les configurations. D'autres normes définissent les protocoles de communication sur une liaison RS-485.

L'avantage est que maintenant les protocoles de communication sont indépendants du support de transmission.
Rien n'empêche de faire du Modbus sur de la fibre optique.
De même on fait transiter du "protocole RS232" sur de l'USB.

Pour la syntaxe je dit peutetre une betise mais je dirais :

RS485Serial.write(00,03,00,00,00,01,85,DB);

Mais je dit peut-être une bêtise !!!

Au moins sa relance le sujet initial :wink:

tu trouveras ton bonheure ici:

tu prend l'example basic, tu change la vitesse de transmission avec celle donnée dans la datasheet, en general 9600

tu change change l'adresse esclave en 0 au lieu de 2.

 node.begin(0, Serial);

et tu envois la requette

result = node.readHoldingRegisters(0, 3); //lecture des 3 premiers registres...

Au moins sa relance le sujet initial ;)

Il y a des fois où éviter de confondre protocole et moyen de transmission me parait aussi utile et peut aider à résoudre le sujet initial en ouvrant d'autres horizons.

Hello,
Je reviens sur le sujet après une absence forcée.
J'ai le sketch basic Modbus que voici

#include <ModbusMaster.h>

// instantiate ModbusMaster object
ModbusMaster node;

void setup()
{
  // use Serial (port 0); initialize Modbus communication baud rate
  Serial.begin(19200);

  // communicate with Modbus slave ID 2 over Serial (port 0)
  node.begin(2, Serial);
}

void loop()
{
  static uint32_t i;
  uint8_t j, result;
  uint16_t data[6];
  
  i++;
  
  // set word 0 of TX buffer to least-significant word of counter (bits 15..0)
  node.setTransmitBuffer(0, lowWord(i));
  
  // set word 1 of TX buffer to most-significant word of counter (bits 31..16)
  node.setTransmitBuffer(1, highWord(i));
  
  // slave: write TX buffer to (2) 16-bit registers starting at register 0
  result = node.writeMultipleRegisters(0, 2);
  
  // slave: read (6) 16-bit registers starting at register 2 to RX buffer
  result = node.readHoldingRegisters(2, 6);
  
  // do something with data if read is successful
  if (result == node.ku8MBSuccess)
  {
    for (j = 0; j < 6; j++)
    {
      data[j] = node.getResponseBuffer(j);
    }
  }
}

Tout d'abord, j’aimerais comprendre ce code qui pour moi n'est pas clair. Aucun détails n'est donné au niveau du câblage. Quel pins de l'arduino sont utilisés ? Comment intégrer un module RS485 pour envoyer la requête et lire la réponse du contrôleur ? A quel endroit du code j'envoie la requete 00 03 00 00 00 01 85 DB ?

bonjour!

si vous pourriez m'aider cest un peu sur le meme chose, jai un capteur qui je le donne des commandes en mode modbus, il dis plus specifiquement:
*MODBUS serial communication via serial interfaces such
as RS232, RS485
*MODBUS ASCII codes the data using ASC-II character
set in the form of legible character chains

je dois faire quelques demandes comme par example:"0003018000106c"
et envoyer autres pour fixer des paramettres sur les measures par example :"000602000001F7"

est ce que cest posible de realicer ca avec un Module 5V MAX485 / RS485 TTL à carte de développement RS-485 MCU?

le sensor a un connection USB mini femelle.

merci en avance