Communication série entre 2 arduinos

Bonjour à tous !

Je suis actuellement en train de travailler sur un projet nécessitant une communication série entre deux arduinos nano. L’objectif serait que par exemple si un bouton est pressé sur la carte 1, la carte 2 allume une led.

J’ai réussi pour l’instant à émettre des messages, mais j’ai encore du mal à tout faire fonctionner comme je le souhaiterai. Il y a notamment un problème auquel je me heurte actuellement. Je désire tout simplement en guise de test que ma carte 1 envoie la chaîne de caractère “ok” en fonction d’une banale condition if. je vous joins ci-dessous les deux programmes de chacune des cartes :

Carte recevant le message :

#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 12); // RX, TX//on informe le microcontrôleur que l'on utilise ses broches pour une connexion série
String readString;

void setup() {
    // Communication série
  mySerial.begin(9600);
  Serial.begin (57600);
}

void loop() {
    while (mySerial.available()) {
    delay(10);
    char c = mySerial.read();
    readString += c;
  }
    if (readString.length() > 0) {//si je reçois des valeurs
    Serial.println(readString);//j'imprime ses valeurs
    }
  Serial.println("fin boucle");
}

Carte émettant le message selon ma valeur d’une variable :

#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 12); // RX, TX//on informe le microcontrôleur que l'on utilise ses broches pour une connexion série
String readString;

int x = 1;

void setup() {
    // Communication série
  mySerial.begin(9600);
  Serial.begin (57600);
}

void loop() {

  if (x == 1){
  Serial.println("ok"); delay(50);
  mySerial.write("ok");
  x = 0; 
  }
}

Lorsque je téléverse ces programmes, le message ok est bien émis. Problème, il semblerait qu’il soit émis en continu et la carte réceptrice sur son moniteur série affiche un défilé de ok, alors que je ne souhaiterai en recevoir qu’un.

Voilà, merci à tous !
N’hésitez pas également si vous avez des tutos complémentaires clairs à me proposer pour creuser encore la communication série !

Il n'y a pas de raison pour que "ok" soit envoyé plusieurs fois.

Ton problème vient du fait que readString n'est pas vidé après traitement de la réception.

Conseil : si tu désires que ton sketch ait une certaines durée de vie, évite d'utiliser String.

Pourquoi delay(10) après mySerial.available() ? ? ?

La commande transmise "ok" n'a pas de caractère terminateur. Il serait bien de transmettre au minimum un '\n' par exemple, afin que le récepteur comprenne que la réception est terminée.

Serial.print("ok\n");

Lis mon tuto pour en savoir plus (c'est long) :
commander-un-arduino-par-la-ligne-serie

A propos de fragmentation : arduino-la-fragmentation-memoire

hbachetti:
Pourquoi delay(10) après mySerial.available() ? ? ?

Le 1er caractère arrive.
Serial.available() dit OK.
Serial.read() lit le caractère.
Si on n'attend pas l'arrivée du second caractère (~1 ms), available() dit KO et on sort de la boucle.
Bon là 10 ms c'est très large.

@MathOs
A part l'oubli d'effacer readString à chaque tour, je ne vois pas où ça coince.
Que dit l'envoyeur ? tu as mis un print vers le moniteur, ça donne quoi ?

Rebonjour,
J’ai suivi vos conseils, à savoir rajouter le /n et vider la chaîne de caractère string. J’ai aussi remarqué que le nom de la variable chaîne de caractères était un mot clé (apparaissant en orange), je l’ai donc changé (je ne sais pas si cela a influé sur le programme).
En revanche, un seul bémol, il semblerait que lors de l’envoi d’un ok, le programme de la carte réceptrice fasse 2 tours de boucle au lieu d’un seul. En effet dans le moniteur série il y a une sorte d’espace, comme si il renvoyait encore le contenu de la string, mais qui est maintenant vide. Je vous joins la capture d’écran. A gauche la carte réceptrice et à droite la carte émettrice.

Deux autres questions annexes :
Quel est le problème avec le fait d’utiliser une chaîne de caractère string, et par quoi la remplacer ?
Pouvons-nous déclarer le débit (en baud) du moniteur série et de la transmission à la même vitesse ? Par exemple, peut-on faire Serial.begin(9600); et mySerial.begin (9600); sur les deux cartes.

Merci beaucoup, et je vais voir les tutos que vous m’avez indiqué !

Sans le code : que dire ? ? ?

Excusez-moi pour ce petit oubli…
Le voici !

Carte émettrice :

#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 12); // RX, TX//on informe le microcontrôleur que l'on utilise ses broches pour une connexion série
String readString;

int x = 1;

void setup() {
    // Communication série
  mySerial.begin(9600);
  Serial.begin (57600);
}

void loop() {

  if (x == 1){
  Serial.println("ok"); delay(50);
  mySerial.write("ok\n");
  x = 0; 
  }
}

carte réceptrice :

#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 12); // RX, TX//on informe le microcontrôleur que l'on utilise ses broches pour une connexion série
String myString;

void setup() {
    // Communication série
  mySerial.begin(9600);
  Serial.begin (57600);
}

void loop() {
    while (mySerial.available()) {
    delay(10);
    char c = mySerial.read();
    myString += c;
  }
    if (myString.length() > 0) {//si je reçois des valeurs
    Serial.println(myString);//j'imprime ses valeurs
    myString = "";
    }
}

Le récepteur doit arrêter la lecture lorsqu'il reçoit '\n', sinon il ne sert à rien de l'envoyer.
Tu serais avisé de lire mon article, en particulier l'utilisation de ReadBytesUntil(), même si cela prend du temps.