Comparaison de .read avec des string

Bonsoir,

Je voudrais comparer un Serial.read() avec une string :

Quelque chose comme ceci :

if(Serial.read()=="abc"){}

Auriez vous une idée ? d'après ce que j'ai compris le problème vient du fait que le read affiche caractère par caractère.

Il faut donc réussir à faire une variable qui rejoigne tous les caractères tant qu'il y en a.

Normal : Serial.read() renvoie un seul caractère.
Tu pourrais utiliser readString, qui introduirait un timeout de 1s après la réception du dernier caractère reçu.

Sinon, je t'invite à lire ceci : Ecouter le Port Série ou un keypad (applicable à 1 flux de données asynchrone ) - Tutoriels et cours - Arduino Forum

@+

Merci beaucoup pour le lien, j'avais bien compris le problème, par contre pourquoi ceci ne march epas :

Serial.write(Serial.readString());

Parce que Serial.readString() retourne un objet String et que Serail.write attend une chaine de caractères
Faudrait essayer:
Serial.write(Serial.readString().c_str());

J'ai essayé vos pistes dans mon code :

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32test");
}

void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    Serial.write(SerialBT.read());
  }
  delay(20);
}

Mon but est de faire un échange avec l'esp.
Ce que je veux c'est que sur mon tel que j'envoie "test" à l'esp il me réponde "oui" et, quand c'est l'esp qui envoie"test", c'est le tel qui réponde "oui".

J'ai essayé avec le lien et les méthodes proposées.

Si quelqu'un sait comment faire

Calvin-duino:
Merci beaucoup pour le lien, j'avais bien compris le problème, par contre pourquoi ceci ne march epas :

Serial.write(Serial.readString());

Bonjour,

Serial.write() envoi un caractère. Il faut utiliser Serial.print().

Non ce n'est pas le but, le print n'enverrait pas l'info en bluetooth, enfin je le trompe peut être ?

Je viens d'essayer et on ne reçoit que des valeurs, de 48 a je ne sais plus combien

Personne svp ?

48 est le code ASCII de '0'.
Reposte ton code.

@+

Donc j'ai bien avancé :

#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

#include "connexion.h"

int LED1 = 12;
int LED2 = 13;
int LED3 = 14;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP_32");
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  digitalWrite(LED1,LOW);
  digitalWrite(LED2,LOW);
  digitalWrite(LED3,LOW);
}

void loop() {
  if (!msgtel()) {
    Serial.print(message);
    if (strcmp(message,"LED1ON")==0){
      digitalWrite(LED1,HIGH);
      strcpy(message,message);
    }
    if (strcmp(message,"LED2ON")==0){
      digitalWrite(LED2,HIGH);
      strcpy(message,message);
    }
    if (strcmp(message,"LED3ON")==0){
      digitalWrite(LED3,HIGH);
      strcpy(message,message);
    }
  }
  
  if (!msgn()) {
    SerialBT.print(message);
  }

  delay(20);

}

avec mon connexion.h:

const byte tailleMessageMax = 50;
char message[tailleMessageMax + 1];
const char marqueurDeFin = '#';

boolean msgtel()
{
  static byte indexMessage = 0;
  boolean messageEnCours = true;

  while (SerialBT.available() && messageEnCours) {
    int c = SerialBT.read();
    if (c != -1) {
      switch (c) {
        case marqueurDeFin:
          message[indexMessage] = '\0';
          indexMessage = 0;
          messageEnCours = false;
          break;
        default:
          if (indexMessage <= tailleMessageMax - 1) message[indexMessage++] = (char) c;
          else Serial.println(F("j'ignore!"));
          break;
      }
    }
  }
  return messageEnCours;
}

boolean msgn()
{
  static byte indexMessage = 0;
  boolean messageEnCours = true;

  while (Serial.available() && messageEnCours) {
    int c = Serial.read();
    if (c != -1) {
      switch (c) {
        case marqueurDeFin:
          message[indexMessage] = '\0';
          indexMessage = 0;
          messageEnCours = false;
          break;
        default:
          if (indexMessage <= tailleMessageMax - 1) message[indexMessage++] = (char) c;
          else Serial.println(F("j'ignore!"));
          break;
      }
    }
  }
  return messageEnCours;
}

Le problème c'est que je peux envoyer un message avec mon télephone mais pour le second il n'est pas pris en charge.

Comment réinitialiser la valeur de message ?

Up

Cette ligne ne sert à rien:
strcpy(message,message);Elle copie message dans message.
Réinitialiser message, cela veut dire mettre une chaine vide pour cela il faut placer un \0 dans le premier élément de message.

j'ai essayé le code du lien plus haut et, quand j'écris Bonjour# ca ne repond pas ce qu'il faut, dans :

void loop() {
if (! ecouter()) {
if (!strcmp(message, "Bonjour")) {
Serial.println(F("Salut, Comment ça va?"));
} else {
Serial.println(F("pardon, pouvez vous repeter ?"));
}
}
}

Peut etre que strcmp a changé ?

Calvin-duino:
j'ai essayé le code du lien plus haut

Moi, et je ne suis sans doute pas le seul, je ne suis pas trop fan des jeux de piste alors si tu pouvais mettre le code d'une pièce ce serait pas mal.
Et ça fait un moment que tu postes sur ce forum tu dois savoir qu'il faut placer le code entre balise code sinon il s'affiche mal.

Et non strcmp n'a pas changé il retourne 0 s'il y a égalité entre les chaînes

Si tu compares "Bonjour" avec "Bonjour #" strcmp ne va pas trouver d'égalité.
Pour chercher une sous-chaîne dans une chaîne il faut utiliser strstr

Okay, donc plus haut dans le sujet, on m'a conseillé ceci :

const byte tailleMessageMax = 50;
char message[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'

const char marqueurDeFin = '#';

boolean ecouter()
{
  static byte indexMessage = 0; // static pour se souvenir de cette variable entre 2 appels consécutifs. initialisée qu'une seule fois.
  boolean messageEnCours = true;

  while (Serial.available() && messageEnCours) {
    int c = Serial.read();
    if (c != -1) {
      switch (c) {
        case marqueurDeFin:
          message[indexMessage] = '\0'; // on termine la c-string
          indexMessage = 0; // on se remet au début pour la prochaine fois
          messageEnCours = false;
          break;
        default:
          if (indexMessage <= tailleMessageMax - 1) message[indexMessage++] = (char) c; // on stocke le caractère et on passe à la case suivante
          break;
      }
    }
  }
  return messageEnCours;
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  if (! ecouter()) {
    if (!strcmp(message, "Bonjour")) {
      Serial.println(F("Salut, Comment ça va?"));
    } else {
      Serial.println(F("pardon, pouvez vous repeter ?"));
    }
  }
}

J'écris test# puis Bonjour#, le Bonjour n'est pas pris en compte.
J'ai également remplacé par strstr mais c'est le même problème, de toutes manières le # est le marqueur de fin donc il disparait.

Et dans mon programme, c'est un peu le même problème :

J'ai ceci :

#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

#include "connexion.h"

int LED1 = 12;
int LED2 = 13;
int LED3 = 14;

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP_32");
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  digitalWrite(LED1,LOW);
  digitalWrite(LED2,LOW);
  digitalWrite(LED3,LOW);
}

void loop() {
  if (!msgtel()) {
    Serial.print(message);
    if (!strcmp(message,"LED1ON")){
      digitalWrite(LED1,HIGH);
      message[0] = '\0';
    }
    if (!strcmp(message,"LED2ON")){
      digitalWrite(LED2,HIGH);
      message[0] = '\0';
    }
    if (!strcmp(message,"LED3ON")){
      digitalWrite(LED3,HIGH);
      message[0] = '\0';
    }
  }
  
  if (!msgn()) {
    SerialBT.print(message);
  }

  delay(20);

}

Seul le premier message envoyé est pris en compte.

Je suis pas loin du résultat je pense mais, il y a une coui**e quelque part

Si tu rentres dans ce cas là:

else Serial.println(F("j'ignore!"));

Tu ne réinitialises pas l'index.
Tu fais un print de message au début de loop. Pour du debug, tu devrais encadrer la chaine avec 2 caractères quelconques.

Serial.print("\");Serial.print(message);Serial.print("\");

Cela permet de voir s'il y a des espaces qui trainent. Le mieux étant de faire afficher la chaîne caractère par caractère en hexa au cas où il y aurait des caractères non imprimables.

J'ai peut être trouvé le problème. En effet, quand dans le code on écrit Bonjour#, il y a un octet qui est lu a la fin.

Octet lu: 0x6E	[n]
Octet lu: 0x6A	[j]
Octet lu: 0x6F	[o]
Octet lu: 0x75	[u]
Octet lu: 0x72	[r]
Octet lu: 0x23	[#]
Fin de chaine
Phrase: [Bonjour]
Octet lu: 0xA	[
]

Il apparait quand la boucle a lieu.

0x0A c'est le symbole de saut de ligne. Tu dois faire un println() à l'émission.