Liaison RS232 TTL problème au premier envoi

Bonjour à tous,

Dans le cadre d'un projet, je cherche à interfacer un relais et un ordinateur grâce à une carte Arduino.

Côté relais, aucun problème : l'envoi d'un niveau haut sur une pin digitale de ma carte Arduino permet la saturation d'un transistor, qui permet alors la commutation de mon relais.

Côté ordinateur, j'ai mis en place une liaison série RS232 TTL avec ma carte Arduino grâce à un câble convertisseur USB-to-TTL et la bibliothèque SoftwareSerial, afin de pouvoir utiliser 2 pins digitales. J'utilise HTerm sur mon ordinateur pour transmettre et recevoir des données de mon Arduino. Mon programme (que je vous partage plus bas dans le message) doit me renvoyer une information quand le relais commute, afin que je sache s'il est ouvert (OFF) ou fermé (ON).

Mon problème est le suivant : lors de mon PREMIER envoi de commande (envoi, via HTerm, d'un "ON" ou d'un "OFF"), ma carte Arduino me retourne une série de caractères qui ne correspondent pas du tout aux réponses attendues.
Mais, dès le second envoi d'une commande, aucun problème et je reçois bien ce que je m'attends à recevoir.

J'aimerais pouvoir régler ce problème "proprement" (que le premier retour de ma carte soit exploitable) ou du moins comprendre pourquoi ce phénomène se produit.

Merci d'avance de votre aide !

Mon programme :

#include <SoftwareSerial.h>
const byte rxPin = 7;
const byte txPin = 8;
SoftwareSerial RS232(rxPin,txPin);

const byte relayPin = 2;

String command = String();

void setup() {

  RS232.begin(9600);
  
  while(!RS232){
    ;
  }

  pinMode(relayPin, OUTPUT);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
}

void loop() {

    if (RS232.available() > 0) {
      command = RS232.readString();

      if(command == "ON") {
        RS232.println("ON DONE");
        digitalWrite(relayPin, HIGH);
      } else if (command == "OFF") {
        RS232.println("OFF DONE");
        digitalWrite(relayPin, LOW);
    }
  }
}

Pour mieux illustrer mon propos, voici une capture d'écran de HTerm où je fais apparaître mes 2 premières commandes envoyées à Arduino et ses réponses.

Post mis dans la mauvaise section, on parle anglais dans les forums généraux, je viens de déplacer le post dans la section francophone.

Merci de prendre en compte les recommandations listées dans "Les bonnes pratiques du Forum Francophone".

Désolé pour l'erreur, c'est la première fois que j'utilise le forum.

Puis-je reposter ce sujet dans la section où je l'ai placé initialement si je le rédige en anglais ?

Oui, si tu préfères mais les doublons sont interdits. Donc il faut choisir sur quelle partie du forum tu veux échanger.

Ton fil de discussion a été déplacé dans le forum francophone où tu peux continuer en français.


Ces lignes sont inutiles la configuration des pin est assurée lorsque tu fais l'instanciation de ton objet RS232.

Il est possible au démarrage que quelque chose soit vu comme une communication. Transitoires sur Rx de l'Arduino lors de l'initialisation, par exemple.
À la fin du setup(), tu pourrais faire

while(RS232.available()){
     RS232.read();
}

pour vider le buffer de réception.

De même, il est possible que le démarrage de l'Arduino crée des transitoires sur le Tx et que le terminal voit (enfin plutôt, croit voir) une communication.


readString() n'est pas très sûr dans le sens où la réception stoppe au bout d'un temps donné (timeout) même si la commande complète n'a pas été reçue.
Il est préférable d'utiliser readStringUntil() en spécifiant un terminateur de chaîne (saut de ligne (0x0A) ou retour chariot (0x0D)) et en configurant le terminal en face dans ce sens. Ainsi tu seras certain de ne traiter que des commandes complètes.

Dans ce cas je vais m'en tenir à ce post là vu que tu as commencé à m'y apporter des éléments de réponse.

Je ne pense pas que ce soit ce qu'il se passe dans mon cas : à un moment j'ai rajouté un bout de code qui demandait à l'Arduino de me renvoyer ce qu'il avait reçu tel quel si la communication reçue n'était pas "ON" ou "OFF" (cas déjà traités par le programme). Et il ne me renvoyait rien du tout tant que je ne lui avais pas transmis quelque chose. S'il y avait eu un élément résiduel dans le buffer, j'aurais dû le recevoir.

Ce phénomène semble plus correspondre à ce que je constate sur mon terminal.

Effectivement j'avais bien entendu parler de cette histoire de timeout mais j'avoue ne pas en avoir saisi la subtilité. Merci pour la précision.

Dès que j'aurais mon matériel sous la main (lundi), je mettrai en place ces modifications et te tiendrai au courant.

Il y a quand même toujours un truc qui me chiffonne : s'il y a effectivement des éléments résiduels dans le buffer à l'initialisation, comment se fait-il que la première réponse que je reçoive quand j'envoie un "ON" par exemple (cf. capture d'écran partagée plus tôt) comporte le même nombre de caractères que ce que je m'attendais à recevoir (soit 9 caractères) ?

J'ai vu sous d'autres posts que des personnes utilisaient un élément intermédiaire entre leur carte Arduino et le reste du circuit (MAX232). Suis-je en train de faire prendre un risque à ma carte Arduino en connectant directement ses pins digitales au câble USB-to-TTL (Référence) branché à mon PC ?

De ce que j'ai compris de tes explications

Tu utilises un adaptateur USB <--> TTL série pour raccorder 2 I/O TTL de ton Arduino au port USB de ton PC. Donc il n'y a pas de conflit. C'est exactement ce qu'il y a sur les Arduino UNO pour réaliser la liaison série qui sert au téléchargement.
Il vaut mieux ne pas parler de RS232 dans ce cas car RS232 sous-entend aussi des niveaux électriques qui sont effectivement incompatibles avec les interfaces en 5V ou moins.
Le MAX232 est nécessaire si tu veux interfacer une carte Arduino avec un équipement à la norme RS232.

Oui c'est exactement ça. Je me suis peut-être fait induire en erreur par ce que j'ai lu, mais j'ai souvent vu le terme de "RS232 TTL" car la trame du protocole semble identique à celle de la norme RS232, simplement les niveaux de tension correspondant à un 0 et 1 sont différents (±10V pour la norme RS232 et 0/5V pour TTL).

As-tu une idée pour expliquer ce comportement ?

Bonjour nathan_2581

Tu peux améliorer ta réception, comme tu n'a pas de caractère de terminaison à tes commandes ON et OFF:
image
la commande RS232.readString() attend une seconde avant de te "donner la main", tu peux éviter ça en mettant un temps de timout

RS232.begin(9600);
RS232.setTimeout(80);

Tu peux "nettoyer" la réception avec trim():
command.trim();

Cordialement
jpbbricole

Merci pour ces pistes d'amélioration ! Comme je le précisais plus tôt dans la journée, je vous tiendrai informés de la résolution ou non de mon problème dès lundi.

Tout à fait, c'est une grosse source de confusion et de destruction du matériel.

Bienvenue dans le monde du jargon de l'électronique.
Les gens qui savent utilisent à tord des termes qu'ils savent faux, mais tout le monde se comprend.
Enfin presque tout le monde parce que les débutants ne peuvent que croire ce qu'ils lisent.

Je m'explique :

La grosse erreur de la norme RS232 est de définir le protocole et les signaux électriques qui peuvent faire entre -20 V et +20V, le plus courant est entre -12 et +12 V.

Autrement dit si tu connectes un vrai composant RS232 sur un micro, tu crames le micro. On l'a déjà vu sur ce forum, ce n'est pas une supposition.

C'est pour cela que l'usage du terme RS232 est fortement déconseillé

Mais l'usage du terme "TTL" est aussi une source de confusion.
Officiellement "TTL" ne défini que les niveaux électriques de l'état BAS et de l'état HAUT de la norme TTL
TTL n'a jamais signifié alimentation 5 V. Par contre TTL défini qu'un état haut est un signal compris entre 2 V et 5 V.

Cette norme est d'une part très particulière et d'autre part elle est moyenâgeuse et n'existe pratiquement plus.
Il est impossible de faire dialoguer un vrai circuit TTL avec un microcontrôleur CMOS alors que tous les deux sont alimenté en 5 V, les niveaux du 1 et du 0 ne correspondent pas.

OK si la TTL n'existe plus cela diminue les risques, mais autant ne pas participer à répandre les bêtises de youtube.

Le moins faux est de parler de Convertisseur USB/liaison série 5 V.

C'est le moins faux parce qu'il n'existe plus de liaisons parallèle. La centronic, avec ses 25 ou 30 fils, utilisée par les imprimantes a disparue depuis plus de 20 ou 30 ans.
l'I2C et le SPI sont aussi des liaisons séries : les bits des données sont envoyés les uns à la suite des autres sur un même fil de cuivre.

L'I2C et le SPI ou le CAN ont un nom qui identifie un protocole précis, il n'y a pas de risque d'erreur.

Mais attention on ne peut pas connecter de l'I2C (ou du SPI, ou du CAN) 5 V directement sur un composant 3,3 V, ou l'inverse.
Cela cramera. Il faudra insérer des adaptations de niveau entre micro et composant.

L'usage fait que quand on parle de liaison série cela s'applique au protocole RS232, mais absolument pas aux niveaux RS232.

Bonjour à tous,

J'ai tenté de mettre en place vos pistes d'amélioration de mon programme (je vous transmets le nouveau code plus bas dans ce message) mais le problème subsiste.

J'arrive à court d'idées pour le faire fonctionner et je reste tout ouïe à de nouvelles propositions.

#include <SoftwareSerial.h>
const byte rxPin = 7;
const byte txPin = 8;
SoftwareSerial TTL(rxPin, txPin);

const byte relayPin = 2;

String command = String();

void setup() {

  TTL.begin(9600);
  while (TTL.available()) {
    TTL.read();
  }

  pinMode(relayPin, OUTPUT);
}

void loop() {

  if (TTL.available() > 0) {

    command = TTL.readStringUntil("\n");
    command.trim();

    if (command == "ON") {
      TTL.println("ON DONE");
      digitalWrite(relayPin, HIGH);
    } else if (command == "OFF") {
      TTL.println("OFF DONE");
      digitalWrite(relayPin, LOW);
    } else {
      TTL.println(command);
    }
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.